特征值等同于 Octave/MATLAB 矩形矩阵的 mldivide
Eigen equivalent to Octave/MATLAB mldivide for rectangular matrices
我正在使用 Eigen v3.2.7。
我有一个中型矩形矩阵 X
(170x17) 和行向量 Y
(170x1),我正在尝试使用 Eigen 求解它们。 Octave 使用 X\Y
很好地解决了这个问题,但是 Eigen 为这些矩阵返回了不正确的值(但不是更小的)——但是我怀疑这就是我使用 Eigen 的方式,而不是 Eigen 本身。
auto X = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>{170, 17};
auto Y = Eigen::Matrix<T, Eigen::Dynamic, 1>{170};
// Assign their values...
const auto theta = X.colPivHouseholderQr().solve(Y).eval(); // Wrong!
根据 Eigen documentation,ColPivHouseholderQR
求解器适用于一般矩阵并且非常稳健,但为了确保我也尝试了 FullPivHouseholderQR
。结果是一样的。
Octave 的 mldivide
是否有一些我需要为 Eigen 手动实现的特殊魔法?
更新
This spreadsheet 有两个输入矩阵,加上 Octave 和我的结果矩阵。
替换 auto
没有什么不同,我也不希望它有什么不同,因为构造不能是惰性操作,我必须在求解结果上调用 .eval()
因为接下来的事情我对结果矩阵所做的是获取尾部和头部操作的原始数据(使用 .data()
)。这些块操作结果的表达式模板版本没有 .data()
成员,所以我必须事先强制求值 - 换句话说 theta
已经是具体类型,而不是表达式模板。
(X*theta-Y).norm()/Y.norm()
的结果是:
2.5365e-007
(X.transpose()*X*theta-X.transpose()*Y).norm() / (X.transpose()*Y).norm()
的结果是:
2.80096e-007
由于我目前对我的基本数值类型使用单精度浮点数,因此两者几乎都是零。
根据您的验证,您得到的方案完全没问题。如果您想要更高的准确性,请使用 double
浮点数。请注意,MatLab/Octave 默认使用双精度。
此外,也可能是你的问题不是满秩的,在这种情况下你的问题有无限多的解。 ColPivHouseholderQR 任意选择一个。另一方面,mldivide 将选择您也可以使用 Eigen::BDCSVD
(Eigen 3.3)或较慢的 Eigen::JacobiSVD
.
获得的最小范数
我正在使用 Eigen v3.2.7。
我有一个中型矩形矩阵 X
(170x17) 和行向量 Y
(170x1),我正在尝试使用 Eigen 求解它们。 Octave 使用 X\Y
很好地解决了这个问题,但是 Eigen 为这些矩阵返回了不正确的值(但不是更小的)——但是我怀疑这就是我使用 Eigen 的方式,而不是 Eigen 本身。
auto X = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>{170, 17};
auto Y = Eigen::Matrix<T, Eigen::Dynamic, 1>{170};
// Assign their values...
const auto theta = X.colPivHouseholderQr().solve(Y).eval(); // Wrong!
根据 Eigen documentation,ColPivHouseholderQR
求解器适用于一般矩阵并且非常稳健,但为了确保我也尝试了 FullPivHouseholderQR
。结果是一样的。
Octave 的 mldivide
是否有一些我需要为 Eigen 手动实现的特殊魔法?
更新
This spreadsheet 有两个输入矩阵,加上 Octave 和我的结果矩阵。
替换 auto
没有什么不同,我也不希望它有什么不同,因为构造不能是惰性操作,我必须在求解结果上调用 .eval()
因为接下来的事情我对结果矩阵所做的是获取尾部和头部操作的原始数据(使用 .data()
)。这些块操作结果的表达式模板版本没有 .data()
成员,所以我必须事先强制求值 - 换句话说 theta
已经是具体类型,而不是表达式模板。
(X*theta-Y).norm()/Y.norm()
的结果是:
2.5365e-007
(X.transpose()*X*theta-X.transpose()*Y).norm() / (X.transpose()*Y).norm()
的结果是:
2.80096e-007
由于我目前对我的基本数值类型使用单精度浮点数,因此两者几乎都是零。
根据您的验证,您得到的方案完全没问题。如果您想要更高的准确性,请使用 double
浮点数。请注意,MatLab/Octave 默认使用双精度。
此外,也可能是你的问题不是满秩的,在这种情况下你的问题有无限多的解。 ColPivHouseholderQR 任意选择一个。另一方面,mldivide 将选择您也可以使用 Eigen::BDCSVD
(Eigen 3.3)或较慢的 Eigen::JacobiSVD
.