# apple/swift-numerics

`The link target for `[Real]` wasn't defined. I decided toremove the link altogether because the readme would essentially link to itself.`
Latest commit 0ed7e78 Nov 12, 2019
Type Name Latest commit message Commit time
..
Failed to load latest commit information. ElementaryFunctions.swift Nov 11, 2019 README.md Nov 12, 2019 Real.swift Nov 11, 2019 RealFunctions.swift Nov 8, 2019 ScalarConformances.swift Nov 11, 2019

# Real

SE-0246 proposed an API for "basic math functions" that would make operations like sine and logarithm available in generic contexts. It was accepted, but because of limitations in the compiler, the API could not be added to the standard library in a source-stable manner. The `Real` module provides that API as a separate module so that you can use it right away to get access to the improved API for these operations in your projects.

## Protocols and Methods

The module defines three protocols. The most general is `ElementaryFunctions`, which makes the following functions available:

• Exponential functions: `exp`, `expMinusOne`
• Logarithmic functions: `log`, `log(onePlus:)`
• Trigonometric functions: `cos`, `sin`, `tan`
• Inverse trigonometric functions: `acos`, `asin`, `atan`
• Hyperbolic functions: `cosh`, `sinh`, `tanh`
• Inverse hyperbolic functions: `acosh`, `asinh`, `atanh`
• Power and root functions: `pow`, `sqrt`, `root`

`ElementaryFunctions` refines `AdditiveArithmetic`, and so also provides addition, subtraction, and the `.zero` property.

The `RealFunctions` protocol refines `ElementaryFunctions`, and adds operations that are difficult to define or implement over fields more general than the real numbers:

• `atan2(y:x:)`, which computes `atan(y/x)` with sign chosen by the quadrant of the point `(x,y)` in the Cartesian plane.
• `hypot`, which computes `sqrt(x*x + y*y)` without intermediate overflow or underflow.
• `erf` and `erfc`, the error function and its complement.
• Exponential functions: `exp2` and `exp10`
• Logarithmetic functions: `log2` and `log10`
• Gamma functions: `gamma`, `logGamma`, and `signGamma`, which evaluate the gamma function, its logarithm, and its sign.

The protocol that you will use most often is `Real`, which describes a floating-point type equipped with the full set of basic math functions. This is a great protocol to use in writing generic code, because it has all the basics that you need to implement most numeric functions.

## Using Real

First, either import `Real` directly or import the `Numerics` umbrella module.

Suppose we were experimenting with some basic machine learning, and needed a generic [sigmoid function][Sigmoid] activation function:

```import Numerics

func sigmoid<T: Real>(_ x: T) -> T {
1 / (1 + .exp(-x))
}```

Or suppose we were implementing a DFT, and wanted to precompute weights for the transform; DFT weights are roots of unity:

```import Numerics

extension Real {
// The real and imaginary parts of e^{-2πik/n}
static func dftWeight(k: Int, n: Int) -> (r: Self, i: Self) {
precondition(0 <= k && k < n, "k is out of range")
guard let N = Self(exactly: n) else {
preconditionFailure("n cannot be represented exactly.")
}
let theta = -2 * .pi * (Self(k) / N)
return (r: .cos(theta), i: .sin(theta))
}
}```

This gives us an implementation that works for `Float`, `Double`, and `Float80` if the target supports it. When new basic floating-point types are added to Swift, like `Float16` or `Float128`, it will work for them as well. Not having this protocol is a significant missing feature for numerical computing in Swift, and I'm really looking forward to seeing what people do with it.

### Dependencies:

• The C standard math library (`libm`) via the `NumericShims` target.
You can’t perform that action at this time.