C# fft结果c的功率谱密度#

C# fft结果c的功率谱密度#,c#,matlab,signal-processing,fft,spectral-density,C#,Matlab,Signal Processing,Fft,Spectral Density,我有一个复合体[](来自CsCore),这是我FFT的结果 复数有一个浮点实数和一个浮点虚数 根据这一点,我计算如下 频率:(双)索引*采样器/FFT大小 振幅/幅度:Math.Sqrt(Math.Pow(实,2)+Math.Pow(虚,2)) 阶段:Math.Atan(虚/实) 如果这些是错误的,请纠正我 据我所知,这是频域信息,它让我可以看到哪些频率在我的样本中最常见。现在我想看看功率密度随时间的变化。显示示例,但我不理解,因为我不懂Matlab。有人能解释一下关于这个主题的Matlab

我有一个
复合体[]
(来自CsCore),这是我FFT的结果

复数
有一个
浮点实数
和一个
浮点虚数

根据这一点,我计算如下

  • 频率:
    (双)索引*采样器/FFT大小
  • 振幅/幅度:
    Math.Sqrt(Math.Pow(实,2)+Math.Pow(虚,2))
  • 阶段:
    Math.Atan(虚/实)
如果这些是错误的,请纠正我

据我所知,这是频域信息,它让我可以看到哪些频率在我的样本中最常见。现在我想看看功率密度随时间的变化。显示示例,但我不理解,因为我不懂Matlab。有人能解释一下关于这个主题的Matlab文档,或者帮我做一个C#实现吗

编辑:
建议简单地将振幅平方。这是正确的吗?

事实上,正如我在中所述,您可以通过平方FFT结果的振幅来获得功率谱密度(PSD)估计值。这基本上是您引用的以下行所述的状态(高达比例因子,这对于大多数只需要比较不同频率分量的相对强度的应用而言并不重要):

正如我在另一个答案中提到的,在Matlab文档中也有描述,在进行FFT之前,通过将信号乘以a,并平均多个FFT结果的平方幅度,可以获得更好的PSD估计

注意:对于这个阶段,最好使用
Math.Atan2(虚的,实的)
(请参阅),它覆盖enter
[-pi,pi]
范围(而不是只覆盖
[-pi/2,pi/2]
)。

首先
Math.Sqrt(Math.Pow(实的,2)+Math.Pow(虚的,2))已实现为。或者你可以使用

除了SleuthEye所说的,我还对函数实现进行了一些度量

因为我不信任我实现的
Math.Pow(x,2)
函数:

private static double Square(double value)
{
    return value * value;
}
然而,事实证明C#已经优化了
Math.Pow(x,2)
,所以它足够快了。但无论如何:接下来我比较了三种实现

  • Square(testData[idx].Real)+Square(testData[idx].virtual)
  • Square(testData[idx].量级)
  • Square(Complex.Abs(testData[idx])
  • 我的(平均)结果是(对于10000000个复杂元素):

  • 45毫秒
  • 220毫秒
  • 211毫秒

  • 因此,似乎震级属性和Abs方法在内部使用平方根,这需要大量的周期来处理。但是对于PSD,您不需要它。

    我不确定如何使用窗口。我理解hann(
    0.50f*(1-(float)Math.Cos((2*Math.PI*n)/n-1))
    )的公式,但我必须在对我的波进行fft之前使用窗口?如果你只使用它已经对复数
    a+bi
    @GertKommer是的,如果你的波中有一大块n个样本,你可以用窗口函数乘以元素,然后对结果进行FFT。我有一个包含10ms数据的
    float[]buffer1
    。我只需要创建一个新的
    float[]buffer2
    ,它保存
    buffer1*窗口的值。因此,如果
    buffer1[0]==5
    ,并且窗口函数的输出是
    2
    ,则
    buffer2[0]=10
    ,因此我不使用标准复杂类,而是使用CsCore的复杂类。可悲的是,一个人没有这个量值和相位。至于你剩下的答案,我真的不知道该怎么办。有时候,将一种类型转换为另一种类型以使用更多功能是值得的;)但我想说的是:首先确定绝对值/大小(我看到:在CsCore中它被称为
    Complex.Value
    )-它有一个平方根-然后对结果进行平方运算是非常低效的。我很惭愧我没有看到
    Complex.Value
    。对于PSD,我确实需要平方大小,然后是复数。Value
    或我自己编写的函数比Sys numerics快?
    Math.Pow(a[i]。Real,2)+Math.Pow(a[i]。virtual,2)
    Math.Pow(a[i]。Value,2)
    快。自己编写一个比较测试是一个很好的练习:)好的,
    a[i].Value
    也有一个sqrt,而另一个没有,因此它更快并不令人惊讶。关于我自己比较不同方法的好建议。老实说,我没有这样做,因为我对实现的工作方式更感兴趣,在以后的阶段,我会担心性能并开始优化。但是提示仍然是thx:)根据,它有
    浮点实数
    浮点虚数
    ,而不是
    双精度
    。。。
    private static double Square(double value)
    {
        return value * value;
    }