用Eigen查找最接近的正定矩阵

时间:2020-05-06 15:33:52

标签: c++ matrix eigen

我想找到最接近X矩阵的正定矩阵。

我在这里看到了这个答案:https://scicomp.stackexchange.com/questions/30631/how-to-find-the-nearest-a-near-positive-definite-from-a-given-matrix

但是我在将其转换为Eigen的答案时遇到了麻烦。我尝试了以下方法:

Matrix<double, 9, 9> X, D, DPLUS, Z, Y;
X.setRandom();
Y = 0.5 * (X + X.transpose().eval());
EigenSolver<Matrix<double, 9, 9>> es;
es.compute(Y);
D = es.eigenvalues().asDiagonal();
DPlus = D.cwiseMax(0);
Z = es.eigenvectors() * DPLUS * es.eigenvectors().transpose().eval();

这给了我一个复杂问题的错误,但这是否与链接的答案所暗示的内容一致?

1 个答案:

答案 0 :(得分:1)

您没有使用正确的特征值求解器的问题。

由于矩阵 Y 在构造上是对称的,因此需要使用SelfAdjointEigenSolver。 这种对称性确保您的实矩阵是对角线化的,并且具有实特征值和特征向量,因此您不必处理复数。

一般的EigenSolver不做这个假设,因此在这种情况下无法按预期工作。您可能会得到相同的结果(您将获得实际上是真实的复本征值,但您需要创建复数矢量等。效率也低得多)。

这将为您提供本征值和本征向量,可用于构建正交基矩阵 Q

const MatrixXd Y = 0.5 * (X + X.transpose());
const SelfAdjointEigenSolver<MatrixXd> solver(Y);
const VectorXd D = solver.eigenvalues();
const MatrixXd Q = solver.eigenvectors();
const VectorXd Dplus = D.cwiseMax(0);
const MatrixXd Z = Q * Dplus.asDiagonal() * Q.transpose();

当然,如果您喜欢单线,可以随时将其缩短为:

const SelfAdjointEigenSolver<MatrixXd> solver(0.5 * (X + X.transpose()));
const MatrixXd Z = solver.eigenvectors() * solver.eigenvalues().cwiseMax(0).asDiagonal() * solver.eigenvectors().transpose();
相关问题