Python Accelerate和NumPy为FFT生成不同的结果
我正在为CoreML开发一个功能工程管道,我需要对我的数据执行FFT。问题是加速框架的结果和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
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:负震级
我希望有人能帮忙:)如果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的实现包括一个归一化步骤,该步骤取幅值的平方根并乘以标量
。使用NumPy的实现没有2/N
- NumPy的FFT支持任意长度的输入,产生的频率单元与您期望的一样(索引0处为零频率,索引1-50处为正频率,索引51-99处为负频率)。另一方面,加速框架中的FFT长度需要为2的幂。相应地,该代码示例计算前64个输入值的FFT。这将零频率置于指数0,正频率置于指数1-32,负频率置于指数33-63。剩下的索引(64-99)只是未触及的输入的剩余部分