gpt4 book ai didi

c# - 这个傅立叶变换实现有什么问题

转载 作者:可可西里 更新时间:2023-11-01 08:27:42 29 4
gpt4 key购买 nike

我正在尝试实现离散傅里叶变换,但它不起作用。我可能在某处写了一个错误,但我还没有找到它。

基于以下公式:

terere

此函数执行第一个循环,遍历 X0 - Xn-1... enter image description here

    public Complex[] Transform(Complex[] data, bool reverse)
{
var transformed = new Complex[data.Length];
for(var i = 0; i < data.Length; i++)
{
//I create a method to calculate a single value
transformed[i] = TransformSingle(i, data, reverse);
}
return transformed;
}

而实际的计算,这可能就是错误所在。

    private Complex TransformSingle(int k, Complex[] data, bool reverse)
{
var sign = reverse ? 1.0: -1.0;
var transformed = Complex.Zero;
var argument = sign*2.0*Math.PI*k/data.Length;
for(var i = 0; i < data.Length; i++)
{
transformed += data[i]*Complex.FromPolarCoordinates(1, argument*i);
}
return transformed;
}

接下来解释其余代码:

var sign = reverse ? 1.0: -1.0; 反向 DFT 的参数中没有 -1,而常规 DFT 的参数中有 -1

enter image description here

var argument = sign*2.0*Math.PI*k/data.Length; 是算法的参数。这部分:

enter image description here

然后是最后一部分

transformed += data[i]*Complex.FromPolarCoordinates(1, argument*i);

我想我仔细复制了算法,所以我看不出我在哪里犯了错误......

附加信息

正如 Adam Gritt 在他的回答中所展示的,AForge.net 很好地实现了该算法。我大概可以通过复制他们的代码在 30 秒内解决这个问题。但是,我仍然不知道我在实现过程中做错了什么。

我真的很好奇我的缺陷在哪里,我解释错了什么。

最佳答案

我做复杂数学的日子现在已经过去了,所以我自己可能会遗漏一些东西。但是,在我看来,您正在执行以下行:

transformed += data[i]*Complex.FromPolarCoordinates(1, argument*i);

什么时候应该更像:

transformed += data[i]*Math.Pow(Math.E, Complex.FromPolarCoordinates(1, argument*i));

除非您将其包装到方法 FromPolarCoordinates()

更新:我在 AForge.NET Framework 中找到了以下代码库,它显示了您的代码中未处理的其他已完成的 Cos/Sin 操作。可以在 Sources\Math\FourierTransform.cs: DFT 方法中的完整上下文中找到此代码。

for ( int i = 0; i < n; i++ )
{
dst[i] = Complex.Zero;

arg = - (int) direction * 2.0 * System.Math.PI * (double) i / (double) n;

// sum source elements
for ( int j = 0; j < n; j++ )
{
cos = System.Math.Cos( j * arg );
sin = System.Math.Sin( j * arg );

dst[i].Re += ( data[j].Re * cos - data[j].Im * sin );
dst[i].Im += ( data[j].Re * sin + data[j].Im * cos );
}
}

它使用自定义的 Complex 类(因为它是 4.0 之前的版本)。大多数数学运算与您已实现的相似,但内部迭代是对实部和虚部进行额外的数学运算。

进一步更新:经过一些实现和测试,我发现上面的代码和问题中提供的代码产生相同的结果。我还发现,根据评论,从这段代码生成的内容与 WolframAlpha 生成的内容之间有什么区别。结果的不同之处在于,Wolfram 似乎正在对结果应用 1/sqrt(N) 的归一化。在提供的 Wolfram 链接中,如果每个值都乘以 Sqrt(2),则这些值与上述代码生成的值相同(舍入误差除外)。我通过将 3、4 和 5 值传递给 Wolfram 来对此进行测试,发现我的结果分别因 Sqrt(3)、Sqrt(4) 和 Sqrt(5) 而不同。基于Discrete Fourier Transform维基百科提供的信息确实提到了使 DFT 和 IDFT 单一变换的规范化。这可能是您需要查看以修改代码或了解 Wolfram 可能在做什么的途径。

关于c# - 这个傅立叶变换实现有什么问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5715835/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com