|
| 1 | +//===--- AlgebraicField.swift ---------------------------------*- swift -*-===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift Numerics open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2019 Apple Inc. and the Swift Numerics project authors |
| 6 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +// |
| 8 | +// See https://swift.org/LICENSE.txt for license information |
| 9 | +// |
| 10 | +//===----------------------------------------------------------------------===// |
| 11 | + |
| 12 | +/// A type modeling an algebraic [field]. Refines the `Numeric` protocol, |
| 13 | +/// adding division. |
| 14 | +/// |
| 15 | +/// A field is a set on which addition, subtraction, multiplication, and |
| 16 | +/// division are defined, and behave basically like those operations on |
| 17 | +/// the real numbers. More precisely, a field is a commutative group under |
| 18 | +/// its addition, the non-zero elements of the field form a commutative |
| 19 | +/// group under its multiplication, and the distributitve law holds. |
| 20 | +/// |
| 21 | +/// Some common examples of fields include: |
| 22 | +/// |
| 23 | +/// - the rational numbers |
| 24 | +/// - the real numbers |
| 25 | +/// - the complex numbers |
| 26 | +/// - the integers modulo a prime |
| 27 | +/// |
| 28 | +/// The most familiar example of a thing that is *not* a field is the integers. |
| 29 | +/// This may be surprising, since integers seem to have addition, subtraction, |
| 30 | +/// multiplication and division. Why don't they form a field? |
| 31 | +/// |
| 32 | +/// Because integer multiplication does not form a group; it's commutative and |
| 33 | +/// associative, but integers do not have multiplicative inverses. |
| 34 | +/// I.e. if a is any integer other than 1 or -1, there is no integer b such |
| 35 | +/// that a*b = 1. The existence of inverses is requried to form a field. |
| 36 | +/// |
| 37 | +/// If a type `T` conforms to the `Real` protocol, then `T` and `Complex<T>` |
| 38 | +/// both conform to `AlgebraicField`. |
| 39 | +/// |
| 40 | +/// See Also: |
| 41 | +/// - |
| 42 | +/// - Real |
| 43 | +/// - Numeric |
| 44 | +/// - AdditiveArithmetic |
| 45 | +/// |
| 46 | +/// [field]: https://en.wikipedia.org/wiki/Field_(mathematics) |
| 47 | +public protocol AlgebraicField: Numeric { |
| 48 | + |
| 49 | + static func /=(a: inout Self, b: Self) |
| 50 | + |
| 51 | + static func /(a: Self, b: Self) -> Self |
| 52 | + |
| 53 | + /// The (approximate) reciprocal (multiplicative inverse) of this number, |
| 54 | + /// if it is representable. |
| 55 | + /// |
| 56 | + /// If reciprocal is non-nil, you can replace division by self with |
| 57 | + /// multiplication by reciprocal and either get exact the same result |
| 58 | + /// (for finite fields) or approximately the same result up to a typical |
| 59 | + /// rounding error (for floating-point formats). |
| 60 | + /// |
| 61 | + /// If self is zero, or if a reciprocal would overflow or underflow such |
| 62 | + /// that it cannot be accurately represented, the result is nil. Note that |
| 63 | + /// `.zero.reciprocal`, somewhat surprisingly, is *not* nil for `Real` or |
| 64 | + /// `Complex` types, because these types have an `.infinity` value that |
| 65 | + /// acts as the reciprocal of `.zero`. |
| 66 | + var reciprocal: Self? { get } |
| 67 | +} |
| 68 | + |
| 69 | +extension AlgebraicField { |
| 70 | + @_transparent |
| 71 | + public static func /(a: Self, b: Self) -> Self { |
| 72 | + var result = a |
| 73 | + result /= b |
| 74 | + return result |
| 75 | + } |
| 76 | + |
| 77 | + /// Implementations should be *conservative* with the reciprocal property; |
| 78 | + /// it is OK to return `nil` even in cases where a reciprocal could be |
| 79 | + /// represented. For this reason, a default implementation that simply |
| 80 | + /// always returns `nil` is correct, but conforming types should provide |
| 81 | + /// a better implementation if possible. |
| 82 | + public var reciprocal: Self? { |
| 83 | + return nil |
| 84 | + } |
| 85 | +} |
0 commit comments