英文:
How to copy a c++ array into eigen tensor
问题
以下是代码部分的翻译:
我有一段代码,它对Eigen张量进行3D FFT,并返回一个Eigen张量输出。我正在使用C++数组将其传递给FFTW计划,但是我遇到了获取正确输出(即大小不对)的问题。是否有更好的方法来使用Eigen::map将“output_array”中的内容复制到Eigen张量中,而不是使用for循环?
示例代码:
主代码
```cpp
static const int nx = 4;
static const int ny = 4;
static const int nz = 4;
void r2cfft3d(Eigen::Tensor<double, 3>& rArr, Eigen::Tensor<std::complex<double>, 3>& cArr){
fftw_complex *input_array;
input_array = (fftw_complex*) fftw_malloc(nx*ny*nz * sizeof(fftw_complex));
memcpy(input_array, rArr.data(), nx*ny*nz * sizeof(fftw_complex));
fftw_complex *output_array;
output_array = (fftw_complex*) fftw_malloc(nx*ny*nz * sizeof(fftw_complex));
fftw_plan forward = fftw_plan_dft_3d(nx, ny, nz, input_array, output_array, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(forward);
fftw_destroy_plan(forward);
fftw_cleanup();
for(int i=0; i < nx; ++i){
for(int j=0; j < ny; ++j) {
for(int k=0; k < nz; ++k) {
cArr(i,j,k).real(output_array[i + nz * (j + ny * k)][REAL]);
cArr(i,j,k).imag(output_array[i + nz * (j + ny * k)][IMAG]);
}
}
}
fftw_free(input_array);
fftw_free(output_array);
}
这返回以下结果:
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 -9.53674e-07 -9.53674e-07 -9.53674e-07 2.86102e-06 0 0 0 0
1e+11 1e+11 1e+11 1e+11 1e+11 5e+11 1e+11 1e+11 -4.76837e-06 -4.76837e-06 -4.76837e-06 -1.62125e-05 -1.52588e-05 -1.52588e-05 -1.52588e-05 -1.52588e-05
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 -9.53674e-07 -9.53674e-07 -9.53674e-07 2.86102e-06 0 0 0 0
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 -8.58307e-06 -8.58307e-06 -8.58307e-06 -4.76837e-06 -7.62939e-06 -7.62939e-06 -7.62939e-06 -7.62939e-06
而正确答案是
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 5e+11 1e+11 1e+11 1e+11 1e+11 1e+11
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11
看起来某些列被填充为零,行和列也不正确(即5e11的位置)。
是否有一种方法可以代替此处的for循环使用类似于以下的东西:
TensorMap<Eigen::Tensor<std::complex<double>, 3>> test(output_array, nx,ny,nz);
英文:
I have a code that takes the 3D FFT of an Eigen tensor and returns an Eigen tensor output. I am using a c++ array to pass it to the FFTW plan however I am having an issue getting the correct output (i.e. the size is off). Is there a better way to copy the content of the ''output_array'' into an Eigen tensor using Eigen::map instead of a for loop?
Code example:
Main code
static const int nx = 4;
static const int ny = 4;
static const int nz = 4;
void r2cfft3d(Eigen::Tensor<double, 3>& rArr, Eigen::Tensor<std::complex<double>, 3>& cArr){
fftw_complex *input_array;
input_array = (fftw_complex*) fftw_malloc(nx*ny*nz * sizeof(fftw_complex));
memcpy(input_array, rArr.data(), nx*ny*nz * sizeof(fftw_complex));
fftw_complex *output_array;
output_array = (fftw_complex*) fftw_malloc(nx*ny*nz * sizeof(fftw_complex));
fftw_plan forward = fftw_plan_dft_3d(nx, ny, nz, input_array, output_array, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(forward);
fftw_destroy_plan(forward);
fftw_cleanup();
for(int i=0; i < nx; ++i){
for(int j=0; j < ny; ++j) {
for(int k=0; k < nz; ++k) {
cArr(i,j,k).real(output_array[i + nz * (j + ny * k)][REAL]);
cArr(i,j,k).imag(output_array[i + nz * (j + ny * k)][IMAG]);
}
}
}
fftw_free(input_array);
fftw_free(output_array);
}
This returns the following:
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 -9.53674e-07 -9.53674e-07 -9.53674e-07 2.86102e-06 0 0 0 0
1e+11 1e+11 1e+11 1e+11 1e+11 5e+11 1e+11 1e+11 -4.76837e-06 -4.76837e-06 -4.76837e-06 -1.62125e-05 -1.52588e-05 -1.52588e-05 -1.52588e-05 -1.52588e-05
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 -9.53674e-07 -9.53674e-07 -9.53674e-07 2.86102e-06 0 0 0 0
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 -8.58307e-06 -8.58307e-06 -8.58307e-06 -4.76837e-06 -7.62939e-06 -7.62939e-06 -7.62939e-06 -7.62939e-06
While the correct answer is
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 5e+11 1e+11 1e+11 1e+11 1e+11 1e+11
1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11 1e+11
It seems like some columns are being filled with zeros for some reason and the rows and columns are off as well (i.e. location of 5e11)
Is there a way to use something like this instead of the for loop here:
TensorMap<Eigen::Tensor<std::complex<double>, 3>> test(output_array, nx,ny,nz);
答案1
得分: 0
我通过实际使用 memcpy
来修复了这个问题。所以,不是使用 for 循环,而是添加了以下行:
memcpy(cArr.data(), output_array, nx*ny*nz * sizeof(fftw_complex));
英文:
I was able to fix this by using memcpy
actually. So, instead of the for loop I added the line:
memcpy(cArr.data(),output_array, nx*ny*nz * sizeof(fftw_complex));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论