Complex.swift

import Foundation

struct Complex: CustomStringConvertible {
    let real: Double
    let imag: Double

    typealias IntegerLiteralType = Double

    var conj: Complex {
        return Complex(real: self.real, imag: -1.0 * self.imag)
    }

    var abs: Double {
        return sqrt( self.real * self.real + self.imag * self.imag )
    }

    var amplitude: Double {
        return self.abs
    }

    var magnitude: Double {
        return self.abs
    }

    var phase: Double {
        return atan2( self.imag, self.real )
    }

    var description: String {
        return "\(self.real) + 1i * \(self.imag)"
    }

    init(real: Double, imag: Double) {
        self.real = real
        self.imag = imag
    }

    init(integerLiteral: IntegerLiteralType) {
        self.real = integerLiteral
        self.imag = 0
    }

    init?<T: BinaryInteger>(exactly source: T) {
        if let real = Int(exactly: source), let realDouble = Double(exactly: real) {
            self.real = realDouble
            self.imag = 0
        } else {
            return nil
        }
    }

}

// Numeric protocol
extension Complex: Numeric {
    static func +(left: Complex, right: Complex) -> Complex {
        return Complex(real: left.real + right.real, imag: left.imag + right.imag)
    }

    static func -(left: Complex, right: Complex) -> Complex {
        return Complex(real: left.real - right.real, imag: left.imag - right.imag)
    }

    static func *(left: Complex, right: Complex) -> Complex {
        let real = left.real * right.real - left.imag * right.imag
        let imag = left.real * right.imag + left.imag * right.real
        return Complex(real: real, imag: imag)
    }

    static func /(left: Complex, right: Complex) -> Complex {
        let numerator = left * right.conj
        let denominator = right.abs
        return Complex(real: numerator.real / denominator, imag: numerator.imag / denominator)
    }

    static func +=(left: inout Complex, right: Complex) {
        left = left + right
    }

    static func -=(left: inout Complex, right: Complex) {
        left = left - right
    }

    static func *=(left: inout Complex, right: Complex) {
        left = left * right
    }

    prefix static func + (x: Complex) -> Complex {
        return x
    }

    prefix static func - (x: Complex) -> Complex {
        return Complex(real: -x.real, imag: -x.imag)
    }

}

// Methods conforming Equatable
extension Complex {
    static func == (lhs: Complex, rhs: Complex) -> Bool {
        return (lhs.real == rhs.real) && (lhs.imag == rhs.imag)
    }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s