Eigen3中SelfAdjointEigenSolver矩阵类型错误排查求助
编写了计算自伴随矩阵特征值与特征向量的方法,但编译时出现Eigen3库Tridiagonalization.h头文件的C2672错误。怀疑问题出在传入的MatrixType(Eigen::Matrix<float, -1, DIMENSION>)上,想知道是否需要修改该类型,若需要应使用哪种类型?
相关代码
static void calculate(const Eigen::Matrix<float, DIMENSION, -1> &matrix, Eigen::Matrix<float, DIMENSION, 1> &mean, Eigen::Matrix<float, DIMENSION, DIMENSION> &eigenVectors, Eigen::Matrix<float, DIMENSION, 1> &eigenValues, Method method = SLOW) { mean = matrix.rowwise().mean(); Eigen::Matrix<float, -1, DIMENSION> meanCentered = (matrix.colwise() - mean).transpose(); Eigen::SelfAdjointEigenSolver<Eigen::Matrix<float, -1, DIMENSION> > solver(meanCentered, Eigen::ComputeFullV); }
错误信息
C:\Program Files (x86)\Eigen3\include\eigen3\Eigen\src/Eigenvalues/Tridiagonalization.h(434,52): error C2672: 'Eigen::internal::tridiagonalization_inplace_selector<MatrixType,-1,false>::run': 找不到匹配的重载函数 [C:\Users\JumpStart\repo-git\segmentationcpp\PlaneDetection\CommandLineOption\out\build\x64-release\src\planeprocessing_lib.vcxproj]
这个错误的核心原因是**SelfAdjointEigenSolver仅支持处理方阵**,但你传入的Eigen::Matrix<float, -1, DIMENSION>是动态行数、固定列数的非方阵类型,Eigen内部模板无法匹配到对应的实现逻辑。
你需要修正两个关键点:
- 自伴随矩阵特征值求解的输入必须是方阵,这里应计算数据的协方差矩阵(维度为
DIMENSION×DIMENSION的方阵),而非直接传入转置后的中心化数据。 - 给
SelfAdjointEigenSolver指定正确的方阵类型。
修正后的代码如下:
static void calculate(const Eigen::Matrix<float, DIMENSION, -1> &matrix, Eigen::Matrix<float, DIMENSION, 1> &mean, Eigen::Matrix<float, DIMENSION, DIMENSION> &eigenVectors, Eigen::Matrix<float, DIMENSION, 1> &eigenValues, Method method = SLOW) { mean = matrix.rowwise().mean(); // 计算中心化数据,保持原维度(DIMENSION行,动态列数) Eigen::Matrix<float, DIMENSION, -1> centered = matrix.colwise() - mean; // 计算协方差矩阵(自伴随方阵),若需无偏估计可除以(matrix.cols() - 1) Eigen::Matrix<float, DIMENSION, DIMENSION> cov = centered * centered.transpose(); // 使用固定大小的方阵类型初始化求解器 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<float, DIMENSION, DIMENSION>> solver(cov, Eigen::ComputeFullV); // 提取计算结果 eigenValues = solver.eigenValues(); eigenVectors = solver.eigenVectors(); }
如果你的场景中DIMENSION是动态值,也可以改用动态方阵类型Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic>,但固定大小的模板在性能上更有优势。
内容的提问来源于stack exchange,提问作者xeon123

