diff --git a/src/org/nwapw/abacus/plugin/StandardPlugin.java b/src/org/nwapw/abacus/plugin/StandardPlugin.java index f7a2363..9881ff2 100755 --- a/src/org/nwapw/abacus/plugin/StandardPlugin.java +++ b/src/org/nwapw/abacus/plugin/StandardPlugin.java @@ -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 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()); + } + }