我在Eigen3库中有一些复杂,密集的矢量/矩阵,我想将实部和虚部提取到单独的数组中。在Matlab中,我可以做类似
的事情cplxFoo = [1, 1i; -1i -1]
re = real(cplxFoo)
im = imag(cplxFoo)
期望产生
cplxFoo =
1.0000 + 0.0000i 0.0000 + 1.0000i
0.0000 - 1.0000i -1.0000 + 0.0000i
re =
1 0
0 -1
im =
0 1
-1 0
Eigen3中有real()
和imag()
Matlab函数吗?
现在,我知道唯一可行的方法就是
MatrixXcd cplxFoo = ...;
MatrixXd re(cplxFoo.rows(), cplxFoo.cols());
MatrixXd im(cplxFoo.rows(), cplxFoo.cols());
for(size_t j=0; j<cplxFoo.cols(); ++j) {
for(size_t i=0; i<cplxFoo.rows(); ++i) {
re(i, j) = cplxFoo(i,j).real();
im(i, j) = cplxFoo(i,j).imag();
}
}
它可以工作,我甚至可以把它放在一个函数中,但是我不得不做自己的循环矢量化,展开等等,而且我必须做一个额外的副本。
我希望能够做的是在Map<MatrixXd>
周围以适当的步幅包裹几个cplxFoo
以获得实部和虚部。但问题是MatrixXcd
的元素是std::complex<double>
,我不确定它的布局是什么。我的猜测是std::complex<T>
基本上像struct {T real; T imag;};
那样布局,这样当你创建一个std::complex<T>
数组时,实部和虚部就会被紧密打包和交错(和这也似乎是this SO question)的共识,但这是否由C ++标准保证? AFAICT,一个兼容的C ++编译器可以像struct {T imag; T real;};
那样(注意改变的顺序),或者像
class {
T radius;
T angle;
public:
T real() const { return radius * cos(angle); }
T imag() const { return radius * sin(angle); }
/* ... */
};
那么,是否可以在Map<MatrixXd>
周围以适当的步幅包裹几个cplxFoo
?如果是这样,我该如何正确设置步幅?
或者,有没有办法让Eigen的复杂数据类型为实部和虚部使用单独的内存块?
对于它的价值,我需要这样做的原因是因为我需要将Eigen库与MATLAB接口,MATLAB只能处理实部和虚部的单独数组,而不是以任何方式交错。
答案 0 :(得分:10)
这很简单,只需使用.real()
和.imag()
次观看次数:
MatrixXcd M;
MatrixXd r, i;
r = M.real();
i.imag();
请注意,您可以将M.real()
用于表达式,而无需将其复制到MatrixXd
。