Hi all –
I’m preparing to tag the 1.1 release of numerics. This release branch introduces the following features and significant changes:
-
Expanded documentation and docc catalogs for ComplexModule and RealModule
-
“Relaxed arithmetic” bindings are added to the Real module. These allow you to write floating-point arithmetic that licenses the compiler to reassociate and form FMAs, which allows for much better performance in hot loops (e.g. if you are writing a signal-processing or linear algebra kernel in Swift). I expect that these will get nicer syntax sugar eventually, but I want the functionality to be available now, because it can make a huge difference in some cases. For arrays that fit into cache, on common hardware,
relaxedSum
below is an order of magnitude faster thanstrictSum
, and competitive with specialized libraries when optimization is enabled. -
func strictSum(_ array: [Float]) -> Float { array.reduce(0, +) } import RealModule func relaxedSum(_ array: [Float]) -> Float { array.reduce(0, Relaxed.sum) }
-
The generic constraint on the
Augmented
arithmetic methods has been relaxed fromReal
toFloatingPoint
. This is more correct and makes the operations more broadly useful. Formally,Augmented.sum(large:small:)
should arguably be constrained toBinaryFloatingPoint
, because the fast2sum algorithm doesn’t work in radix 10, but this would complicate generic call sites. Instead, it will dispatch to the unorderedsum(_:_:)
for decimal types, so that callers do not have to worry about this detail. -
There is a new algorithm for complex division when the inputs are poorly scaled such that the naive approach would fail. This gives more accurate results than the old approach, and (importantly for some use cases) does not perturb results if the numerator and denominator are rescaled by the same power of two (up to the underflow boundary), and is more optimizable. Note that while it produces better results, the results will change for some inputs vis-a-vis what is seen on 1.0.x
-
Complex
no longer conditionally conforms toDifferentiable
. Given that the Differentiation module has not formally stabilized, support for it will be moved onto a feature branch for now. -
AlgebraicField
has aMagnitude: AlgebraicField
constraint. This is formally source-breaking. I do not expect it to actually matter for any real-world clients, which is why this isn’t a major-version release, but I want to make sure people are aware of it. Please speak up if it would have an effect that I’m overlooking. -
Complex
has a newrawStorage
property that directly vends the cartesian coordinates as a tuple. Previously they were available via underscored properties. These are mainly useful for interoperation with other languages, but are expected to be fairly niche outside of that use case.
I expect to cut a candidate tag in the next few days, and release 1.1.0 around the end of next week if no issues are raised.