Skip to content

Various documentation improvements. #265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sources/ComplexModule/Complex+AdditiveArithmetic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019-2021 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand All @@ -14,7 +14,7 @@ import RealModule
extension Complex: AdditiveArithmetic {
/// The additive identity, with real and imaginary parts both zero.
///
/// See also: `one`, `i`, `infinity`
/// See also: ``one``, ``i``, ``infinity``
@_transparent
public static var zero: Complex {
Complex(0, 0)
Expand Down
4 changes: 3 additions & 1 deletion Sources/ComplexModule/Complex+AlgebraicField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019-2024 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand All @@ -13,6 +13,8 @@ import RealModule

extension Complex: AlgebraicField {
/// The multiplicative identity `1 + 0i`.
///
/// See also: ``zero``, ``i``, ``infinity``
@_transparent
public static var one: Complex {
Complex(1, 0)
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComplexModule/Complex+Codable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019 - 2021 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComplexModule/Complex+ElementaryFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019-2020 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComplexModule/Complex+Hashable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019 - 2021 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComplexModule/Complex+IntegerLiteral.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019 - 2021 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand Down
21 changes: 12 additions & 9 deletions Sources/ComplexModule/Complex+Numeric.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019 - 2021 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -37,17 +37,20 @@ extension Complex: Numeric {
self.init(real, 0)
}

/// The ∞-norm of the value (`max(abs(real), abs(imaginary))`).
/// The infinity-norm of the value (a.k.a. "maximum norm" or "Чебышёв
/// [Chebyshev] norm").
///
/// If you need the Euclidean norm (a.k.a. 2-norm) use the `length` or
/// `lengthSquared` properties instead.
/// Equal to `max(abs(real), abs(imaginary))`.
///
/// Edge cases:
/// - If `z` is not finite, `z.magnitude` is `.infinity`.
/// - If `z` is zero, `z.magnitude` is `0`.
/// - Otherwise, `z.magnitude` is finite and non-zero.
/// If you need to work with the Euclidean norm (a.k.a. 2-norm) instead,
/// use the ``length`` or ``lengthSquared`` properties. If you just need
/// to know "how big" a number is, use this property.
///
/// **Edge cases:**
///
/// See also `.length` and `.lengthSquared`.
/// - If `z` is not finite, `z.magnitude` is infinity.
/// - If `z` is zero, `z.magnitude` is zero.
/// - Otherwise, `z.magnitude` is finite and non-zero.
@_transparent
public var magnitude: RealType {
guard isFinite else { return .infinity }
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComplexModule/Complex+StringConvertible.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019 - 2021 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand Down
68 changes: 25 additions & 43 deletions Sources/ComplexModule/Complex.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This source file is part of the Swift Numerics open source project
//
// Copyright (c) 2019 - 2021 Apple Inc. and the Swift Numerics project authors
// Copyright (c) 2019-2025 Apple Inc. and the Swift Numerics project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand All @@ -11,39 +11,8 @@

import RealModule

/// A complex number represented by real and imaginary parts.
///
/// TODO: introductory text on complex numbers
///
/// Implementation notes:
///
/// This type does not provide heterogeneous real/complex arithmetic,
/// not even the natural vector-space operations like real * complex.
/// There are two reasons for this choice: first, Swift broadly avoids
/// mixed-type arithmetic when the operation can be adequately expressed
/// by a conversion and homogeneous arithmetic. Second, with the current
/// typechecker rules, it would lead to undesirable ambiguity in common
/// expressions (see README.md for more details).
///
/// Unlike C's `_Complex` and C++'s `std::complex<>` types, we do not
/// attempt to make meaningful semantic distinctions between different
/// representations of infinity or NaN. Any Complex value with at least
/// one non-finite component is simply "non-finite". In as much as
/// possible, we use the semantics of the point at infinity on the
/// Riemann sphere for such values. This approach simplifies the number of
/// edge cases that need to be considered for multiplication, division, and
/// the elementary functions considerably.
///
/// `.magnitude` does not return the Euclidean norm; it uses the "infinity
/// norm" (`max(|real|,|imaginary|)`) instead. There are two reasons for this
/// choice: first, it's simply faster to compute on most hardware. Second,
/// there exist values for which the Euclidean norm cannot be represented
/// (consider a number with `.real` and `.imaginary` both equal to
/// `RealType.greatestFiniteMagnitude`; the Euclidean norm would be
/// `.sqrt(2) * .greatestFiniteMagnitude`, which overflows). Using
/// the infinity norm avoids this problem entirely without significant
/// downsides. You can access the Euclidean norm using the `length`
/// property.
// A [complex number](https://en.wikipedia.org/wiki/Complex_number).
// See Documentation.docc/Complex.md for more details.
@frozen
public struct Complex<RealType> where RealType: Real {
// A note on the `x` and `y` properties
Expand All @@ -53,11 +22,11 @@ public struct Complex<RealType> where RealType: Real {
// `.real` and `.imaginary` properties, which wrap this storage and
// fixup the semantics for non-finite values.

/// The real component of the value.
/// The storage for the real component of the value.
@usableFromInline @inline(__always)
internal var x: RealType

/// The imaginary part of the value.
/// The storage for the imaginary part of the value.
@usableFromInline @inline(__always)
internal var y: RealType

Expand Down Expand Up @@ -95,27 +64,40 @@ extension Complex {
set { y = newValue }
}

/// The raw representation of the value.
///
/// Use this when you need the underlying RealType values,
/// without fixup for NaN or infinity.
public var rawStorage: (x: RealType, y: RealType) {
@_transparent
get { (x, y) }
@_transparent
set { (x, y) = newValue }
}

/// The raw representation of the real part of this value.
@available(*, deprecated, message: "Use rawStorage")
@_transparent
public var _rawX: RealType { x }

/// The raw representation of the imaginary part of this value.
@available(*, deprecated, message: "Use rawStorage")
@_transparent
public var _rawY: RealType { y }
}

extension Complex {
/// The imaginary unit.
///
/// See also `.zero`, `.one` and `.infinity`.
/// See also ``zero``, ``one`` and ``infinity``.
@_transparent
public static var i: Complex {
Complex(0, 1)
}

/// The point at infinity.
///
/// See also `.zero`, `.one` and `.i`.
/// See also ``zero``, ``one`` and ``i``.
@_transparent
public static var infinity: Complex {
Complex(.infinity, 0)
Expand All @@ -125,7 +107,7 @@ extension Complex {
///
/// A complex value is finite if neither component is an infinity or nan.
///
/// See also `.isNormal`, `.isSubnormal` and `.isZero`.
/// See also ``isNormal``, ``isSubnormal`` and ``isZero``.
@_transparent
public var isFinite: Bool {
x.isFinite && y.isFinite
Expand All @@ -138,7 +120,7 @@ extension Complex {
/// one of the components is normal if its exponent allows a full-precision
/// representation.
///
/// See also `.isFinite`, `.isSubnormal` and `.isZero`.
/// See also ``isFinite``, ``isSubnormal`` and ``isZero``.
@_transparent
public var isNormal: Bool {
isFinite && (x.isNormal || y.isNormal)
Expand All @@ -150,7 +132,7 @@ extension Complex {
/// When the result of a computation is subnormal, underflow has occurred and
/// the result generally does not have full precision.
///
/// See also `.isFinite`, `.isNormal` and `.isZero`.
/// See also ``isFinite``, ``isNormal`` and ``isZero``.
@_transparent
public var isSubnormal: Bool {
isFinite && !isNormal && !isZero
Expand All @@ -161,7 +143,7 @@ extension Complex {
/// A complex number is zero if *both* the real and imaginary components
/// are zero.
///
/// See also `.isFinite`, `.isNormal` and `isSubnormal`.
/// See also ``isFinite``, ``isNormal`` and ``isSubnormal``.
@_transparent
public var isZero: Bool {
x == 0 && y == 0
Expand Down Expand Up @@ -200,7 +182,7 @@ extension Complex {
self.init(real, 0)
}

/// The complex number with specified imaginary part and zero real part.
/// The complex number with zero real part and specified imaginary part.
///
/// Equivalent to `Complex(0, imaginary)`.
@inlinable
Expand Down
67 changes: 67 additions & 0 deletions Sources/ComplexModule/Documentation.docc/Complex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# ``Complex``

A complex number type represented by its real and imaginary parts, and equipped
with the usual arithmetic operators and math functions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯


## Overview

You can access these Cartesian components using the real and imaginary
properties.

```swift
let z = Complex(1,-1) // 1 - i
let re = z.real // 1
let im = z.imaginary // -1
```

All `Complex` numbers with a non-finite component are treated as a single
"point at infinity," with infinite magnitude and indeterminant phase. Thus,
the real and imaginary parts of an infinity are nan.

```swift
let w = Complex<Double>.infinity
w == -w // true
let re = w.real // .nan
let im = w.imag // .nan
```

See <doc:Infinity> for more details.

The ``magnitude`` property of a complex number is the infinity norm of the
value (a.k.a. “maximum norm” or “Чебышёв [Chebyshev] norm”). To get the two
norm (a.k.a. "Euclidean norm"), use the ``length`` property. See
<doc:Magnitude> for more details.

## Topics

### Real and imaginary parts

- ``real``
- ``imaginary``
- ``rawStorage``
- ``init(_:_:)``
- ``init(_:)-5aesj``
- ``init(imaginary:)``

### Phase, length and magnitude

- ``magnitude``
- ``length``
- ``lengthSquared``
- ``normalized``
- ``phase``
- ``polar``
- ``init(length:phase:)``

### Scaling by real numbers
- ``multiplied(by:)``
- ``divided(by:)``

### Complex-specific operations
- ``conjugate``

### Classification
- ``isZero``
- ``isSubnormal``
- ``isNormal``
- ``isFinite``
Loading