Details
-
Improvement
-
Status: Closed
-
Trivial
-
Resolution: Implemented
-
1.0
-
None
Description
The updated Gamma function (see NUMBERS-174) tabulates all representable factorials.
This suggests one of the following changes:
- The FactorialDouble class can call the Gamma function to obtain the values.
- The FactorialDouble class can also tabulate the values and not use a dependency on the Gamma class
Note that if the call is made to the Gamma class the method is effectively:
public static double value(int n) { // The Gamma class has all factorial values tabulated. return tgamma(n + 1); } static double tgamma(double z) { // Handle integers if (Math.rint(z) == z) { if (z <= 0) { // Pole error return Double.NaN; } if (z <= MAX_GAMMA_Z) { // Gamma(n) = (n-1)! return FACTORIAL[(int) z - 1]; } // Overflow return Double.POSITIVE_INFINITY; } // ... Not used }
So calling the Gamma method has a round trip of the integer to a double, a check it is an integer, then a conversion back to an integer.
The FactorialDouble class also has a cache of the values. So all the values are precomputed once and stored for the instance.
I suggest updating the class to remove the cache and just storing the 171 representable double values for values up to 170!. The public API can remain the same but the cache methods marked as deprecated. The value method then becomes:
public double value(int n) { if (n < 0) { throw new CombinatoricsException(CombinatoricsException.NEGATIVE, n); } if (n < FACTORIAL.length) { // Cache of precomputed values up to 170! return FACTORIAL[n]; } return Double.POSITIVE_INFINITY; }
Note:
This class is a similar implementation to the LogFactorial class. In that case the maximum representable LogFactorial is very big and the cache functionality makes sense. For a maximum cache size of 171 this caching functionality seems unnecessary.