Skip to content

1.1: Relax

Choose a tag to compare

@stephentyrone stephentyrone released this 28 Aug 19:56
· 2 commits to release/1.1 since this release
bbadd4b
  • 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 than strictSum, and often 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 from Real to FloatingPoint. This is more correct and makes the operations more broadly useful. Arguably, Augmented.sum(large:small:) should be constrained to BinaryFloatingPoint, because the fast2sum algorithm doesn’t work in radix 10, but this would complicate generic call sites. Instead, it will dispatch to the unordered sum(_:_:) 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 naïve 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-à-vis what is seen on 1.0.x

  • Complex no longer conditionally conforms to Differentiable. Given that the Differentiation module has not formally stabilized, support for it will be moved onto a feature branch for now.

  • AlgebraicField has a Magnitude: 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 new rawStorage 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.

As always, thanks for your feedback and contributions.