如何在Eigen3库中有效地提取复杂矩阵的实部/虚部?

Nic*_*rca 7 c++ matlab eigen3

我在Eigen3库中有一些复杂,密集的矢量/矩阵,我想将实部和虚部提取到单独的数组中.在Matlab中,我可以做类似的事情

cplxFoo = [1, 1i; -1i -1]
re = real(cplxFoo)
im = imag(cplxFoo)
Run Code Online (Sandbox Code Playgroud)

期望收益率

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
Run Code Online (Sandbox Code Playgroud)

有喜欢什么real(),并imag()在Eigen3 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

它工作,我甚至可以把它放在一个函数中,但后来我不得不做我自己的循环矢量化,展开等,而且我必须做一个额外的副本.

我希望能够做的是Map<MatrixXd>用适当的步幅包围几个cplxFoo来获得真实和想象的部分.但问题是,元素MatrixXcd是std::complex<double>,我不知道它的布局是什么.我的猜测是,std::complex<T>基本上奠定了一样struct {T real; T imag;};,这样实部和虚部紧凑和交织当你的数组std::complex<T>(和也似乎是共识这太问题),但是是保证由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); }
    /* ... */
};
Run Code Online (Sandbox Code Playgroud)

那么,可以Map<MatrixXd>用适当的步幅包裹几个cplxFoo吗?如果是这样,我该如何正确设置步幅?

或者,有没有办法让Eigen的复杂数据类型为真实和虚部使用单独的内存块?

对于它的价值,我需要这样做的原因是因为我需要将Eigen库与MATLAB接口,MATLAB只能处理实部和虚部的单独数组,而不是以任何方式交错.

gga*_*ael 10

这很简单,只需使用.real()和.imag()视图:

MatrixXcd M;
MatrixXd r, i;
r = M.real();
i.imag();
Run Code Online (Sandbox Code Playgroud)

请注意,您可以使用M.real()表达式而不将其复制到表达式中MatrixXd.