Eigen调用matrix().cos()触发不完整类型编译错误咨询
Eigen逐元素余弦计算编译报错修复
可正常运行的原始代码
Matrix <float, ny+1, nx> eXX; eXX.setZero(); Eigen::Matrix< double, (ny+1), (ny)> u; u.setZero(); for(int i = 0; i< nx; i++){ for(int j = 0; j< ny+1; j++){ eXX(j + (ny+1)*i) = (i)*2*EIGEN_PI/nx; u(j + (ny+1)*i) = cos(eXX(j + (ny+1)*i)); } }
改写后编译失败的代码
Matrix <float, ny+1, nx> eXX; eXX.setZero(); Eigen::Matrix< double, (ny+1), (ny)> u; u.setZero(); for(int i = 0; i< nx; i++){ for(int j = 0; j< ny+1; j++){ eXX(j + (ny+1)*i) = (i)*2*EIGEN_PI/nx; } } u = eXX.matrix().cos();// -or- std::cos(eXX.array()); std::cout << u << "\n"; //error
完整报错信息
Test.cpp:418:23: error: invalid use of incomplete type ‘const class Eigen::MatrixFunctionReturnValue<Eigen::Matrix<float, 11, 10> >’ 418 | u = eXX.matrix().cos(); | ^ In file included from /mnt/c/Users/eigen-3.4.0/eigen-3.4.0/Eigen/Core:163, from /mnt/c/Users/eigen-3.4.0/eigen-3.4.0/Eigen/Dense:1, from Test.cpp:21: /mnt/c/Users/eigen-3.4.0/eigen-3.4.0/Eigen/src/Core/util/ForwardDeclarations.h:305:34: note: declaration of ‘class Eigen::MatrixFunctionReturnValue<Eigen::Matrix<float, 11, 10> >’ 305 | template<typename Derived> class MatrixFunctionReturnValue;
已尝试的无效方案
- 重写
eXX的赋值逻辑,问题没有解决 - 按照网上说法引入
#include <MatrixFunctionReturnValue>头文件,反而出现更多编译错误
当前代码引入的所有头文件如下:
#define _USE_MATH_DEFINES #include <cmath> #include<math.h> #include<stdio.h> #include "fftw3.h" #include <cstring> #include <sstream> #include <string> #include <sys/resource.h> #include <iostream> #include <vector> #include <fstream> #include <iomanip> #include <numeric> #include <assert.h> #include <Eigen/Dense> #include <unsupported/Eigen/FFT> #include <Eigen/SparseCore> #include <Eigen/Sparse>
问题原因
两个核心问题:
- 用错了cos接口:
eXX.matrix().cos()调用的是Eigen的矩阵余弦函数,属于高等矩阵运算,计算的是基于矩阵泰勒展开定义的矩阵余弦值,根本不是你要的「对每个元素单独算余弦」的逐元素操作。而且这个模块不在<Eigen/Dense>默认引入的范围内,所以会报不完整类型的错误。 - 头文件引错了:
MatrixFunctionReturnValue是Eigen内部实现用的类,对应的头文件不是给用户直接引入的,硬引肯定会出一堆错。
修复方法
你要的效果和原始循环完全一致,就是逐元素算余弦,根本不需要引入额外头文件,用Eigen的Array逐元素运算接口就行,注意处理好类型和维度匹配:
// 逐元素计算cos,float转double,取前ny列适配u的维度(如果nx==ny可以去掉.block部分) u = eXX.cast<double>().array().cos().block(0, 0, ny+1, ny); std::cout << u << std::endl;
如果你确实是要计算矩阵余弦(不是逐元素),再补加官方对外的头文件即可:
#include <Eigen/MatrixFunctions>
加完之后matrix().cos()就能正常编译,但计算结果和你原始循环的逻辑完全不一样,不要乱用。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

