22//
33// This source file is part of the Swift Numerics open source project
44//
5- // Copyright (c) 2019 - 2021 Apple Inc. and the Swift Numerics project authors
5+ // Copyright (c) 2019-2025 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- /// A complex number represented by real and imaginary parts.
15- ///
16- /// Implementation notes:
17- ///
18- /// This type does not provide heterogeneous real/complex arithmetic,
19- /// not even the natural vector-space operations like real * complex.
20- /// There are two reasons for this choice: first, Swift broadly avoids
21- /// mixed-type arithmetic when the operation can be adequately expressed
22- /// by a conversion and homogeneous arithmetic. Second, with the current
23- /// typechecker rules, it would lead to undesirable ambiguity in common
24- /// expressions (see README.md for more details).
25- ///
26- /// Unlike C's `_Complex` and C++'s `std::complex<>` types, we do not
27- /// attempt to make meaningful semantic distinctions between different
28- /// representations of infinity or NaN. Any Complex value with at least
29- /// one non-finite component is simply "non-finite". In as much as
30- /// possible, we use the semantics of the point at infinity on the
31- /// Riemann sphere for such values. This approach simplifies the number of
32- /// edge cases that need to be considered for multiplication, division, and
33- /// the elementary functions considerably.
34- ///
35- /// `.magnitude` does not return the Euclidean norm; it uses the "infinity
36- /// norm" (`max(|real|,|imaginary|)`) instead. There are two reasons for this
37- /// choice: first, it's simply faster to compute on most hardware. Second,
38- /// there exist values for which the Euclidean norm cannot be represented
39- /// (consider a number with `.real` and `.imaginary` both equal to
40- /// `RealType.greatestFiniteMagnitude`; the Euclidean norm would be
41- /// `.sqrt(2) * .greatestFiniteMagnitude`, which overflows). Using
42- /// the infinity norm avoids this problem entirely without significant
43- /// downsides. You can access the Euclidean norm using the `length`
44- /// property.
14+ // A [complex number](https://en.wikipedia.org/wiki/Complex_number).
15+ // See Documentation.docc/Complex.md for more details.
4516@frozen
4617public struct Complex < RealType> where RealType: Real {
4718 // A note on the `x` and `y` properties
@@ -51,11 +22,11 @@ public struct Complex<RealType> where RealType: Real {
5122 // `.real` and `.imaginary` properties, which wrap this storage and
5223 // fixup the semantics for non-finite values.
5324
54- /// The real component of the value.
25+ /// The storage for the real component of the value.
5526 @usableFromInline @inline ( __always)
5627 internal var x : RealType
5728
58- /// The imaginary part of the value.
29+ /// The storage for the imaginary part of the value.
5930 @usableFromInline @inline ( __always)
6031 internal var y : RealType
6132
@@ -93,27 +64,40 @@ extension Complex {
9364 set { y = newValue }
9465 }
9566
67+ /// The raw representation of the value.
68+ ///
69+ /// Use this when you need the underlying RealType values,
70+ /// without fixup for NaN or infinity.
71+ public var rawStorage : ( x: RealType , y: RealType ) {
72+ @_transparent
73+ get { ( x, y) }
74+ @_transparent
75+ set { ( x, y) = newValue }
76+ }
77+
9678 /// The raw representation of the real part of this value.
79+ @available ( * , deprecated, message: " Use rawStorage " )
9780 @_transparent
9881 public var _rawX : RealType { x }
9982
10083 /// The raw representation of the imaginary part of this value.
84+ @available ( * , deprecated, message: " Use rawStorage " )
10185 @_transparent
10286 public var _rawY : RealType { y }
10387}
10488
10589extension Complex {
10690 /// The imaginary unit.
10791 ///
108- /// See also `. zero`, `. one` and `. infinity`.
92+ /// See also `` zero`` , `` one`` and `` infinity` `.
10993 @_transparent
11094 public static var i : Complex {
11195 Complex ( 0 , 1 )
11296 }
11397
11498 /// The point at infinity.
11599 ///
116- /// See also `. zero`, `. one` and `.i `.
100+ /// See also `` zero`` , `` one`` and ``i` `.
117101 @_transparent
118102 public static var infinity : Complex {
119103 Complex ( . infinity, 0 )
@@ -123,7 +107,7 @@ extension Complex {
123107 ///
124108 /// A complex value is finite if neither component is an infinity or nan.
125109 ///
126- /// See also `. isNormal`, `. isSubnormal` and `. isZero`.
110+ /// See also `` isNormal`` , `` isSubnormal`` and `` isZero` `.
127111 @_transparent
128112 public var isFinite : Bool {
129113 x. isFinite && y. isFinite
@@ -136,7 +120,7 @@ extension Complex {
136120 /// one of the components is normal if its exponent allows a full-precision
137121 /// representation.
138122 ///
139- /// See also `. isFinite`, `. isSubnormal` and `. isZero`.
123+ /// See also `` isFinite`` , `` isSubnormal`` and `` isZero` `.
140124 @_transparent
141125 public var isNormal : Bool {
142126 isFinite && ( x. isNormal || y. isNormal)
@@ -148,7 +132,7 @@ extension Complex {
148132 /// When the result of a computation is subnormal, underflow has occurred and
149133 /// the result generally does not have full precision.
150134 ///
151- /// See also `. isFinite`, `. isNormal` and `. isZero`.
135+ /// See also `` isFinite`` , `` isNormal`` and `` isZero` `.
152136 @_transparent
153137 public var isSubnormal : Bool {
154138 isFinite && !isNormal && !isZero
@@ -159,7 +143,7 @@ extension Complex {
159143 /// A complex number is zero if *both* the real and imaginary components
160144 /// are zero.
161145 ///
162- /// See also `. isFinite`, `. isNormal` and `isSubnormal`.
146+ /// See also `` isFinite`` , `` isNormal`` and `` isSubnormal` `.
163147 @_transparent
164148 public var isZero : Bool {
165149 x == 0 && y == 0
@@ -198,7 +182,7 @@ extension Complex {
198182 self . init ( real, 0 )
199183 }
200184
201- /// The complex number with specified imaginary part and zero real part.
185+ /// The complex number with zero real part and specified imaginary part.
202186 ///
203187 /// Equivalent to `Complex(0, imaginary)`.
204188 @inlinable
0 commit comments