通过cuFFT在逆FFT中缩放

Ani*_*Ani 5 matlab scaling cuda fft cufft

每当我绘制一个使用cuFFT程序获得的值并将结果与​​Matlab进行比较时,我都会得到相同形状的图形,并且最大值和最小值都在相同的点上。但是,cuFFT产生的值比Matlab产生的值大得多。Matlab代码是

fs = 1000;                              % sample freq
D = [0:1:4]';                           % pulse delay times
t = 0 : 1/fs : 4000/fs;                 % signal evaluation time
w = 0.5;                                % width of each pulse
yp = pulstran(t,D,'rectpuls',w);
filt = conj(fliplr(yp));
xx = fft(yp,1024).*fft(filt,1024);
xx = (abs(ifft(xx)));    
Run Code Online (Sandbox Code Playgroud)

输入相同的CUDA代码如下:

cufftExecC2C(plan, (cufftComplex *)d_signal, (cufftComplex *)d_signal, CUFFT_FORWARD);
cufftExecC2C(plan, (cufftComplex *)d_filter_signal, (cufftComplex *)d_filter_signal,     CUFFT_FORWARD);
ComplexPointwiseMul<<<blocksPerGrid, threadsPerBlock>>>(d_signal, d_filter_signal, NX);
cufftExecC2C(plan, (cufftComplex *)d_signal, (cufftComplex *)d_signal, CUFFT_INVERSE);
Run Code Online (Sandbox Code Playgroud)

cuFFT还执行1024批处理大小为的点FFT 2

使用的比例因子时NX=1024,值不正确。请告诉该怎么办。

Jac*_*ern 5

这是一个较晚的答案,可以从未答复的列表中删除此问题。

您没有提供足够的信息来诊断问题,因为您缺少指定cuFFT计划的方式。您甚至没有指定Matlab和cuFFT信号的形状完全相同(因此您只有缩放比例)还是形状大致相同。但是,让我进行以下两个观察:

  1. yp矢量具有4000元件; 与bym相反fft(yp,1024),您正在通过将信号截短到1024元素来执行FFT ;
  2. 逆cuFFT不执行矢量元素数量的缩放。

为了方便起见(可能对其他用户有用),我在下面报告一个简单的FFT-IFFT方案,该方案还包括使用CUDA Thrust库执行的缩放。

#include <cufft.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

/*********************/
/* SCALE BY CONSTANT */
/*********************/
class Scale_by_constant
{
    private:
        float c_;

    public:
        Scale_by_constant(float c) { c_ = c; };

        __host__ __device__ float2 operator()(float2 &a) const
        {
            float2 output;

            output.x = a.x / c_;
            output.y = a.y / c_;

            return output;
        }

};

int main(void){

    const int N=4;

    // --- Setting up input device vector    
    thrust::device_vector<float2> d_vec(N,make_cuComplex(1.f,2.f));

    cufftHandle plan;
    cufftPlan1d(&plan, N, CUFFT_C2C, 1);

    // --- Perform in-place direct Fourier transform
    cufftExecC2C(plan, thrust::raw_pointer_cast(d_vec.data()),thrust::raw_pointer_cast(d_vec.data()), CUFFT_FORWARD);

    // --- Perform in-place inverse Fourier transform
    cufftExecC2C(plan, thrust::raw_pointer_cast(d_vec.data()),thrust::raw_pointer_cast(d_vec.data()), CUFFT_INVERSE);

    thrust::transform(d_vec.begin(), d_vec.end(), d_vec.begin(), Scale_by_constant((float)(N)));

    // --- Setting up output host vector    
    thrust::host_vector<float2> h_vec(d_vec);

    for (int i=0; i<N; i++) printf("Element #%i; Real part = %f; Imaginary part: %f\n",i,h_vec[i].x,h_vec[i].y);

    getchar();
}
Run Code Online (Sandbox Code Playgroud)