使用 Eigen 找到最近的正定矩阵

Find the nearest postive definte matrix with 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();

这是一个复杂问题的错误提示,但这是否符合链接答案的建议?

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

由于矩阵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();