apple / swift-numerics

Advanced mathematical types and functions for Swift

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Convenient name for `AlgebraicField & ElementaryFunctions`

NevinBR opened this issue · comments

The natural place to write many generic algorithms is the protocol composition AlgebraicField & ElementaryFunctions, as it provides all the basic arithmetic operations including negation and division, as well as powers, roots, and transcendental functions.

To facilitate and encourage this practice, we should provide a convenient name for that composition.

It's worth listing what types can actually plausibly conform to such a protocol:

The elementary functions generally don't make sense for finite fields, and also don't make sense for anything "below" the reals. At the same time AlgebraicField requires commutative multiplication, so rules out anything "past" the complex numbers in some sense.

So the set of things that could conform is basically the reals and the complex numbers, plus a giant family of exotic non-Archimedian fields that could conform, but are relatively unlikely to be implemented.

So the set of things that could conform is basically the reals and the complex numbers

There could also be an ElementwiseMatrix type, which conforms using elementwise operations when its elements themselves do. I suspect this might be useful for machine-learning applications.

• • •

Some ideas for naming the protocol composition:

Math
BasicMath
Mathematical
Transcendental
Analytic

It’s worth noting that in Swift today, one cannot extend a protocol composition.

This suggests that either we should make a refining protocol instead of a typealias, or we should push on Swift Evolution to make it possible to extend a composition.

@NevinBR You can do a constrained extension to accomplish essentially the same thing (which is not to say that we shouldn't make a refining protocol):

extension ElementaryFunctions where Self: AlgebraicField {
  public func logisticCurve(
    _ x: Self,
    ceiling: Self = 1,
    rate: Self = 1,
    midpoint: Self = 0
  ) -> Self {
    return ceiling / 1 + .exp(rate * (midpoint - x))
  }
}

Right, my point is to make this easy and convenient for users.

Yup, just wanted to stick it on this thread so anyone searching for a solution to the issue finds it here =)