1
0
mirror of https://github.com/DanilaFe/abacus synced 2024-11-18 00:19:32 -08:00

Add fromInt function into StandardPlugin and replace existing instantiations and promotions of NaiveNumbers with integer values with fromInt calls.

This commit is contained in:
Arthur Drobot 2017-08-07 10:33:16 -07:00
parent fcb264d134
commit 938f902c92

View File

@ -18,6 +18,11 @@ import java.util.function.BiFunction;
*/ */
public class StandardPlugin extends Plugin { public class StandardPlugin extends Plugin {
/**
* Stores objects of NumberInterface with integer values for reuse.
*/
private final static HashMap<Class<? extends NumberInterface>, HashMap<Integer, NumberInterface>> integerValues = new HashMap<>();
/** /**
* The addition operator, + * The addition operator, +
*/ */
@ -112,7 +117,7 @@ public class StandardPlugin extends Plugin {
@Override @Override
protected NumberInterface applyInternal(NumberInterface[] params) { protected NumberInterface applyInternal(NumberInterface[] params) {
if (params[0].signum() == 0) { if (params[0].signum() == 0) {
return (new NaiveNumber(1)).promoteTo(params[0].getClass()); return fromInt(params[0].getClass(), 1);
} }
NumberInterface factorial = params[0]; NumberInterface factorial = params[0];
NumberInterface multiplier = params[0]; NumberInterface multiplier = params[0];
@ -157,14 +162,14 @@ public class StandardPlugin extends Plugin {
int powersOf2 = 0; int powersOf2 = 0;
while (FUNCTION_ABS.apply(param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))).compareTo(new NaiveNumber(0.1).promoteTo(param.getClass())) >= 0) { while (FUNCTION_ABS.apply(param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))).compareTo(new NaiveNumber(0.1).promoteTo(param.getClass())) >= 0) {
if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() == 1) { if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() == 1) {
param = param.divide(new NaiveNumber(2).promoteTo(param.getClass())); param = param.divide(fromInt(param.getClass(), 2));
powersOf2++; powersOf2++;
if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() != 1) { if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() != 1) {
break; break;
//No infinite loop for you. //No infinite loop for you.
} }
} else { } else {
param = param.multiply(new NaiveNumber(2).promoteTo(param.getClass())); param = param.multiply(fromInt(param.getClass(), 2));
powersOf2--; powersOf2--;
if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() != -1) { if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() != -1) {
break; break;
@ -203,17 +208,17 @@ public class StandardPlugin extends Plugin {
*/ */
private NumberInterface getLog2(NumberInterface number) { private NumberInterface getLog2(NumberInterface number) {
NumberInterface maxError = getMaxError(number); NumberInterface maxError = getMaxError(number);
//NumberInterface errorBound = (new NaiveNumber(1)).promoteTo(number.getClass()); //NumberInterface errorBound = fromInt(number.getClass(), 1);
//We'll use the series \sigma_{n >= 1) ((1/3^n + 1/4^n) * 1/n) //We'll use the series \sigma_{n >= 1) ((1/3^n + 1/4^n) * 1/n)
//In the following, a=1/3^n, b=1/4^n, c = 1/n. //In the following, a=1/3^n, b=1/4^n, c = 1/n.
//a is also an error bound. //a is also an error bound.
NumberInterface a = (new NaiveNumber(1)).promoteTo(number.getClass()), b = a, c = a; NumberInterface a = fromInt(number.getClass(), 1), b = a, c = a;
NumberInterface sum = NaiveNumber.ZERO.promoteTo(number.getClass()); NumberInterface sum = NaiveNumber.ZERO.promoteTo(number.getClass());
int n = 0; int n = 0;
while (a.compareTo(maxError) >= 1) { while (a.compareTo(maxError) >= 1) {
n++; n++;
a = a.divide((new NaiveNumber(3)).promoteTo(number.getClass())); a = a.divide(fromInt(number.getClass(), 3));
b = b.divide((new NaiveNumber(4)).promoteTo(number.getClass())); b = b.divide(fromInt(number.getClass(), 4));
c = NaiveNumber.ONE.promoteTo(number.getClass()).divide((new NaiveNumber(n)).promoteTo(number.getClass())); c = NaiveNumber.ONE.promoteTo(number.getClass()).divide((new NaiveNumber(n)).promoteTo(number.getClass()));
sum = sum.add(a.add(b).multiply(c)); sum = sum.add(a.add(b).multiply(c));
} }
@ -311,7 +316,7 @@ public class StandardPlugin extends Plugin {
//right and left refer to lhs and rhs in the above inequality. //right and left refer to lhs and rhs in the above inequality.
NumberInterface sum = NaiveNumber.ONE.promoteTo(params[0].getClass()); NumberInterface sum = NaiveNumber.ONE.promoteTo(params[0].getClass());
NumberInterface nextNumerator = params[0]; NumberInterface nextNumerator = params[0];
NumberInterface left = params[0].multiply((new NaiveNumber(3)).promoteTo(params[0].getClass()).intPow(params[0].ceiling().intValue())), right = maxError; NumberInterface left = params[0].multiply(fromInt(params[0].getClass(), 3).intPow(params[0].ceiling().intValue())), right = maxError;
do { do {
sum = sum.add(nextNumerator.divide(factorial(params[0].getClass(), n + 1))); sum = sum.add(nextNumerator.divide(factorial(params[0].getClass(), n + 1)));
n++; n++;
@ -359,12 +364,12 @@ public class StandardPlugin extends Plugin {
@Override @Override
protected NumberInterface applyInternal(NumberInterface[] params) { protected NumberInterface applyInternal(NumberInterface[] params) {
NumberInterface pi = getPi(params[0].getClass()); NumberInterface pi = getPi(params[0].getClass());
NumberInterface twoPi = pi.multiply(new NaiveNumber(2).promoteTo(pi.getClass())); NumberInterface twoPi = pi.multiply(fromInt(pi.getClass(), 2));
NumberInterface theta = getSmallAngle(params[0], pi); NumberInterface theta = getSmallAngle(params[0], pi);
//System.out.println(theta); //System.out.println(theta);
if (theta.compareTo(pi.multiply(new NaiveNumber(1.5).promoteTo(twoPi.getClass()))) >= 0) { if (theta.compareTo(pi.multiply(new NaiveNumber(1.5).promoteTo(twoPi.getClass()))) >= 0) {
theta = theta.subtract(twoPi); theta = theta.subtract(twoPi);
} else if (theta.compareTo(pi.divide(new NaiveNumber(2).promoteTo(pi.getClass()))) > 0) { } else if (theta.compareTo(pi.divide(fromInt(pi.getClass(), 2))) > 0) {
theta = pi.subtract(theta); theta = pi.subtract(theta);
} }
//System.out.println(theta); //System.out.println(theta);
@ -382,7 +387,7 @@ public class StandardPlugin extends Plugin {
@Override @Override
protected NumberInterface applyInternal(NumberInterface[] params) { protected NumberInterface applyInternal(NumberInterface[] params) {
return functionSin.apply(getPi(params[0].getClass()).divide(new NaiveNumber(2).promoteTo(params[0].getClass())) return functionSin.apply(getPi(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
.subtract(params[0])); .subtract(params[0]));
} }
}; };
@ -470,7 +475,7 @@ public class StandardPlugin extends Plugin {
* @return the maximum error. * @return the maximum error.
*/ */
private static NumberInterface getMaxError(NumberInterface number) { private static NumberInterface getMaxError(NumberInterface number) {
return (new NaiveNumber(10)).promoteTo(number.getClass()).intPow(-number.getMaxPrecision()); return fromInt(number.getClass(), 10).intPow(-number.getMaxPrecision());
} }
/** /**
@ -531,6 +536,22 @@ public class StandardPlugin extends Plugin {
return theta; return theta;
} }
/**
* Returns a number of class numType with value n.
* @param numType class of number to return.
* @param n value of returned number.
* @return numClass instance with value n.
*/
private static NumberInterface fromInt(Class<? extends NumberInterface> numType, int n){
if(!integerValues.containsKey(numType)){
integerValues.put(numType, new HashMap<>());
}
if(!integerValues.get(numType).containsKey(n)){
integerValues.get(numType).put(n, new NaiveNumber(n).promoteTo(numType));
}
return integerValues.get(numType).get(n);
}
@Override @Override
public void onEnable() { public void onEnable() {
registerNumberImplementation("naive", IMPLEMENTATION_NAIVE); registerNumberImplementation("naive", IMPLEMENTATION_NAIVE);