【发布时间】:2014-04-14 22:07:54
【问题描述】:
我在 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); }
/* ... */
};
那么,可以在cplxFoo 周围适当地包裹几个Map<MatrixXd> 吗?如果是这样,我该如何正确设置步幅?
或者,有没有办法让 Eigen 的复杂数据类型为实部和虚部使用单独的内存块?
对于它的价值,我需要这样做的原因是因为我需要将 Eigen 库与 MATLAB 接口,它只能处理实部和虚部的单独数组,不能以任何方式交错。
【问题讨论】:
-
std::complex<T>的布局保证与两个T值(实部后跟虚部)的数组兼容,并且数组可以按照您的期望进行泛化。 (但我对 Eigen 的了解不够,无法回答其他问题)。 -
如果我没有弄错文档,
cplxFoo.imag()和cplxFoo.real()应该可以工作。你试过吗? -
@anderas 该死的,它有效!我希望我能在文档中看到它,可以为我省去很多麻烦。
-
@anderas 您的评论与 Mike 的结合完全回答了我的问题。