apple / swift-numerics

Advanced mathematical types and functions for Swift

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add `compound` function

stephentyrone opened this issue · comments

IEEE 754 recommends (but does not require) a compound function, which is in the process of being standardized for C and C++; we should expose it in swift-numerics. The simplest, most literal translation of the operation into Swift would be:

extension RealFunctions {
  /// (1+x)ⁿ
  /// 
  /// Returns NaN if x < -1.
  static func compound(_ x: Self, _ n: Int) -> Self {
    // not quite production-quality implementation
    // (good for well-scaled results, loses precision
    // near overflow and underflow, also misbehaves
    // when n cannot be represented as Self).
    exp(Self(n) * log(onePlus: x))
  }
}

A good implementation is somewhat subtle, but we can come up with a good solution. I'm initially mainly interested in feedback on what the API should look like for this operation, both the naming and whether to put it on RealFunctions or ElementaryFunctions (where it can also be defined).

Admittedly, I'm not terribly familiar with the compound terminology.

However, it seems to me that this function might fit well with the naming scheme of the other 1p functions; i.e., as static func pow(onePlus x: Self, _ n: Int) -> Self. (It seems that I'm not alone, as this was also suggested parenthetically for Julia.)

I think, even if compound makes a lot of sense within the realm of floating-point operations, in a general purpose language (and even in a numerics library, where theoretically there could be a fraction type, for instance), there's not one unambiguous meaning of the word. pow(onePlus:_:) on the other hand, would be pretty difficult to misinterpret.

Yes, I think that's an excellent suggestion, given the log(onePlus:) precedent that we have. The compound name used by IEEE 754 comes from the fact that this function computes (simple) compound interest for a rate of x applied over n periods.

There's also an interesting question of whether or not the better operation to provide would actually be (1+x)ⁿ - 1, which is less often what people think they want but numerically more useful in some ways.

There's also an interesting question of whether or not the better operation to provide would actually be (1+x)ⁿ - 1, which is less often what people think they want but numerically more useful in some ways.

I’d support this. The straightforward name powMinusOne(onePlus: x, n) might seem a little awkward, but it’s clear about what it does..

Also worth considering if we should include the (Self, Self) version in addition to the (Self, Int) one.

For placement, I think this operation naturally belongs on ElementaryFunctions. The idiom of compound interest might not make sense outside the reals, but the concept of binomial powers definitely does.

Here are two Wikipedia pages explaining the concept, that might be helpful to others:
https://en.wikipedia.org/wiki/Compound_interest
https://en.wikipedia.org/wiki/E_(mathematical_constant)#Compound_interest
I was researching the purpose and terminology of compound and (1+x)ⁿ - 1 and found them quite useful.