如何将一个 C++ 数组复制到 Eigen 张量中

huangapple go评论72阅读模式
英文:

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));

huangapple
  • 本文由 发表于 2023年4月11日 10:05:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75981925.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定