Swift Numerics is a new open-source library for Swift that attempts to fill a gap in Swift Standard Library, writes Apple's engineer Steve Cannon. Currently, it includes two modules, for real and complex computational mathematics, but more are on the roadmap.
The current decision to keep Swift Numerics in its own package rather than inside the Standard Library is mainly motivated by some limitations in the compiler that prevent the new APIs from being implemented in a way that preserves Swift's promise of source-stability across language versions. This does not rule out, though, that parts of Swift Numerics may transition to the Standard Library in the future. It goes without saying that only features that are generic enough will be considered for inclusion.
Swift Numerics is a modular library, meaning you can only import the module you need. For example, this is how you can import just the Complex
module:
import Complex
Alternatively, you can import the whole Numerics API by writing:
import Numerics
The Real
module defines three protocols: ElementaryFunctions
, RealFunctions
, and Real
, which is the most relevant of the three, says Cannon.
Real
describes a floating-point type providing a full set of numeric functions, such as exp
, log
, cos
, pow
, etc. Its power comes from the possibility of writing generic code that will seamlessly adapt itself to any new floating-point type that Swift will add in the future, such as Float16
or Float128
. The other two protocols mentioned above are used to partition functions that are easy to extend to numeric fields more general than real numbers and those that are not. The latter group includes functions such as exp2
and exp10
, gamma
, logGamma
, and many others.
Complex
numbers are built on top of Real
:
public struct Complex<RealType> where RealType: Real {
...
}
You can calculate most basic operations on complex numbers using a straightforward syntax:
import Complex
// Declare a complex number:
let z: Complex<Double> = 2 + 3 * .i
print(z) // (2.0, 3.0)
print(z.real) // 2.0
print(z.imaginary) // 3.0
let w = Complex<Double>(1, -2.5)
let zz = z + zz
let p = z * Complex(0, 2.5)
According to Cannon, Swift Numerics provide great performance in comparison with C code. This is mostly due to a simplification in the handling of zeroes and NaNs. While C (and C++) tends to distinguish different kinds of zeroes and NaNs, Swift Numerics opts for losing a bit of information in favour of simplifying code, which reduces the overhead on the programmer to keep things safe and correct and brings a significant speed-up, says Cannon.
As a last note, Swift Numerics is still under active development and more types will be added in the future, including Float16
, fixed-width integers larger than 64 bits, the ShapedArray
protocol to represent multidimensional homogeneous data, and others.