 infix operator =~ { associativity none precedence 130 }
 infix operator !~ { associativity none precedence 130 }
 // != is auto-generated thanks to Equatable
-func == <T>(lhs:Complex<T>, rhs:Complex<T>) -> Bool {
+public func == <T>(lhs:Complex<T>, rhs:Complex<T>) -> Bool {
     return lhs.re == rhs.re && lhs.im == rhs.im
 }
-func == <T>(lhs:Complex<T>, rhs:T) -> Bool {
+public func == <T>(lhs:Complex<T>, rhs:T) -> Bool {
     return lhs.re == rhs && lhs.im == T(0)
 }
-func == <T>(lhs:T, rhs:Complex<T>) -> Bool {
+public func == <T>(lhs:T, rhs:Complex<T>) -> Bool {
     return rhs.re == lhs && rhs.im == T(0)
 }
 // +, +=
-prefix func + <T>(z:Complex<T>) -> Complex<T> {
+public prefix func + <T>(z:Complex<T>) -> Complex<T> {
     return z
 }
-func + <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
+public func + <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
     return Complex(lhs.re + rhs.re, lhs.im + rhs.im)
 }
-func + <T>(lhs:Complex<T>, rhs:T) -> Complex<T> {
+public func + <T>(lhs:Complex<T>, rhs:T) -> Complex<T> {
     return lhs + Complex(rhs, T(0))
 }
-func + <T>(lhs:T, rhs:Complex<T>) -> Complex<T> {
+public func + <T>(lhs:T, rhs:Complex<T>) -> Complex<T> {
     return Complex(lhs, T(0)) + rhs
 }
-func += <T>(inout lhs:Complex<T>, rhs:Complex<T>) {
+public func += <T>(inout lhs:Complex<T>, rhs:Complex<T>) {
     lhs.re += rhs.re ; lhs.im += rhs.im
 }
-func += <T>(inout lhs:Complex<T>, rhs:T) {
+public func += <T>(inout lhs:Complex<T>, rhs:T) {
     lhs.re += rhs
 }
 // -, -=
-prefix func - <T>(z:Complex<T>) -> Complex<T> {
+public prefix func - <T>(z:Complex<T>) -> Complex<T> {
     return Complex<T>(-z.re, -z.im)
 }
-func - <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
+public func - <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
     return Complex(lhs.re - rhs.re, lhs.im - rhs.im)
 }
-func - <T>(lhs:Complex<T>, rhs:T) -> Complex<T> {
+public func - <T>(lhs:Complex<T>, rhs:T) -> Complex<T> {
     return lhs - Complex(rhs, T(0))
 }
-func - <T>(lhs:T, rhs:Complex<T>) -> Complex<T> {
+public func - <T>(lhs:T, rhs:Complex<T>) -> Complex<T> {
     return Complex(lhs, T(0)) - rhs
 }
-func -= <T>(inout lhs:Complex<T>, rhs:Complex<T>) {
+public func -= <T>(inout lhs:Complex<T>, rhs:Complex<T>) {
     lhs.re -= rhs.re ; lhs.im -= rhs.im
 }
-func -= <T>(inout lhs:Complex<T>, rhs:T) {
+public func -= <T>(inout lhs:Complex<T>, rhs:T) {
     lhs.re -= rhs
 }
 // *, *=
-func * <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
+public func * <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
     return Complex(
         lhs.re * rhs.re - lhs.im * rhs.im,
         lhs.re * rhs.im + lhs.im * rhs.re
     )
 }
-func * <T>(lhs:Complex<T>, rhs:T) -> Complex<T> {
+public func * <T>(lhs:Complex<T>, rhs:T) -> Complex<T> {
     return Complex(lhs.re * rhs, lhs.im * rhs)
 }
-func * <T>(lhs:T, rhs:Complex<T>) -> Complex<T> {
+public func * <T>(lhs:T, rhs:Complex<T>) -> Complex<T> {
     return Complex(lhs * rhs.re, lhs * rhs.im)
 }
-func *= <T>(inout lhs:Complex<T>, rhs:Complex<T>) {
+public func *= <T>(inout lhs:Complex<T>, rhs:Complex<T>) {
     lhs = lhs * rhs
 }
-func *= <T>(inout lhs:Complex<T>, rhs:T) {
+public func *= <T>(inout lhs:Complex<T>, rhs:T) {
     lhs = lhs * rhs
 }
 // /, /=
 //
 // cf. https://github.com/dankogai/swift-complex/issues/3
 //
-func / <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
+public func / <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
     if abs(rhs.re) >= abs(rhs.im) {
         let r = rhs.im / rhs.re
         let d = rhs.re + rhs.im * r

    }
}
// cos(z)
func cos<T>(z:Complex<T>) -> Complex<T> {
    // return (exp(i*z) + exp(-i*z)) / 2
    return (exp(z.i) + exp(-z.i)) / T(2)
}
// sin(z)
func sin<T>(z:Complex<T>) -> Complex<T> {
    // return (exp(i*z) - exp(-i*z)) / (2*i)
    return -(exp(z.i) - exp(-z.i)).i / T(2)
}
// tan(z)
func tan<T>(z:Complex<T>) -> Complex<T> {
    // return sin(z) / cos(z)
    let ezi = exp(z.i), e_zi = exp(-z.i)
    return (ezi - e_zi) / (ezi + e_zi).i
}
// atan(z)
func atan<T>(z:Complex<T>) -> Complex<T> {
    let l0 = log(T(1) - z.i), l1 = log(T(1) + z.i)
    return (l0 - l1).i / T(2)
}
func atan<T:RealType>(r:T) -> T { return atan(Complex(r, T(0))).re }
// asin(z)
func asin<T>(z:Complex<T>) -> Complex<T> {
    return -log(z.i + sqrt(T(1) - z*z)).i
}
// acos(z)
func acos<T>(z:Complex<T>) -> Complex<T> {
    return log(z - sqrt(T(1) - z*z).i).i
}
// sinh(z)
func sinh<T>(z:Complex<T>) -> Complex<T> {
    return (exp(z) - exp(-z)) / T(2)
}
// cosh(z)
func cosh<T>(z:Complex<T>) -> Complex<T> {
    return (exp(z) + exp(-z)) / T(2)
}
// tanh(z)
func tanh<T>(z:Complex<T>) -> Complex<T> {
    let ez = exp(z), e_z = exp(-z)
    return (ez - e_z) / (ez + e_z)
}
// asinh(z)
func asinh<T>(z:Complex<T>) -> Complex<T> {
    return log(z + sqrt(z*z + T(1)))
}
// acosh(z)
func acosh<T>(z:Complex<T>) -> Complex<T> {
    return log(z + sqrt(z*z - T(1)))
}
// atanh(z)
func atanh<T>(z:Complex<T>) -> Complex<T> {
    let t0 = T(1) + z
    let t1 = T(1) - z
    return log(t0 / t1) / T(2)
}
// for the compatibility's sake w/ C++11
func abs<T>(z:Complex<T>) -> T { return z.abs }
func arg<T>(z:Complex<T>) -> T { return z.arg }
func real<T>(z:Complex<T>) -> T { return z.real }
func imag<T>(z:Complex<T>) -> T { return z.imag }
func norm<T>(z:Complex<T>) -> T { return z.norm }
func conj<T>(z:Complex<T>) -> Complex<T> { return z.conj }
func proj<T>(z:Complex<T>) -> Complex<T> { return z.proj }
//
// approximate comparisons
//
func =~ <T:RealType>(lhs:T, rhs:T) -> Bool {
    if lhs == rhs { return true }
    let t = (rhs - lhs) / rhs
    return abs(t) <= T(2) * T.epsilon
}
func =~ <T>(lhs:Complex<T>, rhs:Complex<T>) -> Bool {
    if lhs == rhs { return true }
    return lhs.abs =~ rhs.abs
}
func =~ <T>(lhs:Complex<T>, rhs:T) -> Bool {
    return abs(lhs) =~ abs(rhs)
}
func =~ <T>(lhs:T, rhs:Complex<T>) -> Bool {
    return abs(lhs) =~ abs(rhs)
}
func !~ <T:RealType>(lhs:T, rhs:T) -> Bool {
    return !(lhs =~ rhs)
}
func !~ <T>(lhs:Complex<T>, rhs:Complex<T>) -> Bool {
    return !(lhs =~ rhs)
}
func !~ <T>(lhs:Complex<T>, rhs:T) -> Bool {
    return !(lhs =~ rhs)
}
func !~ <T>(lhs:T, rhs:Complex<T>) -> Bool {
    return !(lhs =~ rhs)
}
// typealiases
typealias Complex64 = Complex<Double>
typealias Complex32 = Complex<Float>

        
    }
}
public func / <T>(lhs:Complex<T>, rhs:T) -> Complex<T> {
    return Complex(lhs.re / rhs, lhs.im / rhs)
}
public func / <T>(lhs:T, rhs:Complex<T>) -> Complex<T> {
    return Complex(lhs, T(0)) / rhs
}
public func /= <T>(inout lhs:Complex<T>, rhs:Complex<T>) {
    lhs = lhs / rhs
}
public func /= <T>(inout lhs:Complex<T>, rhs:T) {
    lhs = lhs / rhs
}
// exp(z)
public func exp<T>(z:Complex<T>) -> Complex<T> {
    let abs = T.exp(z.re)
    let arg = z.im
    return Complex(abs * T.cos(arg), abs * T.sin(arg))
}
// log(z)
public func log<T>(z:Complex<T>) -> Complex<T> {
    return Complex(T.log(z.abs), z.arg)
}
// log10(z) -- just because C++ has it
public func log10<T>(z:Complex<T>) -> Complex<T> { return log(z) / T.log(T(10)) }
public func log10<T:RealType>(r:T) -> T { return T.log(r) / T.log(T(10)) }
// pow(b, x)
public func pow<T>(lhs:Complex<T>, _ rhs:Complex<T>) -> Complex<T> {
    if lhs == T(0) { return Complex(T(1), T(0)) } // 0 ** 0 == 1
    let z = log(lhs) * rhs
    return exp(z)
}
public func pow<T>(lhs:Complex<T>, _ rhs:T) -> Complex<T> {
    return pow(lhs, Complex(rhs, T(0)))
}
public func pow<T>(lhs:T, _ rhs:Complex<T>) -> Complex<T> {
    return pow(Complex(lhs, T(0)), rhs)
}
// **, **=
public func **<T:RealType>(lhs:T, rhs:T) -> T {
    return T.pow(lhs, rhs)
}
public func ** <T>(lhs:Complex<T>, rhs:Complex<T>) -> Complex<T> {
    return pow(lhs, rhs)
}
public func ** <T>(lhs:T, rhs:Complex<T>) -> Complex<T> {
    return pow(lhs, rhs)
}
public func ** <T>(lhs:Complex<T>, rhs:T) -> Complex<T> {
    return pow(lhs, rhs)
}
public func **= <T:RealType>(inout lhs:T, rhs:T) {
    lhs = T.pow(lhs, rhs)
}
public func **= <T>(inout lhs:Complex<T>, rhs:Complex<T>) {
    lhs = pow(lhs, rhs)
}
public func **= <T>(inout lhs:Complex<T>, rhs:T) {
    lhs = pow(lhs, rhs)
}
// sqrt(z)
public func sqrt<T>(z:Complex<T>) -> Complex<T> {
    // return z ** 0.5
    let d = T.hypot(z.re, z.im)
    let r = T.sqrt((z.re + d)/T(2))
