Complex Numbers

That's not quite what I'm suggesting. I'm advocating for (essentially) two additional types on top of the existing Double type: an Imaginary type and a Complex type. (I'm roughly thinking of Double and Real as being the same thing for the moment.) The idea here is that Real and Imaginary are both backed by a single floating point value, while the Complex type is a structure containing a Real and Imaginary value.

The advantage to having an Imaginary type separate from Complex type is two-fold:

  1. fewer floating point operations, and
  2. smaller memory footprint.

This may also have another advantage. There are two-standard data structures for storing complex types that mimic DSPComplex (as mentioned by Howard Lovatt) and DSPSplitComplex. In the first case, the real part and imaginary part are interleaved, with a stride of 1 separating them. In the second case, the there is a pointer to the real array and a pointer the imaginary array. So now, if you want to mimic the equivalent of DSPComplex and DSPSplitComplex with Swift, you'd do

let interleavedArray : Array<Complex> = [Complex(1.0,1.0),Complex(2.0,1.0)]
let realArray : Array<Real> = [Real(1.0),Real(2.0)]
let imagArray : Array<Imaginary> = [Imaginary(1.0),Imaginary(1.0)]

So this has the advantage of reproducing both standard data structures, and not losing any information about the underlying type, by which I mean the array of Imaginary numbers has the right data structure for use in these algorithms, but also behaves correctly mathematically. I don't think you can achieve this if you only have a Complex type.

My earlier idea was that the squareRoot function on Real numbers would then only return a Real or an Imaginary---never a Complex. Thus, any current check to .isNaN can simply be replaced by .isImaginary.

I don't understand the implications of this---would this make things worse?