[英]Why doesn't QR decomposition work correctly? (Lapacke, complex case)
我用拉帕克。 我正在嘗試在 C 中對復雜數據進行 QR 分解。 為此,我編寫了 function (基於 Haatschii 代碼How to get the Q from the QR factorization output? ):
// Q - input: matrix that we expand / output: Q matrix
// R - output: R matrix
// rows - input: number of rows of Q
// columns - input: number of columns of Q
// rows >= columns condition is always met
void QR(lapack_complex_double * Q, lapack_complex_double * R, size_t rows, size_t columns){
size_t i;
lapack_complex_double* tau = malloc(columns*sizeof(lapack_complex_double));
LAPACKE_zgeqrf(LAPACK_ROW_MAJOR, (int) rows, (int) columns, Q, (int) columns, tau); // returns the Q, R in a packed format
// Copy the upper triangular Matrix R (columns x columns).
for(i = 0; i < columns; ++i)
memcpy(R+i*columns+i, Q+i*columns+i, (columns-i)*sizeof(lapack_complex_double));
LAPACKE_zungqr(LAPACK_ROW_MAJOR, (int) rows, (int) columns, (int) columns, Q, (int) columns, tau); // returns the Q
free(tau);
}
值得注意的是,Alireza 的作者也遇到了 function znugqr的問題,但是他切換到了 function zunmqr ,似乎幸福來了( LAPACK QR 分解)。 我相信我的問題也與LAPACKE_zungqr
有關,因為矩陣 R 與其他方法相同,因此LAPACKE_zgeqrf
可以成功運行。
But in the end, comparing the similar result (QR decompostion) with Mathematica ( QRDecomposition
function) and Python ( numpy.linalg.qr
function), I see that the matrix Q is different, while the matrix R is the same.
輸入矩陣,為簡單起見 5×5:
1 + 3j 6 + 8j 11 + 13j 16 + 18j 21 + 23j
2 + 4j 7 + 9j 12 + 14j 17 + 19j 22 + 24j
3 + 5j 8 + 10j 13 + 15j 18 + 20j 23 + 25j
4 + 6j 9 + 11j 14 + 16j 19 + 21j 24 + 26j
5 + 7j 10 + 12j 15 + 17j 20 + 22j 25 + 27j
Output Q 矩陣(來自我的 C 代碼):前 3 列:
-0.07254 - 0.21764j -0.61558 - 0.41039j 0.519770 - 0.06712j
-0.14509 - 0.29019j -0.35909 - 0.25649j -0.59817 + 0.211099j
-0.21764 - 0.36273j -0.10259 - 0.10259j 0.035755 - 0.18619j
-0.29019 - 0.43528j 0.153896 + 0.051298j -0.35605 + 0.007600j
-0.36273 - 0.50783j 0.410391 + 0.205195j 0.398709 + 0.034623j
最后兩列:
-0.12316 - 0.06327j -0.11940 + 0.303152j
0.221078 + 0.491045j 0.084589 - 0.02148j
-0.06231 - 0.31146j 0.119483 - 0.80553j
-0.04594 - 0.59711j -0.01512 + 0.462905j
0.010343 + 0.480803j -0.06954 + 0.060958j
Output Q矩陣(來自Python代碼):
-0.11670 - 0.06185j -0.13105 + 0.301181j
0.223111 + 0.487988j 0.096454 - 0.02009j
-0.08117 - 0.30874j 0.138515 - 0.80184j
-0.04015 - 0.59906j -0.04217 + 0.459232j
0.014923 + 0.481676j -0.06174 + 0.061519j
(這里我只列出這個矩陣的最后 2 列。前 3 列是相同的)。
我計算了這些矩陣中各列的最大和平均差異。 結論是這樣的:前三列在10^-11
的級別上有所不同,后兩列之間的差異分別為10^-3
和10^-2
(肉眼可見差異)。
隨着矩陣大小的增加,觀察到差異的增加,並且通常前 2-3 列很好地吻合。
也許有人可以幫助我?
輸入矩陣 A 是 5x5 但它的秩為 2。前兩列是線性獨立的,而 A 的后三列是前兩列的線性組合。
對於 QR 分解,這意味着 Q 的最后三列不具有唯一性。QR 分解實現(例如 LAPACK、numpy 等)可以返回(1)相互正交和(2)的任意三列在 A^(perp) 中,這是一個正確的答案。 有很多正確答案! 解決方案不是唯一The
。
如果您想檢查 LAPACK 返回的 Q 和 R(或任何 QR 分解實現),您可以(1)計算 Q'*Q 並檢查您是否得到 5x5 單位矩陣,(請使用 BLAS HERK function這樣做)和(2)計算 Q'*A 並檢查您是否具有 5x5 上三角矩陣 R(由 QR 返回)。 在您的情況下,您應該看到 R 的最后 3 行全為零,這表明 A 的最后三列是前兩列的線性組合。 要計算 Q'*A,您可以使用 BLAS GEMM。
我從 LAPACK 中獲取了您的輸入 A 和 output Q 並為您檢查了 Q'*Q 是身份,Q'*R 是上三角形,最后三行完全為零。 所以我覺得 LAPACK 的 Q output 看起來不錯。 是的,這個 Q 與另一個實現返回的不同,這是完全可能的。
一般來說,我們通過檢查以下內容來檢查 QR 分解的質量: (1) || A - 二維碼 || / || 一個 || 小,(2) || 我 - Q^TQ || 很小,R 是上三角形。 (取任何易於計算的范數。)
檢查兩個代碼是否返回相同的 output 不是一個好主意。 由於 output Q 和 R 的不唯一性有兩個原因:(1)當 A 排名不足時,請參見您給出的示例; (2) 對於任何 j,只要您相應地縮放 R 的第 j 行,就可以對 Q 的第 j 列使用模數 1 的復數進行任何列縮放。 這會改變 Q 和 R 因子,但仍然存在有效的 Q 和 R 因子。
此外,假設您強制 R 的所有對角線元素為非負實數,(通過適當地重新調整 Q 的列和 R 的列)並且 A 是滿秩的,那么您會期望 Q 和 ZE287D6D3D80CAFEE44 的唯一性。 然而,檢查對 (Q,R) 是否接近另一個與計算 Q 和 R 的條件數有關,以進行 QR 分解,因此您可以看到相距很遠的對(前向誤差),即使它們有良好的后向錯誤質量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.