Add exp and helper functions for Taylor Series etc.

This commit is contained in:
Arthur Drobot 2017-07-26 15:26:06 -07:00
parent aae7e678dd
commit 8d9dac1a75
1 changed files with 58 additions and 1 deletions

View File

@ -4,6 +4,8 @@ import org.nwapw.abacus.function.Function;
import org.nwapw.abacus.number.NaiveNumber;
import org.nwapw.abacus.number.NumberInterface;
import java.util.function.BiFunction;
/**
* The plugin providing standard functions such as addition and subtraction to
* the calculator.
@ -93,7 +95,17 @@ public class StandardPlugin extends Plugin {
}
});
System.out.println(getExpSeriesTerm(4, new NaiveNumber(3)));
registerFunction("exp", new Function() {
@Override
protected boolean matchesParams(NumberInterface[] params) {
return params.length == 1;
}
@Override
protected NumberInterface applyInternal(NumberInterface[] params) {
return sumSeries(params[0], StandardPlugin.this::getExpSeriesTerm, getNTermsExp(getMaxError(params[0]), params[0]));
}
});
}
/**
@ -106,4 +118,49 @@ public class StandardPlugin extends Plugin {
return x.intPow(n).divide(this.getFunction("!").apply((new NaiveNumber(n)).promoteTo(x.getClass())));
}
/**
* Returns the number of terms needed to evaluate the exponential function (at x)
* such that the error is at most maxError.
* @param maxError Maximum error permissible (This should probably be positive.)
* @param x where the function is evaluated.
* @return
*/
private int getNTermsExp(NumberInterface maxError, NumberInterface x){
//We need n such that x^(n+2) <= (n+1)! * maxError
//The variables LHS and RHS refer to the above inequality.
int n = 0;
NumberInterface LHS = x.intPow(2), RHS = maxError;
while(LHS.compareTo(RHS) > 0){
n++;
LHS = LHS.multiply(x);
RHS = RHS.multiply(new NaiveNumber(n).promoteTo(RHS.getClass()));
}
return n;
}
/**
* Returns a partial sum of a series whose terms are given by the nthTermFunction, evaluated at x.
* @param x the value at which the series is evaluated.
* @param nthTermFunction the function that returns the nth term of the series, in the format term(x, n).
* @param n the number of terms in the partial sum.
* @return the value of the partial sum that has the same class as x.
*/
private NumberInterface sumSeries(NumberInterface x, BiFunction<Integer, NumberInterface, NumberInterface> nthTermFunction, int n){
NumberInterface sum = NaiveNumber.ZERO.promoteTo(x.getClass());
for(int i = 0; i <= n; i++){
sum = sum.add(nthTermFunction.apply(i, x));
}
return sum;
}
/**
* Returns the maximum error based on the precision of the class of number.
* @param number Any instance of the NumberInterface in question (should return an appropriate precision).
* @return
*/
private NumberInterface getMaxError(NumberInterface number){
return (new NaiveNumber(10)).promoteTo(number.getClass()).intPow(-number.precision());
}
}