mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-25 16:15:19 +00:00
Compare commits
1 Commits
inv-trig
...
rational-n
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9192e671f4 |
1
build.gradle
Normal file → Executable file
1
build.gradle
Normal file → Executable file
@@ -11,6 +11,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1'
|
||||||
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
||||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
|
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.nwapw.abacus.number;
|
package org.nwapw.abacus.number;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,6 +62,15 @@ public class PreciseNumber extends NumberInterface {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a precise number from the given BigInteger.
|
||||||
|
*
|
||||||
|
* @param value a BigInteger object representing the value of the number.
|
||||||
|
*/
|
||||||
|
public PreciseNumber(BigInteger value) {
|
||||||
|
this.value = new BigDecimal(value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxPrecision() {
|
public int getMaxPrecision() {
|
||||||
return internalContext.getPrecision();
|
return internalContext.getPrecision();
|
||||||
|
|||||||
115
src/main/java/org/nwapw/abacus/number/RationalNumber.java
Executable file
115
src/main/java/org/nwapw/abacus/number/RationalNumber.java
Executable file
@@ -0,0 +1,115 @@
|
|||||||
|
package org.nwapw.abacus.number;
|
||||||
|
|
||||||
|
import org.apache.commons.math3.fraction.BigFraction;
|
||||||
|
import org.apache.commons.math3.fraction.Fraction;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class RationalNumber extends NumberInterface{
|
||||||
|
|
||||||
|
static final RationalNumber ONE = new RationalNumber(BigFraction.ONE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of the number.
|
||||||
|
*/
|
||||||
|
private BigFraction value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance with the given value.
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public RationalNumber(BigFraction value){
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxPrecision() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface multiplyInternal(NumberInterface multiplier) {
|
||||||
|
return new RationalNumber(value.multiply(((RationalNumber)multiplier).value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface divideInternal(NumberInterface divisor) {
|
||||||
|
return new RationalNumber(value.divide(((RationalNumber)divisor).value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface addInternal(NumberInterface summand) {
|
||||||
|
return new RationalNumber(value.add(((RationalNumber)summand).value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface subtractInternal(NumberInterface subtrahend) {
|
||||||
|
return new RationalNumber(value.subtract(((RationalNumber)subtrahend).value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface negateInternal() {
|
||||||
|
return new RationalNumber(value.negate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface intPowInternal(int exponent) {
|
||||||
|
return new RationalNumber(value.pow(exponent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(NumberInterface number) {
|
||||||
|
return value.compareTo(((RationalNumber)number).value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int signum() {
|
||||||
|
return value.getNumerator().signum();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface ceilingInternal() {
|
||||||
|
if(value.getNumeratorAsInt() != 1){
|
||||||
|
return floorInternal().add(ONE);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface floorInternal() {
|
||||||
|
BigInteger floor = value.bigDecimalValue().toBigInteger();
|
||||||
|
if(value.compareTo(BigFraction.ZERO) < 0 && value.getDenominatorAsInt() != 1){
|
||||||
|
floor = floor.subtract(BigInteger.ONE);
|
||||||
|
}
|
||||||
|
return new RationalNumber(new BigFraction(floor));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface fractionalPartInternal() {
|
||||||
|
return this.subtractInternal(floorInternal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int intValue() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberInterface promoteToInternal(Class<? extends NumberInterface> toClass) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberInterface getMaxError() {
|
||||||
|
return toPreciseNumber().getMaxError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return toPreciseNumber().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
PreciseNumber toPreciseNumber(){
|
||||||
|
return (PreciseNumber) new PreciseNumber(value.getNumerator()).divideInternal(new PreciseNumber(value.getDenominator()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -451,144 +451,6 @@ public class StandardPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The arcsine function (return type in radians).
|
|
||||||
*/
|
|
||||||
public final Function functionArcsin = new Function() {
|
|
||||||
@Override
|
|
||||||
protected boolean matchesParams(NumberInterface[] params) {
|
|
||||||
return params.length == 1
|
|
||||||
&& FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
|
||||||
if(FUNCTION_ABS.apply(params[0]).compareTo(new NaiveNumber(0.8).promoteTo(params[0].getClass())) >= 0){
|
|
||||||
NumberInterface[] newParams = {FUNCTION_SQRT.apply(fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))};
|
|
||||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
|
||||||
.subtract(applyInternal(newParams)).multiply(fromInt(params[0].getClass(), params[0].signum()));
|
|
||||||
}
|
|
||||||
NumberInterface currentTerm = params[0], sum = currentTerm,
|
|
||||||
multiplier = currentTerm.multiply(currentTerm), summandBound = sum.getMaxError().multiply(fromInt(sum.getClass(), 1).subtract(multiplier)),
|
|
||||||
power = currentTerm, coefficient = fromInt(params[0].getClass(), 1);
|
|
||||||
int exponent = 1;
|
|
||||||
while(FUNCTION_ABS.apply(currentTerm).compareTo(summandBound) > 0){
|
|
||||||
exponent += 2;
|
|
||||||
power = power.multiply(multiplier);
|
|
||||||
coefficient = coefficient.multiply(fromInt(params[0].getClass(), exponent-2))
|
|
||||||
.divide(fromInt(params[0].getClass(), exponent - 1));
|
|
||||||
currentTerm = power.multiply(coefficient).divide(fromInt(power.getClass(), exponent));
|
|
||||||
sum = sum.add(currentTerm);
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The arccosine function.
|
|
||||||
*/
|
|
||||||
public final Function functionArccos = new Function() {
|
|
||||||
@Override
|
|
||||||
protected boolean matchesParams(NumberInterface[] params) {
|
|
||||||
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
|
||||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
|
||||||
.subtract(functionArcsin.apply(params));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The arccosecant function.
|
|
||||||
*/
|
|
||||||
public final Function functionArccsc = new Function() {
|
|
||||||
@Override
|
|
||||||
protected boolean matchesParams(NumberInterface[] params) {
|
|
||||||
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
|
||||||
NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
|
||||||
return functionArcsin.apply(reciprocalParamArr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The arcsecant function.
|
|
||||||
*/
|
|
||||||
public final Function functionArcsec = new Function() {
|
|
||||||
@Override
|
|
||||||
protected boolean matchesParams(NumberInterface[] params) {
|
|
||||||
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
|
||||||
NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
|
||||||
return functionArccos.apply(reciprocalParamArr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The arctangent function.
|
|
||||||
*/
|
|
||||||
public final Function functionArctan = new Function() {
|
|
||||||
@Override
|
|
||||||
protected boolean matchesParams(NumberInterface[] params) {
|
|
||||||
return params.length == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
|
||||||
if(params[0].signum() == -1){
|
|
||||||
NumberInterface[] negatedParams = {params[0].negate()};
|
|
||||||
return applyInternal(negatedParams).negate();
|
|
||||||
}
|
|
||||||
if(params[0].compareTo(fromInt(params[0].getClass(), 1)) > 0){
|
|
||||||
NumberInterface[] reciprocalParams = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
|
||||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
|
||||||
.subtract(applyInternal(reciprocalParams));
|
|
||||||
}
|
|
||||||
if(params[0].compareTo(fromInt(params[0].getClass(), 1)) == 0){
|
|
||||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 4));
|
|
||||||
}
|
|
||||||
if(params[0].compareTo(new NaiveNumber(0.9).promoteTo(params[0].getClass())) >= 0){
|
|
||||||
NumberInterface[] newParams = {params[0].multiply(fromInt(params[0].getClass(),2 ))
|
|
||||||
.divide(fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))};
|
|
||||||
return applyInternal(newParams).divide(fromInt(params[0].getClass(), 2));
|
|
||||||
}
|
|
||||||
NumberInterface currentPower = params[0], currentTerm = currentPower, sum = currentTerm,
|
|
||||||
maxError = params[0].getMaxError(), multiplier = currentPower.multiply(currentPower).negate();
|
|
||||||
int n = 1;
|
|
||||||
while(FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0){
|
|
||||||
n += 2;
|
|
||||||
currentPower = currentPower.multiply(multiplier);
|
|
||||||
currentTerm = currentPower.divide(fromInt(currentPower.getClass(), n));
|
|
||||||
sum = sum.add(currentTerm);
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The arccotangent function. Range: (0, pi).
|
|
||||||
*/
|
|
||||||
public final Function functionArccot = new Function() {
|
|
||||||
@Override
|
|
||||||
protected boolean matchesParams(NumberInterface[] params) {
|
|
||||||
return params.length == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
|
||||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
|
||||||
.subtract(functionArctan.apply(params));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public StandardPlugin(PluginManager manager) {
|
public StandardPlugin(PluginManager manager) {
|
||||||
super(manager);
|
super(manager);
|
||||||
}
|
}
|
||||||
@@ -706,12 +568,6 @@ public class StandardPlugin extends Plugin {
|
|||||||
registerFunction("sec", functionSec);
|
registerFunction("sec", functionSec);
|
||||||
registerFunction("csc", functionCsc);
|
registerFunction("csc", functionCsc);
|
||||||
registerFunction("cot", functionCot);
|
registerFunction("cot", functionCot);
|
||||||
registerFunction("arcsin", functionArcsin);
|
|
||||||
registerFunction("arccos", functionArccos);
|
|
||||||
registerFunction("arccsc", functionArccsc);
|
|
||||||
registerFunction("arcsec", functionArcsec);
|
|
||||||
registerFunction("arctan", functionArctan);
|
|
||||||
registerFunction("arccot", functionArccot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user