apple / swift-numerics

Advanced mathematical types and functions for Swift
Apache License 2.0
1.68k stars 144 forks source link

Convenient name for `AlgebraicField & ElementaryFunctions` #100

Open NevinBR opened 4 years ago

NevinBR commented 4 years ago

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.

stephentyrone commented 4 years ago

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.

NevinBR commented 4 years ago

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

NevinBR commented 4 years ago

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.

stephentyrone commented 4 years ago

@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))
  }
}
NevinBR commented 4 years ago

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

stephentyrone commented 4 years ago

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