---
title: Performing Fourier transforms on interleaved-complex data
framework: accelerate
role: article
role_heading: Article
path: accelerate/performing-fourier-transforms-on-interleaved-complex-data
---

# Performing Fourier transforms on interleaved-complex data

Optimize discrete Fourier transform (DFT) performance with the vDSP interleaved DFT routines.

## Overview

Overview In many cases, your code performs Fourier transforms on data that originates as interleaved-complex values. An interleaved-complex representation stores the real and imaginary parts of complex values together as collections of DSPComplex or DSPDoubleComplex structures. Many Fourier-related routines in vDSP accept complex values in a split-complex representation that stores real and imaginary parts as separate collections. For example, the following shows a collection of four complex values in a single interleaved collection: let interleaved = [DSPComplex(real: real₀, imag: imag₀),                    DSPComplex(real: real₁, imag: imag₁),                    DSPComplex(real: real₂, imag: imag₂),                    DSPComplex(real: real₃, imag: imag₃)] The following shows the same four complex values as two collections in a split representation: let reals = [real₀, real₁, real₂, real₃] let imaginaries = [imag₀, imag₁, imag₂, imag₃] vDSP routines accept split-complex values either as DSPSplitComplex structures or as two separate collections. Convert interleaved values to split-complex format Given an array signal that contains 32 interleaved-complex values, the following code performs a Fourier transform on the values. Use vDSP_ctoz to populate the split collections splitSignalReal and splitSignalImag with the interleaved values from signal: let complexValuesCount = 32

let signal: [DSPComplex] = [ ... ] // `signal.count` equals `complexValuesCount`.

var splitSignalReal = [Float](repeating: 0,                               count: complexValuesCount) var splitSignalImag = [Float](repeating: 0,                               count: complexValuesCount)

signal.withUnsafeBufferPointer { signalPtr in     splitSignalReal.withUnsafeMutableBufferPointer { signalRealPtr in         splitSignalImag.withUnsafeMutableBufferPointer { signalImagPtr in             var splitComplex = DSPSplitComplex(realp: signalRealPtr.baseAddress!,                                                imagp: signalImagPtr.baseAddress!)                          vDSP_ctoz(signalPtr.baseAddress!, 2,                       &splitComplex, 1,                       vDSP_Length(complexValuesCount))         }     } } Perform a Fourier transform on split data Use the vDSP function vDSP_DFT_zop_CreateSetup to create a setup object for complex-to-complex DFTs. The execute function, vDSP_DFT_Execute, automatically switches to a fast Fourier transform (FFT) when the specified count supports the FFT algorithm. var splitOutputReal = [Float](repeating: 0,                               count: complexValuesCount) var splitOutputImag = [Float](repeating: 0,                               count: complexValuesCount)

if let splitComplexSetup = vDSP_DFT_zop_CreateSetup(nil,                                                     vDSP_Length(complexValuesCount),                                                     .FORWARD) {          vDSP_DFT_Execute(splitComplexSetup,                      splitSignalReal, splitSignalImag,                      &splitOutputReal, &splitOutputImag)          vDSP_DFT_DestroySetup(splitComplexSetup) }

let splitComplexDominantFrequency = vDSP.indexOfMaximum(splitOutputReal)

print("Split-complex dominant frequency",       splitComplexDominantFrequency.0,       splitComplexDominantFrequency.1) On return,splitOutputReal and splitOutputImag contain the split format frequency-domain representation of the values in signal. Use indexOfMaximum(_:) to find the dominant frequency. Convert split-complex values to interleaved format Use vDSP_ztoc to convert the split result to the interleaved format. var dftOutputInterleaved = [DSPComplex](repeating: DSPComplex(),                                         count: complexValuesCount)

splitOutputReal.withUnsafeMutableBufferPointer { dftOutputRealPtr in     splitOutputImag.withUnsafeMutableBufferPointer { dftOutputImagPtr in         var splitComplex = DSPSplitComplex(realp: dftOutputRealPtr.baseAddress!,                                            imagp: dftOutputImagPtr.baseAddress!)                  vDSP_ztoc(&splitComplex, 1,                   &dftOutputInterleaved, 2,                   vDSP_Length(complexValuesCount))     } } On return, dftOutputInterleaved contains the DFT result in the interleaved format. Perform a Fourier transform directly on interleaved data vDSP provides routines for DFTs directly on interleaved data. Use these functions instead of using vDSP_ctoz and vDSP_ztoc to convert between interleaved and split formats. The following code performs the transform from the Performing Fourier transforms on interleaved-complex data section directly on the interleaved data: var interleavedOutput = [DSPComplex](repeating: DSPComplex(real: 0, imag: 0),                                      count: complexValuesCount)

if let interleavedSetup = vDSP_DFT_Interleaved_CreateSetup(nil,                                                            vDSP_Length(complexValuesCount),                                                            .FORWARD,                                                            .interleaved_ComplextoComplex) {     vDSP_DFT_Interleaved_Execute(interleavedSetup,                                  signal,                                  &interleavedOutput)          vDSP_DFT_Interleaved_DestroySetup(interleavedSetup) }

let interleavedDominantFrequency = interleavedOutput.enumerated().max {     a, b in a.element.real < b.element.real }

print("Interleaved dominant frequency",       interleavedDominantFrequency?.offset ?? -1,       interleavedDominantFrequency?.element.real ?? 0) On return, interleavedOutput contains the FFT result in the interleaved format.

## See Also

### Fourier and Cosine Transforms

- [Understanding data packing for Fourier transforms](accelerate/understanding-data-packing-for-fourier-transforms.md)
- [Finding the component frequencies in a composite sine wave](accelerate/finding-the-component-frequencies-in-a-composite-sine-wave.md)
- [Reducing spectral leakage with windowing](accelerate/reducing-spectral-leakage-with-windowing.md)
- [Signal extraction from noise](accelerate/signal-extraction-from-noise.md)
- [Performing Fourier Transforms on Multiple Signals](accelerate/performing-fourier-transforms-on-multiple-signals.md)
- [Halftone descreening with 2D fast Fourier transform](accelerate/halftone-descreening-with-2d-fast-fourier-transform.md)
- [Fast Fourier transforms](accelerate/fast-fourier-transforms.md)
- [Discrete Fourier transforms](accelerate/discrete-fourier-transforms.md)
- [Discrete Cosine transforms](accelerate/discrete-cosine-transforms.md)
