1- //===--- Arithmetic .swift ------------ -------------------------*- swift -*-===//
1+ //===--- Complex+AlgebraicField .swift -------------------------*- swift -*-===//
22//
33// This source file is part of the Swift Numerics open source project
44//
5- // Copyright (c) 2019 Apple Inc. and the Swift Numerics project authors
5+ // Copyright (c) 2019-2021 Apple Inc. and the Swift Numerics project authors
66// Licensed under Apache License v2.0 with Runtime Library Exception
77//
88// See https://swift.org/LICENSE.txt for license information
1111
1212import RealModule
1313
14- // MARK: - Additive structure
15- extension Complex : AdditiveArithmetic {
16- @_transparent
17- public static func + ( z: Complex , w: Complex ) -> Complex {
18- return Complex ( z. x + w. x, z. y + w. y)
19- }
20-
21- @_transparent
22- public static func - ( z: Complex , w: Complex ) -> Complex {
23- return Complex ( z. x - w. x, z. y - w. y)
24- }
25-
26- @_transparent
27- public static func += ( z: inout Complex , w: Complex ) {
28- z = z + w
29- }
30-
14+ extension Complex : AlgebraicField {
15+ /// The multiplicative identity `1 + 0i`.
3116 @_transparent
32- public static func -= ( z: inout Complex , w: Complex ) {
33- z = z - w
34- }
35- }
36-
37- // MARK: - Vector space structure
38- //
39- // Policy: deliberately not using the * and / operators for these at the
40- // moment, because then there's an ambiguity in expressions like 2*z; is
41- // that Complex(2) * z or is it RealType(2) * z? This is especially
42- // problematic in type inference: suppose we have:
43- //
44- // let a: RealType = 1
45- // let b = 2*a
46- //
47- // what is the type of b? If we don't have a type context, it's ambiguous.
48- // If we have a Complex type context, then b will be inferred to have type
49- // Complex! Obviously, that doesn't help anyone.
50- //
51- // TODO: figure out if there's some way to avoid these surprising results
52- // and turn these into operators if/when we have it.
53- // (https://github.com/apple/swift-numerics/issues/12)
54- extension Complex {
55- /// `self` scaled by `a`.
56- @usableFromInline @_transparent
57- internal func multiplied( by a: RealType ) -> Complex {
58- // This can be viewed in two different ways, which are mathematically
59- // equivalent: either we are computing `self * Complex(a)` (i.e.
60- // converting `a` to be a complex value, and then using the complex
61- // multiplication) or we are using the scalar product of the vector
62- // space structure: `Complex(a*real, a*imaginary)`.
63- //
64- // Although these two interpretations are _mathematically_ equivalent,
65- // they will generate different representations of the point at
66- // infinity in general. For example, suppose `self` is represented by
67- // `(infinity, 0)`. Then `self * Complex(1)` would evaluate as
68- // `(1*infinity - 0*0, 0*infinity + 1*0) = (infinity, nan)`, but
69- // the vector space interpretation produces `(infinity, 0)`. This does
70- // not matter much, because these are two representations of the same
71- // semantic value, but note that one requires four multiplies and two
72- // additions, while the one we use requires only two real multiplications.
73- Complex ( x*a, y*a)
17+ public static var one : Complex {
18+ Complex ( 1 , 0 )
7419 }
7520
76- /// `self` unscaled by `a`.
77- @usableFromInline @_transparent
78- internal func divided( by a: RealType ) -> Complex {
79- // See implementation notes for `multiplied` above.
80- Complex ( x/ a, y/ a)
81- }
82- }
83-
84- // MARK: - Multiplicative structure
85- extension Complex : AlgebraicField {
21+ /// The [complex conjugate][conj] of this value.
22+ ///
23+ /// [conj]: https://en.wikipedia.org/wiki/Complex_conjugate
8624 @_transparent
87- public static func * ( z : Complex , w : Complex ) -> Complex {
88- return Complex ( z . x*w . x - z . y*w . y , z . x*w . y + z . y*w . x )
25+ public var conjugate : Complex {
26+ Complex ( x , - y )
8927 }
9028
9129 @_transparent
@@ -98,11 +36,6 @@ extension Complex: AlgebraicField {
9836 return z * ( w. conjugate. divided ( by: lenSq) )
9937 }
10038
101- @_transparent
102- public static func *= ( z: inout Complex , w: Complex ) {
103- z = z * w
104- }
105-
10639 @_transparent
10740 public static func /= ( z: inout Complex , w: Complex ) {
10841 z = z / w
0 commit comments