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
- /// 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.
45
16
@frozen
46
17
public struct Complex < RealType> where RealType: Real {
47
18
// A note on the `x` and `y` properties
@@ -51,11 +22,11 @@ public struct Complex<RealType> where RealType: Real {
51
22
// `.real` and `.imaginary` properties, which wrap this storage and
52
23
// fixup the semantics for non-finite values.
53
24
54
- /// The real component of the value.
25
+ /// The storage for the real component of the value.
55
26
@usableFromInline @inline ( __always)
56
27
internal var x : RealType
57
28
58
- /// The imaginary part of the value.
29
+ /// The storage for the imaginary part of the value.
59
30
@usableFromInline @inline ( __always)
60
31
internal var y : RealType
61
32
@@ -93,27 +64,40 @@ extension Complex {
93
64
set { y = newValue }
94
65
}
95
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
+
96
78
/// The raw representation of the real part of this value.
79
+ @available ( * , deprecated, message: " Use rawStorage " )
97
80
@_transparent
98
81
public var _rawX : RealType { x }
99
82
100
83
/// The raw representation of the imaginary part of this value.
84
+ @available ( * , deprecated, message: " Use rawStorage " )
101
85
@_transparent
102
86
public var _rawY : RealType { y }
103
87
}
104
88
105
89
extension Complex {
106
90
/// The imaginary unit.
107
91
///
108
- /// See also `. zero`, `. one` and `. infinity`.
92
+ /// See also `` zero`` , `` one`` and `` infinity` `.
109
93
@_transparent
110
94
public static var i : Complex {
111
95
Complex ( 0 , 1 )
112
96
}
113
97
114
98
/// The point at infinity.
115
99
///
116
- /// See also `. zero`, `. one` and `.i `.
100
+ /// See also `` zero`` , `` one`` and ``i` `.
117
101
@_transparent
118
102
public static var infinity : Complex {
119
103
Complex ( . infinity, 0 )
@@ -123,7 +107,7 @@ extension Complex {
123
107
///
124
108
/// A complex value is finite if neither component is an infinity or nan.
125
109
///
126
- /// See also `. isNormal`, `. isSubnormal` and `. isZero`.
110
+ /// See also `` isNormal`` , `` isSubnormal`` and `` isZero` `.
127
111
@_transparent
128
112
public var isFinite : Bool {
129
113
x. isFinite && y. isFinite
@@ -136,7 +120,7 @@ extension Complex {
136
120
/// one of the components is normal if its exponent allows a full-precision
137
121
/// representation.
138
122
///
139
- /// See also `. isFinite`, `. isSubnormal` and `. isZero`.
123
+ /// See also `` isFinite`` , `` isSubnormal`` and `` isZero` `.
140
124
@_transparent
141
125
public var isNormal : Bool {
142
126
isFinite && ( x. isNormal || y. isNormal)
@@ -148,7 +132,7 @@ extension Complex {
148
132
/// When the result of a computation is subnormal, underflow has occurred and
149
133
/// the result generally does not have full precision.
150
134
///
151
- /// See also `. isFinite`, `. isNormal` and `. isZero`.
135
+ /// See also `` isFinite`` , `` isNormal`` and `` isZero` `.
152
136
@_transparent
153
137
public var isSubnormal : Bool {
154
138
isFinite && !isNormal && !isZero
@@ -159,7 +143,7 @@ extension Complex {
159
143
/// A complex number is zero if *both* the real and imaginary components
160
144
/// are zero.
161
145
///
162
- /// See also `. isFinite`, `. isNormal` and `isSubnormal`.
146
+ /// See also `` isFinite`` , `` isNormal`` and `` isSubnormal` `.
163
147
@_transparent
164
148
public var isZero : Bool {
165
149
x == 0 && y == 0
@@ -198,7 +182,7 @@ extension Complex {
198
182
self . init ( real, 0 )
199
183
}
200
184
201
- /// The complex number with specified imaginary part and zero real part.
185
+ /// The complex number with zero real part and specified imaginary part.
202
186
///
203
187
/// Equivalent to `Complex(0, imaginary)`.
204
188
@inlinable
0 commit comments