【问题标题】:Make Math.NET Fourier work使 Math.NET 傅里叶工作
【发布时间】:2016-06-03 01:54:06
【问题描述】:

我正在努力寻找解决方案几个星期,我真的已经阅读了与这个主题相关的所有主题,所以我真的希望有人能帮助我解决这个问题。

我想要做的是使用一个波形文件作为输入,对其进行傅里叶变换,然后将这些值与另一个文件进行比较并得到差异。

我长期以来一直致力于解决的挑战是让傅里叶变换发挥作用。

我只得到 NaN 值,而不是给我合理的结果。

我有以下代码:

public FFTPerformer(float[] soundvalues)
    {
        buffer = new System.Numerics.Complex[4096];
        try {
            for (int i = 0; i < 4096; i++)
            {
                System.Numerics.Complex tmp = new System.Numerics.Complex(soundvalues[i], 0);
                buffer[i] = tmp;
            }
        }
        catch(Exception ex)
        {
            System.Windows.MessageBox.Show("Es ist ein Fehler bei der Konvertierung des float arrays zum Complex-Array aufgetreten; " + ex.Message);
        }
    }

4096 通常被一个更大的数字代替,它仍然是 2 的幂,但它甚至不能与那个数字一起使用。

public void performFFT()
    {
        try
        {
            MathNet.Numerics.IntegralTransforms.Fourier.Forward(buffer, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);
        }
        catch(Exception ex)
        {
            System.Windows.MessageBox.Show("Fehler: " + ex.Message);
        }
    }

更详细的描述: 我为 4096 个值设置了长度,因为这是两倍,这个长度仅用于测试目的,因此这比使用数百万个值的原始声音文件检查起来要快一点;)所以这只是像这样,只要算法没有被证明有效。这也是奇怪的for循环的原因。即使是很难的 Math.Net 也使用 Bluestein 的算法进行计算,无论如何尝试使用两个数组的因子,因为即使他们使用任何其他算法 atm,它们也应该可以工作。

由于浮点十进制转换,尝试使用该 try-catch 获取错误消息,但它没有引发任何错误。

我现在的问题是,我在那个 fft 中发送了 4096 个复数,它们都有 Y=0,但是 X 取决于音频文件(在另一个线程中读取音频不需要 Y 值- fft 所以你应该将它们设置为 0)。所有 X 值都是正常的浮点数,没有 NaN。但是,FFT 仍然返回一个充满 NaN 的数组。

我首先尝试转换为 System.Numerics.Complex 隐式,但没有成功,所以我使用 tmp 变量来构造。

编辑: 我最终阅读了更多关于 FFT 算法的文章。 现在我仍然让我的声音值浮动并将它们转换为复杂数组。我检查了所有转换步骤的一致性,这在那个区域很好。所以我的问题是我是否真的只需要使用这个

MathNet.Numerics.IntegralTransforms.Fourier.Forward(buffer, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);

或者如果我需要在此之前在 Math.NET 中做一个干净的 FFT

【问题讨论】:

  • 嘿,欢迎来到 SO!德语对我来说没问题,但在这里发帖时您仍应将错误消息翻译成英语。
  • FFT 全部为 NaN 的结果表明至少有一个输入值是 NaN。
  • 如果你的意思是Math.net - 你可以为它添加标签 - 它可能会有所帮助。
  • @MarcusMüller:谢谢,只是忘记更改了。现在将对其进行编辑。我检查了 NaN 的输入,但没有,但我明天再检查一次。

标签: c# fft nan mathnet-numerics


【解决方案1】:

为什么要先分配 buffer 与 4096 个元素,然后为每个元素分配一个 Complex?看起来不对。

只需设置buffer[i].real = soundvalues[i].imag=0(从某种意义上说,不是字面意思。我不会“说”C#)。

编辑

https://msdn.microsoft.com/en-us/library/ee259559%28v=vs.110%29.aspx 解释说存在从 Decimal 到 Complex 的隐式转换,将生成的复数设置为 (Decimal + 0i);这意味着你应该只是

for (int i = 0; i < 4096; i++)
{
    buffer[i] = soundvalues[i];
}

我怀疑你的声音值仍然包含 NaN;也许您的输入有问题?

【讨论】:

  • 构造函数已经这样做了。 (var z = new Complex(float real, float imag))。但实际上,这里的问题是分配了 4096 个复数的静态缓冲区,并且根本没有考虑 float[] soundvalues 的长度。他可能打算将soundvalues[] 分割成长度为4096 的n 子数组并对它们中的每一个进行傅里叶变换?
  • 完全正确。而new Type[4096]分配了4096个元素,所以每个元素都已经存在了;由于存在从 Decimal 到 Complex 的隐式转换,msdn.microsoft.com/en-us/library/ee259559%28v=vs.110%29.aspx,Op 应该只是 buffer[i] = soundvalues[i]
  • @MarcusMüller 我在帖子中写了一个更长的答案,这解释了为什么我这样做:)
猜你喜欢
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2011-07-12
相关资源
最近更新 更多