[Math] - FFT By Using Math.NET Numberics

Posted by William Basics on Sunday, November 28, 2021

引言

快速傅里叶变换是信号处理的常用工具。当我们想要对时间域里的连续信号进行成分分析时,我们就需要通过傅里叶变换来将时间域的连续信号转化为频率域的离散形式。这样我们就能知道这信号的频率成分以及相对的增益大小。

图片来自网络

Math.NET Numberics

Math.NET Numberics 是.NET平台的一个开源数学工具库。它使用的是MIT/X11许可证,用于开源或者商用项目皆可。Github上的项目地址是: https://github.com/mathnet/mathnet-numerics 。可以通过NuGet直接安装。官网地址是: https://numerics.mathdotnet.com/

我们今天将借助它的傅里叶变换的相关函数来处理时间域信号的成分分析。

示例工程

在Visual Studio 2019中创建一个WPF工程。加入 ScottPlot.WPF 以及 MathNet.Numerics

nuget

using FourierOptions = MathNet.Numerics.IntegralTransforms.FourierOptions;
using Fourier = MathNet.Numerics.IntegralTransforms.Fourier;

分别创建频率为 1Hz,2Hz和 3Hz的正弦信号。采样率为64Hz。

var sampleRate = 64;
var sampleLen = sampleRate * 4;
var signal1Hz = SignalGen.Sinusoidal(sampleLen, sampleRate, 1, 1);
var signal2Hz = SignalGen.Sinusoidal(sampleLen, sampleRate, 2, 1);
var signal3Hz = SignalGen.Sinusoidal(sampleLen, sampleRate, 3, 1);

signals

信号混合一下

var signalMixed = new double[signal1Hz.Length];

for (int i = 0; i < signal1Hz.Length; i++)
{
    signalMixed[i] += signal1Hz[i];
    signalMixed[i] += signal2Hz[i];
    signalMixed[i] += signal3Hz[i];
}

我们得到 mixed signal

我们实际采样到的信号一般都是混合的信号,我们就以它为例来做FFT。

// 需要先转化为复数。
var dataClone = signalMixed.Select(d => new Complex(d, 0.0)).ToArray();

// FFT
Fourier.Forward(dataClone, FourierOptions.Default);

// 提取出频率对应的幅值
var fft = dataClone.Select(d => d.Magnitude).ToArray();
// 计算出频率的分布范围
var scale = Fourier.FrequencyScale(fft.Length, sampleRate);

FFT图如下: FFT

从图上看出,混合信号是由1Hz,2Hz和3Hz 三个信号混合而成的。

小结

以上就是通过 Math.NET Numberics 对信号做快速傅里叶变换的一个样例。除了FFT以外, Math.NET Numberics 还有很多其他的数学工具。我们以后有机会再一起学习。

最后,整个样例工程可以在此访问 Github

(end)