gpt4 book ai didi

c++ - 对 Eigen QR 分解感到困惑

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:20:27 25 4
gpt4 key购买 nike

我对 Eigen 的 QR 分解感到困惑。我的理解是矩阵 Q隐式存储为一系列 Householder 变换,矩阵 R存储为上三角矩阵,R 的对角线包含 A 的特征值(至少到阶段为止,这是我所关心的)。

但是,我编写了以下程序来计算矩阵的特征值 A通过两种不同的方法,一种使用 Eigen::EigenSolver , 另一个使用 QR .我知道我的 QR方法返回错误结果,EigenSolver方法返回正确的结果。

我在这里误解了什么?

#include <iostream>
#include <algorithm>
#include <Eigen/Dense>

int main()
{
using Real = long double;
long n = 2;
Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> A(n,n);

for(long i = 0; i < n; ++i) {
for (long j = 0; j < n; ++j) {
A(i,j) = Real(1)/Real(i+j+1);
}
}

auto QR = A.householderQr();

auto Rdiag = QR.matrixQR().diagonal().cwiseAbs();
auto [min, max] = std::minmax_element(Rdiag.begin(), Rdiag.end());
std::cout << "\u03BA\u2082(A) = " << (*max)/(*min) << "\n";

std::cout << "\u2016A\u2016\u2082 via QR = " << (*max) << "\n";
std::cout << "Diagonal of R =\n" << Rdiag << "\n";


// dblcheck:

Eigen::SelfAdjointEigenSolver<decltype(A)> eigensolver(A);
if (eigensolver.info() != Eigen::Success) {
std::cout << "Something went wrong.\n";
return 1;
}
auto absolute_eigs = eigensolver.eigenvalues().cwiseAbs();
auto [min1, max1] = std::minmax_element(absolute_eigs.begin(), absolute_eigs.end());
std::cout << "\u03BA\u2082(A) via eigensolver = " << (*max1)/(*min1) << "\n";
std::cout << "\u2016A\u2016\u2082 via eigensolver = " << (*max1) << "\n";
std::cout << "The absolute eigenvalues of A via eigensolver are:\n" << absolute_eigs << "\n";
}

输出:

κ₂(A) = 15
‖A‖₂ via QR = 1.11803
Diagonal of R =
1.11803
0.0745356
κ₂(A) via eigensolver = 19.2815
‖A‖₂ via eigensolver = 1.26759
The absolute eigenvalues of A via eigensolver are:
0.0657415
1.26759

其他信息:

  • 从头部克隆特征:
$ hg log | more
changeset: 11993:20cbc6576426
tag: tip
date: Tue May 07 16:44:55 2019 -0700
summary: Fix AVX512 & GCC 6.3 compilation
  • 在使用 g++-8、g++-9 和 Apple Clang 编译时发生,有或没有 -ffast-math .我用 Eigen::FullPivHouseholderQR 得到了同样的错误结果.

  • 我还查看了来源 HouseholderQR.h , 他们通过 m_qr.diagonal().prod() 计算行列式,这让我对自己正确使用 API 更有信心。从 EigenSolver 中获取特征值的乘积返回与 QR.absDeterminant() 相同的值.

  • 以下代码片段不返回原始矩阵 A:

Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> R = QR.matrixQR();
Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> Q = QR.householderQ();
std::cout << "Q*R = \n" << Q*R << "\n";
  • 我检查了 Q具有所有必需的属性:Q^-1 = Q^T、Q^TQ = I 和 |det(Q)| = 1。

  • 我还验证了 QR.householderQ().transpose()*QR.matrixQR()不等于 A ;尽管一栏是正确的而另一栏是错误的。

最佳答案

正如@geza 指出的那样,QR 分解的 R 矩阵(通常)将不包含原始矩阵的特征值,如果是这样的话,生活会太轻松了:)

对于你的另一个问题,如果你想从 QR 重建 A 你只需要看一下的上三角部分QR.matrixQR()

Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic>
R = QR.matrixQR().triangularView<Eigen::Upper>();

除此之外,我建议小心使用 auto 结合表达式模板(在你的情况下没有严重错误,除了 Rdiag 至少被评估两次)。

此外,在现代 CPU 上使用 long double 几乎不是一个好主意。首先确保您使用的算法在数值上是稳定的,如果精度确实是一个问题,请考虑使用任意精度 float (如 MPFR)。

关于c++ - 对 Eigen QR 分解感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56047470/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com