Python Accelerate和NumPy为FFT生成不同的结果

Python Accelerate和NumPy为FFT生成不同的结果,python,swift,numpy,fft,coreml,Python,Swift,Numpy,Fft,Coreml,我正在为CoreML开发一个功能工程管道,我需要对我的数据执行FFT。问题是加速框架的结果和NumPy FFT的结果不同 斯威夫特: public func fft(_ input: [Double]) -> [Double] { var real = [Double](input) var imaginary = [Double](repeating: 0.0, count: input.count) var splitComplex = DSPDoubleSpl

我正在为CoreML开发一个功能工程管道,我需要对我的数据执行FFT。问题是加速框架的结果和NumPy FFT的结果不同

斯威夫特:

public func fft(_ input: [Double]) -> [Double] {
    var real = [Double](input)
    var imaginary = [Double](repeating: 0.0, count: input.count)
    var splitComplex = DSPDoubleSplitComplex(realp: &real, imagp: &imaginary)

    let length = vDSP_Length(floor(log2(Float(input.count))))
    let radix = FFTRadix(kFFTRadix2)
    let weights = vDSP_create_fftsetupD(length, radix)
    vDSP_fft_zipD(weights!, &splitComplex, 1, length, FFTDirection(FFT_FORWARD))

    var magnitudes = [Double](repeating: 0.0, count: input.count)
    vDSP_zvmagsD(&splitComplex, 1, &magnitudes, 1, vDSP_Length(input.count))

    var normalizedMagnitudes = [Double](repeating: 0.0, count: input.count)
    vDSP_vsmulD(sqrt(magnitudes), 1, [2.0 / Double(input.count)], &normalizedMagnitudes, 1, vDSP_Length(input.count))

    vDSP_destroy_fftsetupD(weights)

    return normalizedMagnitudes
}
Python:

def fft(series: pd.Series):
    f = np.fft.fft(series)
    fa = np.abs(f)
    return pd.Series(fa)
我对每种方法使用相同的100个值

我想这与规范化部分有关,但我甚至不确定两个数组是否包含相同的内容,如:

  • 索引0:零频率项
  • 指数1-50:正震级
  • 指数50-99:负震级
我只对正数感兴趣

编辑:

以下是NumPy图:

这是加速图:


我希望有人能帮忙:)

如果accelerate返回数量级的sqrt,结果与
python
相同

  public func fft(_ input: [Double]) -> [Double] {
   ....
   return  magnitudes.map{sqrt($0)}
   }
你可以找出哪一个不是现在。如果您想使用accelerate, 可以使用以下选项:

    public func fft(_ input: [Double]) -> [Double] {
   ....

    var normalizedMagnitudes = [Double](repeating: 0.0, count: input.count)
    var count : Int32 = Int32(input.count)
    vvsqrt(   &normalizedMagnitudes, &magnitudes, &count )



     vDSP_destroy_fftsetupD(weights)

     return normalizedMagnitudes}
有两个问题:

  • 正如所指出的,使用Accelerate framework的FFT的实现包括一个归一化步骤,该步骤取幅值的平方根并乘以标量
    2/N
    。使用NumPy的实现没有

  • NumPy的FFT支持任意长度的输入,产生的频率单元与您期望的一样(索引0处为零频率,索引1-50处为正频率,索引51-99处为负频率)。另一方面,加速框架中的FFT长度需要为2的幂。相应地,该代码示例计算前64个输入值的FFT。这将零频率置于指数0,正频率置于指数1-32,负频率置于指数33-63。剩下的索引(64-99)只是未触及的输入的剩余部分


但如何解释加速曲线图中60处的峰值?不可能是sqrt。。。我似乎是某种线性缩放,因为比例大约是2。那么你仍然错过了numpy中的线性缩放步骤