复杂的数组fft-ifft对在每次迭代时都会彻底改变数值,这正常吗?

问题描述 投票:0回答:1

所以,简单的3D fft-ifft对复杂值的数组 代码在此:

using System;
using System.Diagnostics;
using System.Numerics;
using System.Runtime.InteropServices;
using ManagedCuda.BasicTypes;
using ManagedCuda;
using ManagedCuda.CudaFFT;
using ManagedCuda.VectorTypes;

class ManagedCuda3DComplexFFT
{
    public static class Extensions
    {
        public delegate void ActOn3DArrayElement(ref cuFloatComplex element, int i, int j, int k);

        public static void ForEach(ref cuFloatComplex[,,] arr, ActOn3DArrayElement act)
        {
            for (int i = 0; i < arr.GetLength(0); i++)
            {
                for (int j = 0; j < arr.GetLength(1); j++)
                {
                    for (int k = 0; k < arr.GetLength(2); k++)
                    {
                        act(ref arr[i, j, k], i, j, k);
                    }
                }
            }   
        }
        public static string ToString(ref cuFloatComplex[,,] arr)
        {
            string result = "";
            for (int i = 0; i < arr.GetLength(0); i++)
            {
                result += "\n" + i.ToString() + " {[\n";
                for (int j = 0; j < arr.GetLength(1); j++)
                {
                    result +=  "[";
                    for (int k = 0; k < arr.GetLength(2); k++)
                    {
                        result += arr[i, j, k].ToString() + "; ";
                    }
                    result += "]\n";
                }
                result += "]};";
            }

            return result;
        }
    }


    static void Main(string[] args)
    {
        const int DIM = 2;

        CudaContext ctx = new CudaContext(0);

        var dx = new CudaDeviceVariable<cuFloatComplex>( DIM*DIM*DIM);
        var data = new cuFloatComplex[DIM,DIM,DIM];
        var fftdData = new cuFloatComplex[DIM,DIM,DIM];
        var ifftdData = new cuFloatComplex[DIM,DIM,DIM];
        Extensions.ForEach(ref data, (ref cuFloatComplex element, int i, int j, int k) =>
        {
            element.real = 1;
            element.imag = 1;
        } );
        Console.WriteLine("source: " + Extensions.ToString(ref data));
        dx.CopyToDevice(data);
        var plan = new CudaFFTPlan3D(DIM, DIM, DIM, cufftType.C2C);
        for (int z = 0; z < 3; z++)
        {
            Console.WriteLine("iteration == " + z);
            plan.Exec(dx.DevicePointer, TransformDirection.Forward); // now inside dx.DevicePointer fftd data 
            dx.CopyToHost(fftdData);
            plan.Exec(dx.DevicePointer, TransformDirection.Inverse); // now inside dx.DevicePointer ifftd data 
            dx.CopyToHost(ifftdData);

            Console.WriteLine("fft: " + Extensions.ToString(ref fftdData));
            Console.WriteLine("ifft: " + Extensions.ToString(ref ifftdData));
            Console.WriteLine("==========================");

        }

        return;
}

返回变化的值示例输出。

source: 
0 {[
[1 + 1i; 1 + 1i; ]
[1 + 1i; 1 + 1i; ]
]};
1 {[
[1 + 1i; 1 + 1i; ]
[1 + 1i; 1 + 1i; ]
]};
iteration == 0
fft: 
0 {[
[8 + 8i; 0 + 0i; ]
[0 + 0i; 0 + 0i; ]
]};
1 {[
[0 + 0i; 0 + 0i; ]
[0 + 0i; 0 + 0i; ]
]};
ifft: 
0 {[
[8 + 8i; 8 + 8i; ]
[8 + 8i; 8 + 8i; ]
]};
1 {[
[8 + 8i; 8 + 8i; ]
[8 + 8i; 8 + 8i; ]
]};
==========================
iteration == 1
fft: 
0 {[
[64 + 64i; 0 + 0i; ]
[0 + 0i; 0 + 0i; ]
]};
1 {[
[0 + 0i; 0 + 0i; ]
[0 + 0i; 0 + 0i; ]
]};
ifft: 
0 {[
[64 + 64i; 64 + 64i; ]
[64 + 64i; 64 + 64i; ]
]};
1 {[
[64 + 64i; 64 + 64i; ]
[64 + 64i; 64 + 64i; ]
]};
==========================
iteration == 2
fft: 
0 {[
[512 + 512i; 0 + 0i; ]
[0 + 0i; 0 + 0i; ]
]};
1 {[
[0 + 0i; 0 + 0i; ]
[0 + 0i; 0 + 0i; ]
]};
ifft: 
0 {[
[512 + 512i; 512 + 512i; ]
[512 + 512i; 512 + 512i; ]
]};
1 {[
[512 + 512i; 512 + 512i; ]
[512 + 512i; 512 + 512i; ]
]};
==========================
c# math fft complex-numbers managed-cuda
1个回答
2
投票

你有一个非标准化的FFTIFFT对。每一次迭代,数组的值都会增长一个系数,即为 N 阵列中的样本数)。

通常情况下,逆向变换有一个 1/N 中的因子,但有些实现将该因子放在正向变换中,或者通过添加一个 1/sqrt(N) 的两个变换。

有些实现只是想快速地实现,并省去了归一化以节省 N 乘法。你似乎有一个这样的实现。你必须自己添加规范化。

© www.soinside.com 2019 - 2024. All rights reserved.