mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-23 07:15:19 +00:00
Merge branch 'provider-rewrite' into sin
# Conflicts: # src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java
This commit is contained in:
@@ -8,7 +8,6 @@ import org.nwapw.abacus.number.NaiveNumber;
|
||||
import org.nwapw.abacus.number.NumberInterface;
|
||||
import org.nwapw.abacus.number.PreciseNumber;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -20,7 +19,6 @@ import java.util.function.BiFunction;
|
||||
public class StandardPlugin extends Plugin {
|
||||
|
||||
private static HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>> factorialLists = new HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>>();
|
||||
static HashMap<Class<? extends NumberInterface>, NumberInterface> piValues = new HashMap<Class<? extends NumberInterface>, NumberInterface>();
|
||||
|
||||
/**
|
||||
* The addition operator, +
|
||||
@@ -287,7 +285,7 @@ public class StandardPlugin extends Plugin {
|
||||
/**
|
||||
* The sine function (the argument is interpreted in radians).
|
||||
*/
|
||||
public static final Function FUNCTION_SIN = new Function() {
|
||||
public final Function functionSin = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1;
|
||||
@@ -297,7 +295,7 @@ public class StandardPlugin extends Plugin {
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
NumberInterface pi = getPi(params[0].getClass());
|
||||
NumberInterface twoPi = pi.multiply(new NaiveNumber(2).promoteTo(pi.getClass()));
|
||||
NumberInterface theta = getSmallAngle(params[0]);
|
||||
NumberInterface theta = getSmallAngle(params[0], pi);
|
||||
//System.out.println(theta);
|
||||
if(theta.compareTo(pi.multiply(new NaiveNumber(1.5).promoteTo(twoPi.getClass()))) >= 0){
|
||||
theta = theta.subtract(twoPi);
|
||||
@@ -310,7 +308,7 @@ public class StandardPlugin extends Plugin {
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function FUNCTION_COS = new Function() {
|
||||
public final Function functionCos = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1;
|
||||
@@ -318,12 +316,12 @@ public class StandardPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
return FUNCTION_SIN.apply(getPi(params[0].getClass()).divide(new NaiveNumber(2).promoteTo(params[0].getClass()))
|
||||
return functionSin.apply(getPi(params[0].getClass()).divide(new NaiveNumber(2).promoteTo(params[0].getClass()))
|
||||
.subtract(params[0]));
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function FUNCTION_TAN = new Function() {
|
||||
public final Function functionTan = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1;
|
||||
@@ -331,11 +329,11 @@ public class StandardPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
return FUNCTION_SIN.apply(params[0]).divide(FUNCTION_COS.apply(params[0]));
|
||||
return functionSin.apply(params[0]).divide(functionCos.apply(params[0]));
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function FUNCTION_SEC = new Function() {
|
||||
public final Function functionSec = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1;
|
||||
@@ -343,11 +341,11 @@ public class StandardPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
return NaiveNumber.ONE.promoteTo(params[0].getClass()).divide(FUNCTION_COS.apply(params[0]));
|
||||
return NaiveNumber.ONE.promoteTo(params[0].getClass()).divide(functionCos.apply(params[0]));
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function FUNCTION_CSC = new Function() {
|
||||
public final Function functionCsc = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1;
|
||||
@@ -355,11 +353,11 @@ public class StandardPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
return NaiveNumber.ONE.promoteTo(params[0].getClass()).divide(FUNCTION_SIN.apply(params[0]));
|
||||
return NaiveNumber.ONE.promoteTo(params[0].getClass()).divide(functionSin.apply(params[0]));
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function FUNCTION_COT = new Function() {
|
||||
public final Function functionCot = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1;
|
||||
@@ -367,7 +365,59 @@ public class StandardPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
return FUNCTION_COS.apply(params[0]).divide(FUNCTION_COS.apply(params[0]));
|
||||
return functionCos.apply(params[0]).divide(functionCos.apply(params[0]));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The implementation for double-based naive numbers.
|
||||
*/
|
||||
public static final NumberImplementation IMPLEMENTATION_NAIVE = new NumberImplementation(NaiveNumber.class, 0) {
|
||||
@Override
|
||||
public NumberInterface instanceForString(String string) {
|
||||
return new NaiveNumber(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberInterface instanceForPi() {
|
||||
return new NaiveNumber(Math.PI);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The implementation for the infinite-precision BigDecimal.
|
||||
*/
|
||||
public static final NumberImplementation IMPLEMENTATION_PRECISE = new NumberImplementation(PreciseNumber.class, 0) {
|
||||
@Override
|
||||
public NumberInterface instanceForString(String string) {
|
||||
return new PreciseNumber(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberInterface instanceForPi() {
|
||||
NumberInterface C = FUNCTION_SQRT.apply(new PreciseNumber("10005")).multiply(new PreciseNumber("426880"));
|
||||
NumberInterface M = PreciseNumber.ONE;
|
||||
NumberInterface L = new PreciseNumber("13591409");
|
||||
NumberInterface X = M;
|
||||
NumberInterface sum = L;
|
||||
int termsNeeded = C.getMaxPrecision()/13 + 1;
|
||||
|
||||
NumberInterface lSummand = new PreciseNumber("545140134");
|
||||
NumberInterface xMultiplier = new PreciseNumber("262537412")
|
||||
.multiply(new PreciseNumber("1000000000"))
|
||||
.add(new PreciseNumber("640768000"))
|
||||
.negate();
|
||||
for(int i = 0; i < termsNeeded; i++){
|
||||
M = M
|
||||
.multiply(new NaiveNumber(12*i+2).promoteTo(PreciseNumber.class))
|
||||
.multiply(new NaiveNumber(12*i+6).promoteTo(PreciseNumber.class))
|
||||
.multiply(new NaiveNumber(12*i+10).promoteTo(PreciseNumber.class))
|
||||
.divide(new NaiveNumber(Math.pow(i+1,3)).promoteTo(PreciseNumber.class));
|
||||
L = L.add(lSummand);
|
||||
X = X.multiply(xMultiplier);
|
||||
sum = sum.add(M.multiply(L).divide(X));
|
||||
}
|
||||
return C.divide(sum);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -403,8 +453,8 @@ public class StandardPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
registerNumber("naive", NaiveNumber.class);
|
||||
registerNumber("precise", PreciseNumber.class);
|
||||
registerNumberImplementation("naive", IMPLEMENTATION_NAIVE);
|
||||
registerNumberImplementation("precise", IMPLEMENTATION_PRECISE);
|
||||
|
||||
registerOperator("+", OP_ADD);
|
||||
registerOperator("-", OP_SUBTRACT);
|
||||
@@ -417,12 +467,12 @@ public class StandardPlugin extends Plugin {
|
||||
registerFunction("exp", FUNCTION_EXP);
|
||||
registerFunction("ln", FUNCTION_LN);
|
||||
registerFunction("sqrt", FUNCTION_SQRT);
|
||||
registerFunction("sin", FUNCTION_SIN);
|
||||
registerFunction("cos", FUNCTION_COS);
|
||||
registerFunction("tan", FUNCTION_TAN);
|
||||
registerFunction("sec", FUNCTION_SEC);
|
||||
registerFunction("csc", FUNCTION_CSC);
|
||||
registerFunction("cot", FUNCTION_COT);
|
||||
registerFunction("sin", functionSin);
|
||||
registerFunction("cos", functionCos);
|
||||
registerFunction("tan", functionTan);
|
||||
registerFunction("sec", functionSec);
|
||||
registerFunction("csc", functionCsc);
|
||||
registerFunction("cot", functionCot);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -470,48 +520,13 @@ public class StandardPlugin extends Plugin {
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an approximation of Pi, with appropriate accuracy for given number class.
|
||||
* @param numClass type of number.
|
||||
* @return A number of class numClass, with value approximately Pi = 3.1415...
|
||||
*/
|
||||
public static NumberInterface getPi(Class<? extends NumberInterface> numClass){
|
||||
if(!piValues.containsKey(numClass)){
|
||||
//https://en.wikipedia.org/wiki/Chudnovsky_algorithm
|
||||
NumberInterface C = FUNCTION_SQRT.apply(new NaiveNumber(10005).promoteTo(numClass)).multiply(new NaiveNumber(426880).promoteTo(numClass));
|
||||
NumberInterface M = NaiveNumber.ONE.promoteTo(numClass);
|
||||
NumberInterface L = new NaiveNumber(13591409).promoteTo(numClass);
|
||||
NumberInterface X = M;
|
||||
NumberInterface sum = L;
|
||||
int termsNeeded = C.getMaxPrecision()/13 + 1;
|
||||
|
||||
NumberInterface lSummand = new NaiveNumber(545140134).promoteTo(L.getClass());
|
||||
NumberInterface xMultiplier = new NaiveNumber(262537412).promoteTo(X.getClass())
|
||||
.multiply(new NaiveNumber(1000000000).promoteTo(X.getClass()))
|
||||
.add(new NaiveNumber(640768000).promoteTo(X.getClass()))
|
||||
.negate();
|
||||
for(int i = 0; i < termsNeeded; i++){
|
||||
M = M
|
||||
.multiply(new NaiveNumber(12*i+2).promoteTo(M.getClass()))
|
||||
.multiply(new NaiveNumber(12*i+6).promoteTo(M.getClass()))
|
||||
.multiply(new NaiveNumber(12*i+10).promoteTo(M.getClass()))
|
||||
.divide(new NaiveNumber(Math.pow(i+1,3)).promoteTo(M.getClass()));
|
||||
L = L.add(lSummand);
|
||||
X = X.multiply(xMultiplier);
|
||||
sum = sum.add(M.multiply(L).divide(X));
|
||||
}
|
||||
piValues.put(numClass, C.divide(sum));
|
||||
}
|
||||
return piValues.get(numClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an equivalent angle in the interval [0, 2pi)
|
||||
* @param phi an angle (in radians).
|
||||
* @return theta in [0, 2pi) that differs from phi by a multiple of 2pi.
|
||||
*/
|
||||
private static NumberInterface getSmallAngle(NumberInterface phi){
|
||||
NumberInterface twoPi = getPi(phi.getClass()).multiply(new NaiveNumber("2").promoteTo(phi.getClass()));
|
||||
private static NumberInterface getSmallAngle(NumberInterface phi, NumberInterface pi){
|
||||
NumberInterface twoPi = pi.multiply(new NaiveNumber("2").promoteTo(phi.getClass()));
|
||||
NumberInterface theta = FUNCTION_ABS.apply(phi).subtract(twoPi
|
||||
.multiply(FUNCTION_ABS.apply(phi).divide(twoPi).floor())); //Now theta is in [0, 2pi).
|
||||
if(phi.signum() < 0){
|
||||
|
||||
Reference in New Issue
Block a user