2
2
//
3
3
// This source file is part of the Swift Numerics open source project
4
4
//
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
6
6
// Licensed under Apache License v2.0 with Runtime Library Exception
7
7
//
8
8
// See https://swift.org/LICENSE.txt for license information
11
11
12
12
import RealModule
13
13
14
- /// A complex number represented by real and imaginary parts.
15
- ///
16
- /// TODO: introductory text on complex numbers
17
- ///
18
- /// Implementation notes:
19
- ///
20
- /// This type does not provide heterogeneous real/complex arithmetic,
21
- /// not even the natural vector-space operations like real * complex.
22
- /// There are two reasons for this choice: first, Swift broadly avoids
23
- /// mixed-type arithmetic when the operation can be adequately expressed
24
- /// by a conversion and homogeneous arithmetic. Second, with the current
25
- /// typechecker rules, it would lead to undesirable ambiguity in common
26
- /// expressions (see README.md for more details).
27
- ///
28
- /// Unlike C's `_Complex` and C++'s `std::complex<>` types, we do not
29
- /// attempt to make meaningful semantic distinctions between different
30
- /// representations of infinity or NaN. Any Complex value with at least
31
- /// one non-finite component is simply "non-finite". In as much as
32
- /// possible, we use the semantics of the point at infinity on the
33
- /// Riemann sphere for such values. This approach simplifies the number of
34
- /// edge cases that need to be considered for multiplication, division, and
35
- /// the elementary functions considerably.
36
- ///
37
- /// `.magnitude` does not return the Euclidean norm; it uses the "infinity
38
- /// norm" (`max(|real|,|imaginary|)`) instead. There are two reasons for this
39
- /// choice: first, it's simply faster to compute on most hardware. Second,
40
- /// there exist values for which the Euclidean norm cannot be represented
41
- /// (consider a number with `.real` and `.imaginary` both equal to
42
- /// `RealType.greatestFiniteMagnitude`; the Euclidean norm would be
43
- /// `.sqrt(2) * .greatestFiniteMagnitude`, which overflows). Using
44
- /// the infinity norm avoids this problem entirely without significant
45
- /// downsides. You can access the Euclidean norm using the `length`
46
- /// property.
14
+ // A [complex number](https://en.wikipedia.org/wiki/Complex_number).
15
+ // See Documentation.docc/Complex.md for more details.
47
16
@frozen
48
17
public struct Complex < RealType> where RealType: Real {
49
18
// A note on the `x` and `y` properties
@@ -53,11 +22,11 @@ public struct Complex<RealType> where RealType: Real {
53
22
// `.real` and `.imaginary` properties, which wrap this storage and
54
23
// fixup the semantics for non-finite values.
55
24
56
- /// The real component of the value.
25
+ /// The storage for the real component of the value.
57
26
@usableFromInline @inline ( __always)
58
27
internal var x : RealType
59
28
60
- /// The imaginary part of the value.
29
+ /// The storage for the imaginary part of the value.
61
30
@usableFromInline @inline ( __always)
62
31
internal var y : RealType
63
32
@@ -95,27 +64,40 @@ extension Complex {
95
64
set { y = newValue }
96
65
}
97
66
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
+
98
78
/// The raw representation of the real part of this value.
79
+ @available ( * , deprecated, message: " Use rawStorage " )
99
80
@_transparent
100
81
public var _rawX : RealType { x }
101
82
102
83
/// The raw representation of the imaginary part of this value.
84
+ @available ( * , deprecated, message: " Use rawStorage " )
103
85
@_transparent
104
86
public var _rawY : RealType { y }
105
87
}
106
88
107
89
extension Complex {
108
90
/// The imaginary unit.
109
91
///
110
- /// See also `. zero`, `. one` and `. infinity`.
92
+ /// See also `` zero`` , `` one`` and `` infinity` `.
111
93
@_transparent
112
94
public static var i : Complex {
113
95
Complex ( 0 , 1 )
114
96
}
115
97
116
98
/// The point at infinity.
117
99
///
118
- /// See also `. zero`, `. one` and `.i `.
100
+ /// See also `` zero`` , `` one`` and ``i` `.
119
101
@_transparent
120
102
public static var infinity : Complex {
121
103
Complex ( . infinity, 0 )
@@ -125,7 +107,7 @@ extension Complex {
125
107
///
126
108
/// A complex value is finite if neither component is an infinity or nan.
127
109
///
128
- /// See also `. isNormal`, `. isSubnormal` and `. isZero`.
110
+ /// See also `` isNormal`` , `` isSubnormal`` and `` isZero` `.
129
111
@_transparent
130
112
public var isFinite : Bool {
131
113
x. isFinite && y. isFinite
@@ -138,7 +120,7 @@ extension Complex {
138
120
/// one of the components is normal if its exponent allows a full-precision
139
121
/// representation.
140
122
///
141
- /// See also `. isFinite`, `. isSubnormal` and `. isZero`.
123
+ /// See also `` isFinite`` , `` isSubnormal`` and `` isZero` `.
142
124
@_transparent
143
125
public var isNormal : Bool {
144
126
isFinite && ( x. isNormal || y. isNormal)
@@ -150,7 +132,7 @@ extension Complex {
150
132
/// When the result of a computation is subnormal, underflow has occurred and
151
133
/// the result generally does not have full precision.
152
134
///
153
- /// See also `. isFinite`, `. isNormal` and `. isZero`.
135
+ /// See also `` isFinite`` , `` isNormal`` and `` isZero` `.
154
136
@_transparent
155
137
public var isSubnormal : Bool {
156
138
isFinite && !isNormal && !isZero
@@ -161,7 +143,7 @@ extension Complex {
161
143
/// A complex number is zero if *both* the real and imaginary components
162
144
/// are zero.
163
145
///
164
- /// See also `. isFinite`, `. isNormal` and `isSubnormal`.
146
+ /// See also `` isFinite`` , `` isNormal`` and `` isSubnormal` `.
165
147
@_transparent
166
148
public var isZero : Bool {
167
149
x == 0 && y == 0
@@ -200,7 +182,7 @@ extension Complex {
200
182
self . init ( real, 0 )
201
183
}
202
184
203
- /// The complex number with specified imaginary part and zero real part.
185
+ /// The complex number with zero real part and specified imaginary part.
204
186
///
205
187
/// Equivalent to `Complex(0, imaginary)`.
206
188
@inlinable
0 commit comments