0

I am trying to write FFT code in swift to match Matlab FFT code.

So far I notice that when "input.count" is equal to 2^n (where n = 1, 2, 3, ...), the results match perfectly well.

However, for arbitrary sample size ("input.count" is NOT equal to 2^n), Swift and Matlab results do not match.

I am pasting the code below with 2 simple examples.

 import Accelerate

 public func fft(_ input: [Double]) -> ([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))

 return (real, imaginary)
 }

// 2^N samples (WORKS; Matlab Output Same)
let (rl, img) = fft([1, 2, 3, 4, 5, 6, 7, 8])
print("REAL:", rl)
print(" ")
print("IMAG:", img)
print(" ")
// Swift Real: [36.0, -4.0, -4.0, -4.0, -4.0, -4.0, -4.0, -4.0]

// Matlab Real: [36, -4, -4, -4, -4, -4, -4, -4]

// Swift Imag: [0.0, 9.6568542494923797, 4.0, 1.6568542494923806, 0.0, -1.6568542494923806, -4.0, -9.6568542494923797]

// Matlab Imag: [0, 9.65685424949238, 4, 1.65685424949238, 0, -1.65685424949238, -4, -9.65685424949238]


// N samples (DOES NOT WORK; Matlab Output Different)
let (rl2, img2) = fft([1, 2, 3, 4, 5, 6, 7, 8, 9])
print("REAL:", rl2)
print(" ")
print("IMAG:", img2)
print(" ")
// Swift Real: [36.0, -4.0, -4.0, -4.0, -4.0, -4.0, -4.0, -4.0, 9.0]

// Matlab Real: [45, -4.5, -4.5, -4.5, -4.5, -4.5, -4.5, -4.5, -4.5]

// Swift Imag: [0.0, 9.6568542494923797, 4.0, 1.6568542494923806, 0.0, -1.6568542494923806, -4.0, -9.6568542494923797, 0.0]

// Matlab Imag: [0, 12.3636483875458, 5.36289116667395, 2.59807621135332, 0.793471413188091, -0.793471413188091, -2.59807621135332, -5.36289116667395, -12.3636483875458]
Pat
  • 325
  • 1
  • 12
  • 2
    As pointed out in the comments and answers to the "duplicate", FFT from the Accelerate framework can handle only certain sample sizes (powers of 2, times 1, 3, 5, or 15). – Martin R Jan 29 '17 at 20:59
  • Thanks Martin. So it seems there is no solution for now for arbitrary data size ! – Pat Jan 29 '17 at 21:20
  • For an FFT size that does not have small factors, you can still use the Accelerate framework to do a matrix multiply by a DFT basis vector matrix. – hotpaw2 Jan 30 '17 at 18:55
  • Thanks hotpaw ! Actually I have already written a brute force DFT algorithm now that works well (results same as Matlab for arbitrary sample size) on small sample sizes. But say for large sample sizes (> 15,000), it takes about 20 s to compute which is too much. Perhaps Matrix multiplication (as you suggest) might be the way to go. I am creating another post seeking help on how to go to Matrix form DFT (I don't know much about it) or maybe speed up my brute force algorithm. – Pat Jan 31 '17 at 03:09

0 Answers0