<commit_before>//
//  Complex.swift
//  LinearAlgebra
//
//  Created by <NAME> on 06.07.16.
//  Copyright © 2016 pauljohanneskraft. All rights reserved.
//

import Foundation

public typealias C = Complex<Double>

// makes it possible to write something like the following:
//
// var myComplex = 2 + 3*i
//

public struct Complex < Number : BasicArithmetic > : BasicArithmetic {
    public var real      : Number
    public var imaginary : Number
    
    public static var i : C { return C(real: 0, imaginary: 1) }

    public var conjugate : Complex<Number> {
        var this = self
        this.imaginary = -this.imaginary
        return this
    }
    
    public var hashValue: Int {
        if(MemoryLayout<Number>.size == MemoryLayout<Int>.size) {
            return unsafeBitCast(real, to: Int.self) &+ unsafeBitCast(imaginary, to: Int.self)
        } else { return -real.hashValue &+ imaginary.hashValue }
    }
    
    public init(polarForm: (coefficient: Double, exponent: Double)) {
        self.real      = Number(floatLiteral: polarForm.coefficient * cos(polarForm.exponent))
        self.imaginary = Number(floatLiteral: polarForm.coefficient * sin(polarForm.exponent))
    }
    
    public init(floatLiteral   v: Double) { self.init(Number(floatLiteral:   v)) }
    public init(integerLiteral v: Int)    { self.init(Number(integerLiteral: v)) }
    
    // init(_ v: Double) { self.init(Number(v)) }
    // init(_ v: Int)    { self.init(Number(v)) }
    
    public init(_ v: Number) {
        self.real      = v
        self.imaginary = 0
    }
    public init(real: Number, imaginary: Number) {
        self.real      = real
        self.imaginary = imaginary
    }
}

extension Complex where Number : Numeric {
    public var integer: Int? {
        if imaginary != 0 { return nil }
        return real.integer
    }
    
    public var abs : Complex<Number> {
        return Complex((real*real + imaginary*imaginary).sqrt)
    }
    
    public var double: Double? {
        if imaginary != 0 { return nil }
        return real.double
    }

}

extension Complex where Number : Randomizable {
    public static var random : Complex<Number> {
        return Complex(Number.random)
    }
}

extension Complex where Number : AdvancedNumeric {
    public var sqrt : Complex<Number>? {
        var this = self<commit_msg>+ Complex also having integer and double as non-optional properties<commit_after>//
//  Complex.swift
//  LinearAlgebra
//
//  Created by <NAME> on 06.07.16.
//  Copyright © 2016 pauljohanneskraft. All rights reserved.
//

import Foundation

public typealias C = Complex<Double>

// makes it possible to write something like the following:
//
// var myComplex = 2 + 3*i
//

public struct Complex < Number : BasicArithmetic > : BasicArithmetic {
    public var real      : Number
    public var imaginary : Number
    
    public static var i : C { return C(real: 0, imaginary: 1) }

    public var conjugate : Complex<Number> {
        var this = self
        this.imaginary = -this.imaginary
        return this
    }
    
    public var hashValue: Int {
        if(MemoryLayout<Number>.size == MemoryLayout<Int>.size) {
            return unsafeBitCast(real, to: Int.self) &+ unsafeBitCast(imaginary, to: Int.self)
        } else { return -real.hashValue &+ imaginary.hashValue }
    }
    
    public init(polarForm: (coefficient: Double, exponent: Double)) {
        self.real      = Number(floatLiteral: polarForm.coefficient * cos(polarForm.exponent))
        self.imaginary = Number(floatLiteral: polarForm.coefficient * sin(polarForm.exponent))
    }
    
    public init(floatLiteral   v: Double) { self.init(Number(floatLiteral:   v)) }
    public init(integerLiteral v: Int)    { self.init(Number(integerLiteral: v)) }
    
    // init(_ v: Double) { self.init(Number(v)) }
    // init(_ v: Int)    { self.init(Number(v)) }
    
    public init(_ v: Number) {
        self.real      = v
        self.imaginary = 0
    }
    public init(real: Number, imaginary: Number) {
        self.real      = real
        self.imaginary = imaginary
    }
}

extension Complex where Number : Numeric {
    public var integer: Int {
		assert(imaginary != 0, "imaginary part != 0")
        return real.integer
    }
    
    public var abs : Complex<Number> {
        return Complex((real*real + imaginary*imaginary).sqrt)
    }
    
    public var double: Double {
		assert(imaginary != 0, "imaginary part != 0")
        return real.double
    }

}

extension Complex where Number : Randomizable {
    public static var random : Complex<Number> {
        return Complex(Number.random)
    }
}

extension Complex where Number : AdvancedNumeric {
    public var sqrt : Complex<Number> {
        var this = self
{'fraction_non_alphanumeric': 0.10731604469744888, 'fraction_numerical': 0.007590132827324478, 'mean_word_length': 2.460247994164843, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7104832', 'n_tokens_mistral': 1430, 'n_tokens_neox': 1374, 'n_words': 398}