为什么 QR 分解不能正常工作? (Lapacke,复杂的情况)
Why doesn't QR decomposition work correctly? (Lapacke, complex case)
我用的是Lapacke。我正在尝试在 C 中对复杂数据进行 QR 分解。为此,我编写了函数(基于 Haatschii 代码 ):
// 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 的作者在函数 znugqr, but however he switched to the function zunmqr and it seems that happiness has come () 上也有问题。我相信我的问题也与 LAPACKE_zungqr
有关,因为矩阵 R 与其他方法相同,因此 LAPACKE_zgeqrf
成功运行。
但最后,将相似的结果(QR 分解)与 Mathematica(QRDecomposition
函数)和 Python(numpy.linalg.qr
函数)进行比较,我发现矩阵 Q 是不同,而矩阵R相同
输入矩阵,为简单起见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
输出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
最后 2 列:
-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
输出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
(这里我只列出了这个矩阵的最后两列。前三列是相同的)。
我计算了这些矩阵中各列的最大差值和平均差值。结论是这样的:前三列相差10^-11
,后两列相差10^-3
,10^-2
(肉眼可见的区别) ).
随着矩阵大小的增加,观察到差异增加,通常前 2-3 列重合。
也许有人可以帮助我?
输入矩阵 A 为 5x5,但秩为 2。前两列是线性独立的,而 A 的后三列是前两列的线性组合。
对于 QR 分解,这意味着 Q 的最后三列没有唯一性。QR 分解实现(例如 LAPACK、numpy 等)可以 return 任何三列(1) 互正交和 (2) 在 A^(perp) 中,这是正确答案。有很多正确答案! The
解不是唯一的。
如果您想检查由 LAPACK 编辑的 Q 和 R return(或任何 QR 因式分解实现),您可以 (1) 计算 Q'*Q 并检查您是否得到5x5 单位矩阵,(请使用 BLAS HERK 函数)和 (2) 计算 Q'*A 并检查您是否具有 5x5 上三角矩阵 R(由 QR 编辑 return)。在您的情况下,您应该看到 R 的最后 3 行都是零,这表明 A 的最后三列是前两列的线性组合。要计算 Q'*A,您可以使用 BLAS GEMM。
我从 LAPACK 获取了您的输入 A 和输出 Q,并为您检查了 Q'*Q 是恒等式,Q'*R 是上三角,最后三行全为零。所以 LAPACK 的 Q 输出对我来说看起来不错。是的,这个 Q 不同于 return 由另一个实现编辑的内容,这是完全可能的。
一般来说,我们通过检查以下内容来检查 QR 分解的质量:(1) || A - 二维码 || / ||一个||很小, (2) ||我 - Q^T Q ||很小,R 是上三角。 (取任何容易计算的范数。)
检查两个代码 return 相同的输出不是一个好主意。由于两个原因导致输出 Q 和 R 不唯一:(1)当 A 秩亏时,请参见您给出的示例; (2) 对于任何 j,只要您相应地缩放 R 的 j-th 行,对于 Q 的 j-th 列,任何具有复数模数 1 的列缩放都是可能的。这会更改 Q 和 R 因子,但仍然存在有效的 Q 和 R 因子。
此外,假设您强制 R 的所有对角线元素为非负实数,(通过适当地重新缩放 Q 的列和 R 的列,)并且 A 是满秩的,那么您会期望 Q 和R. 然而,检查 (Q,R) 对是否接近另一个与计算 Q 和 R 以进行 QR 因式分解的条件数有关,因此您可以看到相距很远的对(前向误差),即使它们具有良好的后向误差质量。
我用的是Lapacke。我正在尝试在 C 中对复杂数据进行 QR 分解。为此,我编写了函数(基于 Haatschii 代码
// 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 的作者在函数 znugqr, but however he switched to the function zunmqr and it seems that happiness has come (LAPACKE_zungqr
有关,因为矩阵 R 与其他方法相同,因此 LAPACKE_zgeqrf
成功运行。
但最后,将相似的结果(QR 分解)与 Mathematica(QRDecomposition
函数)和 Python(numpy.linalg.qr
函数)进行比较,我发现矩阵 Q 是不同,而矩阵R相同
输入矩阵,为简单起见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
输出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
最后 2 列:
-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
输出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
(这里我只列出了这个矩阵的最后两列。前三列是相同的)。
我计算了这些矩阵中各列的最大差值和平均差值。结论是这样的:前三列相差10^-11
,后两列相差10^-3
,10^-2
(肉眼可见的区别) ).
随着矩阵大小的增加,观察到差异增加,通常前 2-3 列重合。
也许有人可以帮助我?
输入矩阵 A 为 5x5,但秩为 2。前两列是线性独立的,而 A 的后三列是前两列的线性组合。
对于 QR 分解,这意味着 Q 的最后三列没有唯一性。QR 分解实现(例如 LAPACK、numpy 等)可以 return 任何三列(1) 互正交和 (2) 在 A^(perp) 中,这是正确答案。有很多正确答案! The
解不是唯一的。
如果您想检查由 LAPACK 编辑的 Q 和 R return(或任何 QR 因式分解实现),您可以 (1) 计算 Q'*Q 并检查您是否得到5x5 单位矩阵,(请使用 BLAS HERK 函数)和 (2) 计算 Q'*A 并检查您是否具有 5x5 上三角矩阵 R(由 QR 编辑 return)。在您的情况下,您应该看到 R 的最后 3 行都是零,这表明 A 的最后三列是前两列的线性组合。要计算 Q'*A,您可以使用 BLAS GEMM。
我从 LAPACK 获取了您的输入 A 和输出 Q,并为您检查了 Q'*Q 是恒等式,Q'*R 是上三角,最后三行全为零。所以 LAPACK 的 Q 输出对我来说看起来不错。是的,这个 Q 不同于 return 由另一个实现编辑的内容,这是完全可能的。
一般来说,我们通过检查以下内容来检查 QR 分解的质量:(1) || A - 二维码 || / ||一个||很小, (2) ||我 - Q^T Q ||很小,R 是上三角。 (取任何容易计算的范数。)
检查两个代码 return 相同的输出不是一个好主意。由于两个原因导致输出 Q 和 R 不唯一:(1)当 A 秩亏时,请参见您给出的示例; (2) 对于任何 j,只要您相应地缩放 R 的 j-th 行,对于 Q 的 j-th 列,任何具有复数模数 1 的列缩放都是可能的。这会更改 Q 和 R 因子,但仍然存在有效的 Q 和 R 因子。
此外,假设您强制 R 的所有对角线元素为非负实数,(通过适当地重新缩放 Q 的列和 R 的列,)并且 A 是满秩的,那么您会期望 Q 和R. 然而,检查 (Q,R) 对是否接近另一个与计算 Q 和 R 以进行 QR 因式分解的条件数有关,因此您可以看到相距很远的对(前向误差),即使它们具有良好的后向误差质量。