簡體   English   中英

為什么 QR 分解不能正常工作? (Lapacke,復雜案例)

[英]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^-310^-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM