序
最近在学习了eigen3
,使用它写线性判别分析(LDA),遇到了一些小问题,这里总结一下,方便日后使用。
问题:根据特征值大小对特征向量排序
首先,为了代码简洁,我使用using
指定了一些别名,
using eigMatrix = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>;
using eigVector = Eigen::Matrix<double, Eigen::Dynamic, 1>;
using eigEigenSolver = Eigen::EigenSolver<eigMatrix>;
using stdTupleEigen = std::tuple<double, eigMatrix>;
using stdVectorTuple = std::vector<stdTupleEigen>;
虽然在
eigen3
中已经帮我们定义好了,即,
typedef Eigen::Matrix<double, -1, -1> Eigen::MatrixXd
但是实际使用中,我会使用到模板,所以我自己指定了别名,然后把上面的double
替换成模板的typename
。
计算特征值和特征向量,
eigEigenSolver solver(myMatrix);
eigVector eigenValues = solver.pseudoEigenvalueMatrix().diagonal();
eigMatrix eigenVectors = solver.pseudoEigenvectors();
sortEigenVectorByValues(eigenValues, eigenVectors);
其中根据特征值大小对特征向量排序的方法实现如下,
void sortEigenVectorByValues(eigVector& eigenValues, eigMatrix& eigenVectors) {
stdVectorTuple eigenValueAndVector;
int size = static_cast<int>(eigenValues.size());
eigenValueAndVector.reserve(size);
for (int i = 0; i < size; ++i)
eigenValueAndVector.push_back(stdTupleEigen(eigenValues[i], eigenVectors.col(i)));
// 使用标准库中的sort,按从大到小排序
std::sort(eigenValueAndVector.begin(), eigenValueAndVector.end(),
[&](const stdTupleEigen& a, const stdTupleEigen& b) -> bool {
return std::get<0>(a) > std::get<0>(b);
});
for (int i = 0; i < size; ++i) {
//eigenValues[i] = std::get<0>(eigenValueAndVector[i]); // 排序后的特征值
eigenVectors.col(i).swap(std::get<1>(eigenValueAndVector[i])); // 排序后的特征向量
}
}