mirror of
				https://github.com/DanilaFe/abacus
				synced 2025-10-30 17:33:42 -07:00 
			
		
		
		
	Require applicable interfaces to be passed an implementation they use.
This commit is contained in:
		
							parent
							
								
									f7c07ca04d
								
							
						
					
					
						commit
						2b700d3911
					
				| @ -138,16 +138,14 @@ public class Abacus { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Creates a number from a string. |      * Gets the number implementation. | ||||||
|      * |      * @return the number implementation to use for creating numbers. | ||||||
|      * @param numberString the string to create the number from. |  | ||||||
|      * @return the resulting number. |  | ||||||
|      */ |      */ | ||||||
|     public NumberInterface numberFromString(String numberString) { |     public NumberImplementation getNumberImplementation(){ | ||||||
|         NumberImplementation toInstantiate = |         NumberImplementation selectedImplementation = | ||||||
|                 pluginManager.numberImplementationFor(configuration.getNumberImplementation()); |                 pluginManager.numberImplementationFor(configuration.getNumberImplementation()); | ||||||
|         if (toInstantiate == null) toInstantiate = DEFAULT_IMPLEMENTATION; |         if(selectedImplementation != null) return selectedImplementation; | ||||||
| 
 |         return DEFAULT_IMPLEMENTATION; | ||||||
|         return toInstantiate.instanceForString(numberString); |  | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -20,12 +20,13 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberOperator OP_ADD = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0) { |     public static final NumberOperator OP_ADD = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0) { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 2; |             return params.length == 2; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params[0].add(params[1]); |             return params[0].add(params[1]); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -34,12 +35,13 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberOperator OP_SUBTRACT = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0) { |     public static final NumberOperator OP_SUBTRACT = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 0) { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 2; |             return params.length == 2; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params[0].subtract(params[1]); |             return params[0].subtract(params[1]); | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
| @ -49,12 +51,13 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberOperator OP_NEGATE = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.UNARY_PREFIX, 0) { |     public static final NumberOperator OP_NEGATE = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.UNARY_PREFIX, 0) { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params[0].negate(); |             return params[0].negate(); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -63,12 +66,13 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberOperator OP_MULTIPLY = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 1) { |     public static final NumberOperator OP_MULTIPLY = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 1) { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 2; |             return params.length == 2; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params[0].multiply(params[1]); |             return params[0].multiply(params[1]); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -91,13 +95,14 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberFunction FUNCTION_SQRT = new NumberFunction() { |     public static final NumberFunction FUNCTION_SQRT = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return OP_CARET.apply(params[0], ((new NaiveNumber(0.5)).promoteTo(params[0].getClass()))); |             return OP_CARET.apply(implementation, params[0], ((new NaiveNumber(0.5)).promoteTo(params[0].getClass()))); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     /** |     /** | ||||||
| @ -111,7 +116,7 @@ public class StandardPlugin extends Plugin { | |||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface instanceForPi() { |         public NumberInterface instanceForPi() { | ||||||
|             NumberInterface C = FUNCTION_SQRT.apply(new PreciseNumber("10005")).multiply(new PreciseNumber("426880")); |             NumberInterface C = FUNCTION_SQRT.apply(this, new PreciseNumber("10005")).multiply(new PreciseNumber("426880")); | ||||||
|             NumberInterface M = PreciseNumber.ONE; |             NumberInterface M = PreciseNumber.ONE; | ||||||
|             NumberInterface L = new PreciseNumber("13591409"); |             NumberInterface L = new PreciseNumber("13591409"); | ||||||
|             NumberInterface X = M; |             NumberInterface X = M; | ||||||
| @ -145,12 +150,13 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberOperator OP_DIVIDE = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 1) { |     public static final NumberOperator OP_DIVIDE = new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, 1) { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 2 && params[1].compareTo(fromInt(params[0].getClass(), 0)) != 0; |             return params.length == 2 && params[1].compareTo(fromInt(params[0].getClass(), 0)) != 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params[0].divide(params[1]); |             return params[0].divide(params[1]); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -160,14 +166,15 @@ public class StandardPlugin extends Plugin { | |||||||
|     public static final NumberOperator OP_FACTORIAL = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.UNARY_POSTFIX, 0) { |     public static final NumberOperator OP_FACTORIAL = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.UNARY_POSTFIX, 0) { | ||||||
|         //private HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>> storedList = new HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>>(); |         //private HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>> storedList = new HashMap<Class<? extends NumberInterface>, ArrayList<NumberInterface>>(); | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1 |             return params.length == 1 | ||||||
|                     && params[0].fractionalPart().compareTo(fromInt(params[0].getClass(), 0)) == 0 |                     && params[0].fractionalPart().compareTo(fromInt(params[0].getClass(), 0)) == 0 | ||||||
|                     && params[0].signum() >= 0; |                     && params[0].signum() >= 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             if (params[0].signum() == 0) { |             if (params[0].signum() == 0) { | ||||||
|                 return fromInt(params[0].getClass(), 1); |                 return fromInt(params[0].getClass(), 1); | ||||||
|             } |             } | ||||||
| @ -191,13 +198,14 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberOperator OP_NPR = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0) { |     public static final NumberOperator OP_NPR = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0) { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 2 && params[0].fractionalPart().signum() == 0 |             return params.length == 2 && params[0].fractionalPart().signum() == 0 | ||||||
|                     && params[1].fractionalPart().signum() == 0; |                     && params[1].fractionalPart().signum() == 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             if (params[0].compareTo(params[1]) < 0 || |             if (params[0].compareTo(params[1]) < 0 || | ||||||
|                     params[0].signum() < 0 || |                     params[0].signum() < 0 || | ||||||
|                     (params[0].signum() == 0 && params[1].signum() != 0)) return fromInt(params[0].getClass(), 0); |                     (params[0].signum() == 0 && params[1].signum() != 0)) return fromInt(params[0].getClass(), 0); | ||||||
| @ -221,14 +229,15 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberOperator OP_NCR = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0) { |     public static final NumberOperator OP_NCR = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 0) { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 2 && params[0].fractionalPart().signum() == 0 |             return params.length == 2 && params[0].fractionalPart().signum() == 0 | ||||||
|                     && params[1].fractionalPart().signum() == 0; |                     && params[1].fractionalPart().signum() == 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return OP_NPR.apply(params).divide(OP_FACTORIAL.apply(params[1])); |             return OP_NPR.apply(implementation, params).divide(OP_FACTORIAL.apply(implementation, params[1])); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     /** |     /** | ||||||
| @ -236,12 +245,13 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberFunction FUNCTION_ABS = new NumberFunction() { |     public static final NumberFunction FUNCTION_ABS = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params[0].multiply(fromInt(params[0].getClass(), params[0].signum())); |             return params[0].multiply(fromInt(params[0].getClass(), params[0].signum())); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -250,16 +260,17 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberFunction FUNCTION_LN = new NumberFunction() { |     public static final NumberFunction FUNCTION_LN = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1 && params[0].compareTo(fromInt(params[0].getClass(), 0)) > 0; |             return params.length == 1 && params[0].compareTo(fromInt(params[0].getClass(), 0)) > 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             NumberInterface param = params[0]; |             NumberInterface param = params[0]; | ||||||
|             NumberInterface one = fromInt(param.getClass(), 1); |             NumberInterface one = fromInt(param.getClass(), 1); | ||||||
|             int powersOf2 = 0; |             int powersOf2 = 0; | ||||||
|             while (FUNCTION_ABS.apply(param.subtract(one)).compareTo(new NaiveNumber(0.1).promoteTo(param.getClass())) >= 0) { |             while (FUNCTION_ABS.apply(implementation, param.subtract(one)).compareTo(new NaiveNumber(0.1).promoteTo(param.getClass())) >= 0) { | ||||||
|                 if (param.subtract(one).signum() == 1) { |                 if (param.subtract(one).signum() == 1) { | ||||||
|                     param = param.divide(fromInt(param.getClass(), 2)); |                     param = param.divide(fromInt(param.getClass(), 2)); | ||||||
|                     powersOf2++; |                     powersOf2++; | ||||||
| @ -276,7 +287,7 @@ public class StandardPlugin extends Plugin { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             return getLog2(param).multiply(fromInt(param.getClass(), powersOf2)).add(getLogPartialSum(param)); |             return getLog2(implementation, param).multiply(fromInt(param.getClass(), powersOf2)).add(getLogPartialSum(implementation, param)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /** |         /** | ||||||
| @ -285,13 +296,13 @@ public class StandardPlugin extends Plugin { | |||||||
|          * @param x value at which the series is evaluated. 0 < x < 2. (x=2 is convergent but impractical.) |          * @param x value at which the series is evaluated. 0 < x < 2. (x=2 is convergent but impractical.) | ||||||
|          * @return the partial sum. |          * @return the partial sum. | ||||||
|          */ |          */ | ||||||
|         private NumberInterface getLogPartialSum(NumberInterface x) { |         private NumberInterface getLogPartialSum(NumberImplementation implementation, NumberInterface x) { | ||||||
| 
 | 
 | ||||||
|             NumberInterface maxError = x.getMaxError(); |             NumberInterface maxError = x.getMaxError(); | ||||||
|             x = x.subtract(fromInt(x.getClass(), 1)); //Terms used are for log(x+1). |             x = x.subtract(fromInt(x.getClass(), 1)); //Terms used are for log(x+1). | ||||||
|             NumberInterface currentNumerator = x, currentTerm = x, sum = x; |             NumberInterface currentNumerator = x, currentTerm = x, sum = x; | ||||||
|             int n = 1; |             int n = 1; | ||||||
|             while (FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0) { |             while (FUNCTION_ABS.apply(implementation, currentTerm).compareTo(maxError) > 0) { | ||||||
|                 n++; |                 n++; | ||||||
|                 currentNumerator = currentNumerator.multiply(x).negate(); |                 currentNumerator = currentNumerator.multiply(x).negate(); | ||||||
|                 currentTerm = currentNumerator.divide(fromInt(x.getClass(), n)); |                 currentTerm = currentNumerator.divide(fromInt(x.getClass(), n)); | ||||||
| @ -305,7 +316,7 @@ public class StandardPlugin extends Plugin { | |||||||
|          * @param number a number of the same type as the return type. (Used for precision.) |          * @param number a number of the same type as the return type. (Used for precision.) | ||||||
|          * @return the value of log(2) with the appropriate precision. |          * @return the value of log(2) with the appropriate precision. | ||||||
|          */ |          */ | ||||||
|         private NumberInterface getLog2(NumberInterface number) { |         private NumberInterface getLog2(NumberImplementation implementation, NumberInterface number) { | ||||||
|             NumberInterface maxError = number.getMaxError(); |             NumberInterface maxError = number.getMaxError(); | ||||||
|             //NumberInterface errorBound = fromInt(number.getClass(), 1); |             //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) | ||||||
| @ -330,12 +341,13 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberFunction FUNCTION_RAND_INT = new NumberFunction() { |     public static final NumberFunction FUNCTION_RAND_INT = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return fromInt(params[0].getClass(), (int) Math.round(Math.random() * params[0].floor().intValue())); |             return fromInt(params[0].getClass(), (int) Math.round(Math.random() * params[0].floor().intValue())); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -345,17 +357,18 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberFunction FUNCTION_EXP = new NumberFunction() { |     public static final NumberFunction FUNCTION_EXP = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             NumberInterface maxError = params[0].getMaxError(); |             NumberInterface maxError = params[0].getMaxError(); | ||||||
|             int n = 0; |             int n = 0; | ||||||
|             if (params[0].signum() < 0) { |             if (params[0].signum() < 0) { | ||||||
|                 NumberInterface[] negatedParams = {params[0].negate()}; |                 NumberInterface[] negatedParams = {params[0].negate()}; | ||||||
|                 return fromInt(params[0].getClass(), 1).divide(applyInternal(negatedParams)); |                 return fromInt(params[0].getClass(), 1).divide(applyInternal(implementation, negatedParams)); | ||||||
|             } else { |             } else { | ||||||
|                 //We need n such that x^(n+1) * 3^ceil(x) <= maxError * (n+1)!. |                 //We need n such that x^(n+1) * 3^ceil(x) <= maxError * (n+1)!. | ||||||
|                 //right and left refer to lhs and rhs in the above inequality. |                 //right and left refer to lhs and rhs in the above inequality. | ||||||
| @ -382,7 +395,7 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public static final NumberOperator OP_CARET = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 2) { |     public static final NumberOperator OP_CARET = new NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 2) { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             NumberInterface zero = fromInt(params[0].getClass(), 0); |             NumberInterface zero = fromInt(params[0].getClass(), 0); | ||||||
|             return params.length == 2 |             return params.length == 2 | ||||||
|                     && !(params[0].compareTo(zero) == 0 |                     && !(params[0].compareTo(zero) == 0 | ||||||
| @ -390,8 +403,9 @@ public class StandardPlugin extends Plugin { | |||||||
|                     && !(params[0].signum() == -1 && params[1].fractionalPart().compareTo(zero) != 0); |                     && !(params[0].signum() == -1 && params[1].fractionalPart().compareTo(zero) != 0); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             NumberInterface zero = fromInt(params[0].getClass(), 0); |             NumberInterface zero = fromInt(params[0].getClass(), 0); | ||||||
|             if (params[0].compareTo(zero) == 0) |             if (params[0].compareTo(zero) == 0) | ||||||
|                 return zero; |                 return zero; | ||||||
| @ -399,12 +413,12 @@ public class StandardPlugin extends Plugin { | |||||||
|                 return fromInt(params[0].getClass(), 1); |                 return fromInt(params[0].getClass(), 1); | ||||||
|             //Detect integer bases: |             //Detect integer bases: | ||||||
|             if (params[0].fractionalPart().compareTo(fromInt(params[0].getClass(), 0)) == 0 |             if (params[0].fractionalPart().compareTo(fromInt(params[0].getClass(), 0)) == 0 | ||||||
|                     && FUNCTION_ABS.apply(params[1]).compareTo(fromInt(params[0].getClass(), Integer.MAX_VALUE)) < 0 |                     && FUNCTION_ABS.apply(implementation, params[1]).compareTo(fromInt(params[0].getClass(), Integer.MAX_VALUE)) < 0 | ||||||
|                     && FUNCTION_ABS.apply(params[1]).compareTo(fromInt(params[1].getClass(), 1)) >= 0) { |                     && FUNCTION_ABS.apply(implementation, params[1]).compareTo(fromInt(params[1].getClass(), 1)) >= 0) { | ||||||
|                 NumberInterface[] newParams = {params[0], params[1].fractionalPart()}; |                 NumberInterface[] newParams = {params[0], params[1].fractionalPart()}; | ||||||
|                 return params[0].intPow(params[1].floor().intValue()).multiply(applyInternal(newParams)); |                 return params[0].intPow(params[1].floor().intValue()).multiply(applyInternal(implementation, newParams)); | ||||||
|             } |             } | ||||||
|             return FUNCTION_EXP.apply(FUNCTION_LN.apply(FUNCTION_ABS.apply(params[0])).multiply(params[1])); |             return FUNCTION_EXP.apply(implementation, FUNCTION_LN.apply(implementation, FUNCTION_ABS.apply(implementation, params[0])).multiply(params[1])); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     /** |     /** | ||||||
| @ -412,15 +426,16 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionSin = new NumberFunction() { |     public final NumberFunction functionSin = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             NumberInterface pi = piFor(params[0].getClass()); |             NumberInterface pi = piFor(params[0].getClass()); | ||||||
|             NumberInterface twoPi = pi.multiply(fromInt(pi.getClass(), 2)); |             NumberInterface twoPi = pi.multiply(fromInt(pi.getClass(), 2)); | ||||||
|             NumberInterface theta = getSmallAngle(params[0], pi); |             NumberInterface theta = getSmallAngle(implementation, 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); | ||||||
| @ -428,7 +443,7 @@ public class StandardPlugin extends Plugin { | |||||||
|                 theta = pi.subtract(theta); |                 theta = pi.subtract(theta); | ||||||
|             } |             } | ||||||
|             //System.out.println(theta); |             //System.out.println(theta); | ||||||
|             return sinTaylor(theta); |             return sinTaylor(implementation, theta); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     /** |     /** | ||||||
| @ -436,13 +451,14 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionCos = new NumberFunction() { |     public final NumberFunction functionCos = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return functionSin.apply(piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) |             return functionSin.apply(implementation, piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) | ||||||
|                     .subtract(params[0])); |                     .subtract(params[0])); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -451,13 +467,14 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionTan = new NumberFunction() { |     public final NumberFunction functionTan = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return functionSin.apply(params[0]).divide(functionCos.apply(params[0])); |             return functionSin.apply(implementation, params[0]).divide(functionCos.apply(implementation, params[0])); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     /** |     /** | ||||||
| @ -465,13 +482,14 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionSec = new NumberFunction() { |     public final NumberFunction functionSec = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return fromInt(params[0].getClass(), 1).divide(functionCos.apply(params[0])); |             return fromInt(params[0].getClass(), 1).divide(functionCos.apply(implementation, params[0])); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     /** |     /** | ||||||
| @ -479,13 +497,14 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionCsc = new NumberFunction() { |     public final NumberFunction functionCsc = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return fromInt(params[0].getClass(), 1).divide(functionSin.apply(params[0])); |             return fromInt(params[0].getClass(), 1).divide(functionSin.apply(implementation, params[0])); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|     /** |     /** | ||||||
| @ -493,13 +512,14 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionCot = new NumberFunction() { |     public final NumberFunction functionCot = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return functionCos.apply(params[0]).divide(functionSin.apply(params[0])); |             return functionCos.apply(implementation, params[0]).divide(functionSin.apply(implementation, params[0])); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @ -508,23 +528,24 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionArcsin = new NumberFunction() { |     public final NumberFunction functionArcsin = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1 |             return params.length == 1 | ||||||
|                     && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0; |                     && FUNCTION_ABS.apply(implementation, params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             if (FUNCTION_ABS.apply(params[0]).compareTo(new NaiveNumber(0.8).promoteTo(params[0].getClass())) >= 0) { |             if (FUNCTION_ABS.apply(implementation, 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])))}; |                 NumberInterface[] newParams = {FUNCTION_SQRT.apply(implementation, fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))}; | ||||||
|                 return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) |                 return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) | ||||||
|                         .subtract(applyInternal(newParams)).multiply(fromInt(params[0].getClass(), params[0].signum())); |                         .subtract(applyInternal(implementation, newParams)).multiply(fromInt(params[0].getClass(), params[0].signum())); | ||||||
|             } |             } | ||||||
|             NumberInterface currentTerm = params[0], sum = currentTerm, |             NumberInterface currentTerm = params[0], sum = currentTerm, | ||||||
|                     multiplier = currentTerm.multiply(currentTerm), summandBound = sum.getMaxError().multiply(fromInt(sum.getClass(), 1).subtract(multiplier)), |                     multiplier = currentTerm.multiply(currentTerm), summandBound = sum.getMaxError().multiply(fromInt(sum.getClass(), 1).subtract(multiplier)), | ||||||
|                     power = currentTerm, coefficient = fromInt(params[0].getClass(), 1); |                     power = currentTerm, coefficient = fromInt(params[0].getClass(), 1); | ||||||
|             int exponent = 1; |             int exponent = 1; | ||||||
|             while (FUNCTION_ABS.apply(currentTerm).compareTo(summandBound) > 0) { |             while (FUNCTION_ABS.apply(implementation, currentTerm).compareTo(summandBound) > 0) { | ||||||
|                 exponent += 2; |                 exponent += 2; | ||||||
|                 power = power.multiply(multiplier); |                 power = power.multiply(multiplier); | ||||||
|                 coefficient = coefficient.multiply(fromInt(params[0].getClass(), exponent - 2)) |                 coefficient = coefficient.multiply(fromInt(params[0].getClass(), exponent - 2)) | ||||||
| @ -541,14 +562,15 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionArccos = new NumberFunction() { |     public final NumberFunction functionArccos = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0; |             return params.length == 1 && FUNCTION_ABS.apply(implementation, params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) |             return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) | ||||||
|                     .subtract(functionArcsin.apply(params)); |                     .subtract(functionArcsin.apply(implementation, params)); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @ -557,14 +579,15 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionArccsc = new NumberFunction() { |     public final NumberFunction functionArccsc = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0; |             return params.length == 1 && FUNCTION_ABS.apply(implementation, params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])}; |             NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])}; | ||||||
|             return functionArcsin.apply(reciprocalParamArr); |             return functionArcsin.apply(implementation, reciprocalParamArr); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @ -573,14 +596,15 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionArcsec = new NumberFunction() { |     public final NumberFunction functionArcsec = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0; |             return params.length == 1 && FUNCTION_ABS.apply(implementation, params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])}; |             NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])}; | ||||||
|             return functionArccos.apply(reciprocalParamArr); |             return functionArccos.apply(implementation, reciprocalParamArr); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @ -589,20 +613,21 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionArctan = new NumberFunction() { |     public final NumberFunction functionArctan = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             if (params[0].signum() == -1) { |             if (params[0].signum() == -1) { | ||||||
|                 NumberInterface[] negatedParams = {params[0].negate()}; |                 NumberInterface[] negatedParams = {params[0].negate()}; | ||||||
|                 return applyInternal(negatedParams).negate(); |                 return applyInternal(implementation, negatedParams).negate(); | ||||||
|             } |             } | ||||||
|             if (params[0].compareTo(fromInt(params[0].getClass(), 1)) > 0) { |             if (params[0].compareTo(fromInt(params[0].getClass(), 1)) > 0) { | ||||||
|                 NumberInterface[] reciprocalParams = {fromInt(params[0].getClass(), 1).divide(params[0])}; |                 NumberInterface[] reciprocalParams = {fromInt(params[0].getClass(), 1).divide(params[0])}; | ||||||
|                 return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) |                 return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) | ||||||
|                         .subtract(applyInternal(reciprocalParams)); |                         .subtract(applyInternal(implementation, reciprocalParams)); | ||||||
|             } |             } | ||||||
|             if (params[0].compareTo(fromInt(params[0].getClass(), 1)) == 0) { |             if (params[0].compareTo(fromInt(params[0].getClass(), 1)) == 0) { | ||||||
|                 return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 4)); |                 return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 4)); | ||||||
| @ -610,12 +635,12 @@ public class StandardPlugin extends Plugin { | |||||||
|             if (params[0].compareTo(new NaiveNumber(0.9).promoteTo(params[0].getClass())) >= 0) { |             if (params[0].compareTo(new NaiveNumber(0.9).promoteTo(params[0].getClass())) >= 0) { | ||||||
|                 NumberInterface[] newParams = {params[0].multiply(fromInt(params[0].getClass(), 2)) |                 NumberInterface[] newParams = {params[0].multiply(fromInt(params[0].getClass(), 2)) | ||||||
|                         .divide(fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))}; |                         .divide(fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))}; | ||||||
|                 return applyInternal(newParams).divide(fromInt(params[0].getClass(), 2)); |                 return applyInternal(implementation, newParams).divide(fromInt(params[0].getClass(), 2)); | ||||||
|             } |             } | ||||||
|             NumberInterface currentPower = params[0], currentTerm = currentPower, sum = currentTerm, |             NumberInterface currentPower = params[0], currentTerm = currentPower, sum = currentTerm, | ||||||
|                     maxError = params[0].getMaxError(), multiplier = currentPower.multiply(currentPower).negate(); |                     maxError = params[0].getMaxError(), multiplier = currentPower.multiply(currentPower).negate(); | ||||||
|             int n = 1; |             int n = 1; | ||||||
|             while (FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0) { |             while (FUNCTION_ABS.apply(implementation, currentTerm).compareTo(maxError) > 0) { | ||||||
|                 n += 2; |                 n += 2; | ||||||
|                 currentPower = currentPower.multiply(multiplier); |                 currentPower = currentPower.multiply(multiplier); | ||||||
|                 currentTerm = currentPower.divide(fromInt(currentPower.getClass(), n)); |                 currentTerm = currentPower.divide(fromInt(currentPower.getClass(), n)); | ||||||
| @ -630,14 +655,14 @@ public class StandardPlugin extends Plugin { | |||||||
|      */ |      */ | ||||||
|     public final NumberFunction functionArccot = new NumberFunction() { |     public final NumberFunction functionArccot = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 1; |             return params.length == 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) |             return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2)) | ||||||
|                     .subtract(functionArctan.apply(params)); |                     .subtract(functionArctan.apply(implementation, params)); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @ -690,7 +715,7 @@ public class StandardPlugin extends Plugin { | |||||||
|      * @param x where the series is evaluated. |      * @param x where the series is evaluated. | ||||||
|      * @return the value of the series |      * @return the value of the series | ||||||
|      */ |      */ | ||||||
|     private static NumberInterface sinTaylor(NumberInterface x) { |     private static NumberInterface sinTaylor(NumberImplementation implementation, NumberInterface x) { | ||||||
|         NumberInterface power = x, multiplier = x.multiply(x).negate(), currentTerm = x, sum = x; |         NumberInterface power = x, multiplier = x.multiply(x).negate(), currentTerm = x, sum = x; | ||||||
|         NumberInterface maxError = x.getMaxError(); |         NumberInterface maxError = x.getMaxError(); | ||||||
|         int n = 1; |         int n = 1; | ||||||
| @ -699,7 +724,7 @@ public class StandardPlugin extends Plugin { | |||||||
|             power = power.multiply(multiplier); |             power = power.multiply(multiplier); | ||||||
|             currentTerm = power.divide(factorial(x.getClass(), n)); |             currentTerm = power.divide(factorial(x.getClass(), n)); | ||||||
|             sum = sum.add(currentTerm); |             sum = sum.add(currentTerm); | ||||||
|         } while (FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0); |         } while (FUNCTION_ABS.apply(implementation, currentTerm).compareTo(maxError) > 0); | ||||||
|         return sum; |         return sum; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -709,10 +734,10 @@ public class StandardPlugin extends Plugin { | |||||||
|      * @param phi an angle (in radians). |      * @param phi an angle (in radians). | ||||||
|      * @return theta in [0, 2pi) that differs from phi by a multiple of 2pi. |      * @return theta in [0, 2pi) that differs from phi by a multiple of 2pi. | ||||||
|      */ |      */ | ||||||
|     private static NumberInterface getSmallAngle(NumberInterface phi, NumberInterface pi) { |     private static NumberInterface getSmallAngle(NumberImplementation implementation, NumberInterface phi, NumberInterface pi) { | ||||||
|         NumberInterface twoPi = pi.multiply(fromInt(pi.getClass(), 2)); |         NumberInterface twoPi = pi.multiply(fromInt(pi.getClass(), 2)); | ||||||
|         NumberInterface theta = FUNCTION_ABS.apply(phi).subtract(twoPi |         NumberInterface theta = FUNCTION_ABS.apply(implementation, phi).subtract(twoPi | ||||||
|                 .multiply(FUNCTION_ABS.apply(phi).divide(twoPi).floor())); //Now theta is in [0, 2pi). |                 .multiply(FUNCTION_ABS.apply(implementation, phi).divide(twoPi).floor())); //Now theta is in [0, 2pi). | ||||||
|         if (phi.signum() < 0) { |         if (phi.signum() < 0) { | ||||||
|             theta = twoPi.subtract(theta); |             theta = twoPi.subtract(theta); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -3,6 +3,8 @@ package org.nwapw.abacus.tree; | |||||||
| import org.nwapw.abacus.Abacus; | import org.nwapw.abacus.Abacus; | ||||||
| import org.nwapw.abacus.function.*; | import org.nwapw.abacus.function.*; | ||||||
| import org.nwapw.abacus.number.NumberInterface; | import org.nwapw.abacus.number.NumberInterface; | ||||||
|  | import org.nwapw.abacus.number.PromotionManager; | ||||||
|  | import org.nwapw.abacus.number.PromotionResult; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * A reducer implementation that turns a tree into a single number. |  * A reducer implementation that turns a tree into a single number. | ||||||
| @ -26,19 +28,22 @@ public class NumberReducer implements Reducer<NumberInterface> { | |||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public NumberInterface reduceNode(TreeNode node, Object... children) { |     public NumberInterface reduceNode(TreeNode node, Object... children) { | ||||||
|  |         PromotionManager manager = abacus.getPromotionManager(); | ||||||
|         if (node instanceof NumberNode) { |         if (node instanceof NumberNode) { | ||||||
|             return abacus.numberFromString(((NumberNode) node).getNumber()); |             return abacus.getNumberImplementation().instanceForString(((NumberNode) node).getNumber()); | ||||||
|         } else if(node instanceof VariableNode) { |         } else if(node instanceof VariableNode) { | ||||||
|             return abacus.numberFromString("0"); |             return abacus.getNumberImplementation().instanceForString("0"); | ||||||
|         } else if (node instanceof NumberBinaryNode) { |         } else if (node instanceof NumberBinaryNode) { | ||||||
|             NumberInterface left = (NumberInterface) children[0]; |             NumberInterface left = (NumberInterface) children[0]; | ||||||
|             NumberInterface right = (NumberInterface) children[1]; |             NumberInterface right = (NumberInterface) children[1]; | ||||||
|             NumberOperator operator = abacus.getPluginManager().operatorFor(((BinaryNode) node).getOperation()); |             NumberOperator operator = abacus.getPluginManager().operatorFor(((BinaryNode) node).getOperation()); | ||||||
|             return operator.apply(left, right); |             PromotionResult result = manager.promote(left, right); | ||||||
|  |             if(result == null) return null; | ||||||
|  |             return operator.apply(result.getPromotedTo(), result.getItems()); | ||||||
|         } else if (node instanceof NumberUnaryNode) { |         } else if (node instanceof NumberUnaryNode) { | ||||||
|             NumberInterface child = (NumberInterface) children[0]; |             NumberInterface child = (NumberInterface) children[0]; | ||||||
|             NumberOperator operator = abacus.getPluginManager().operatorFor(((UnaryNode) node).getOperation()); |             NumberOperator operator = abacus.getPluginManager().operatorFor(((UnaryNode) node).getOperation()); | ||||||
|             return operator.apply(child); |             return operator.apply(abacus.getPluginManager().interfaceImplementationFor(child.getClass()), child); | ||||||
|         } else if (node instanceof FunctionNode) { |         } else if (node instanceof FunctionNode) { | ||||||
|             NumberInterface[] convertedChildren = new NumberInterface[children.length]; |             NumberInterface[] convertedChildren = new NumberInterface[children.length]; | ||||||
|             for (int i = 0; i < convertedChildren.length; i++) { |             for (int i = 0; i < convertedChildren.length; i++) { | ||||||
| @ -46,7 +51,9 @@ public class NumberReducer implements Reducer<NumberInterface> { | |||||||
|             } |             } | ||||||
|             NumberFunction function = abacus.getPluginManager().functionFor(((FunctionNode) node).getCallTo()); |             NumberFunction function = abacus.getPluginManager().functionFor(((FunctionNode) node).getCallTo()); | ||||||
|             if (function == null) return null; |             if (function == null) return null; | ||||||
|             return function.apply(convertedChildren); |             PromotionResult result = manager.promote(convertedChildren); | ||||||
|  |             if(result == null) return null; | ||||||
|  |             return function.apply(result.getPromotedTo(), result.getItems()); | ||||||
|         } else if (node instanceof TreeValueFunctionNode){ |         } else if (node instanceof TreeValueFunctionNode){ | ||||||
|             CallNode callNode = (CallNode) node; |             CallNode callNode = (CallNode) node; | ||||||
|             TreeNode[] realChildren = new TreeNode[callNode.getChildren().size()]; |             TreeNode[] realChildren = new TreeNode[callNode.getChildren().size()]; | ||||||
| @ -56,19 +63,19 @@ public class NumberReducer implements Reducer<NumberInterface> { | |||||||
|             TreeValueFunction function = |             TreeValueFunction function = | ||||||
|                     abacus.getPluginManager().treeValueFunctionFor(callNode.getCallTo()); |                     abacus.getPluginManager().treeValueFunctionFor(callNode.getCallTo()); | ||||||
|             if(function == null) return null; |             if(function == null) return null; | ||||||
|             return function.applyWithReducer(this, realChildren); |             return function.applyWithReducer(abacus.getNumberImplementation(), this, realChildren); | ||||||
|         } else if (node instanceof TreeValueBinaryNode) { |         } else if (node instanceof TreeValueBinaryNode) { | ||||||
|             BinaryNode binaryNode = (BinaryNode) node; |             BinaryNode binaryNode = (BinaryNode) node; | ||||||
|             TreeValueOperator operator = abacus.getPluginManager() |             TreeValueOperator operator = abacus.getPluginManager() | ||||||
|                     .treeValueOperatorFor(binaryNode.getOperation()); |                     .treeValueOperatorFor(binaryNode.getOperation()); | ||||||
|             if(operator == null) return null; |             if(operator == null) return null; | ||||||
|             return operator.applyWithReducer(this, binaryNode.getLeft(), binaryNode.getRight()); |             return operator.applyWithReducer(abacus.getNumberImplementation(), this, binaryNode.getLeft(), binaryNode.getRight()); | ||||||
|         } else if(node instanceof TreeValueUnaryNode) { |         } else if(node instanceof TreeValueUnaryNode) { | ||||||
|             UnaryNode unaryNode = (UnaryNode) node; |             UnaryNode unaryNode = (UnaryNode) node; | ||||||
|             TreeValueOperator operator = abacus.getPluginManager() |             TreeValueOperator operator = abacus.getPluginManager() | ||||||
|                     .treeValueOperatorFor(unaryNode.getOperation()); |                     .treeValueOperatorFor(unaryNode.getOperation()); | ||||||
|             if(operator == null) return null; |             if(operator == null) return null; | ||||||
|             return operator.applyWithReducer(this, unaryNode.getApplyTo()); |             return operator.applyWithReducer(abacus.getNumberImplementation(), this, unaryNode.getApplyTo()); | ||||||
|         } |         } | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| package org.nwapw.abacus.function.applicable | package org.nwapw.abacus.function.applicable | ||||||
| 
 | 
 | ||||||
|  | import org.nwapw.abacus.plugin.NumberImplementation | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * A class that can be applied to arguments. |  * A class that can be applied to arguments. | ||||||
|  * |  * | ||||||
| @ -15,7 +17,7 @@ interface Applicable<in T : Any, out O : Any> { | |||||||
|      * @param params the parameter array to verify for compatibility. |      * @param params the parameter array to verify for compatibility. | ||||||
|      * @return whether the array can be used with applyInternal. |      * @return whether the array can be used with applyInternal. | ||||||
|      */ |      */ | ||||||
|     fun matchesParams(params: Array<out T>): Boolean |     fun matchesParams(implementation: NumberImplementation, params: Array<out T>): Boolean | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Applies the applicable object to the given parameters, |      * Applies the applicable object to the given parameters, | ||||||
| @ -23,7 +25,7 @@ interface Applicable<in T : Any, out O : Any> { | |||||||
|      * @param params the parameters to apply to. |      * @param params the parameters to apply to. | ||||||
|      * @return the result of the application. |      * @return the result of the application. | ||||||
|      */ |      */ | ||||||
|     fun applyInternal(params: Array<out T>): O? |     fun applyInternal(implementation: NumberImplementation, params: Array<out T>): O? | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * If the parameters can be used with this applicable, returns |      * If the parameters can be used with this applicable, returns | ||||||
| @ -32,9 +34,9 @@ interface Applicable<in T : Any, out O : Any> { | |||||||
|      * @param params the parameters to apply to. |      * @param params the parameters to apply to. | ||||||
|      * @return the result of the operation, or null if parameters do not match. |      * @return the result of the operation, or null if parameters do not match. | ||||||
|      */ |      */ | ||||||
|     fun apply(vararg params: T): O? { |     fun apply(implementation: NumberImplementation, vararg params: T): O? { | ||||||
|         if (!matchesParams(params)) return null |         if (!matchesParams(implementation, params)) return null | ||||||
|         return applyInternal(params) |         return applyInternal(implementation, params) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @ -1,5 +1,6 @@ | |||||||
| package org.nwapw.abacus.function.applicable | package org.nwapw.abacus.function.applicable | ||||||
| 
 | 
 | ||||||
|  | import org.nwapw.abacus.plugin.NumberImplementation | ||||||
| import org.nwapw.abacus.tree.Reducer | import org.nwapw.abacus.tree.Reducer | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -18,7 +19,7 @@ interface ReducerApplicable<in T : Any, out O : Any, in R : Any> { | |||||||
|      * given parameters. |      * given parameters. | ||||||
|      * @param params the parameters to check. |      * @param params the parameters to check. | ||||||
|      */ |      */ | ||||||
|     fun matchesParams(params: Array<out T>): Boolean |     fun matchesParams(implementation: NumberImplementation, params: Array<out T>): Boolean | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Applies this applicable to the given arguments, and reducer. |      * Applies this applicable to the given arguments, and reducer. | ||||||
| @ -26,7 +27,7 @@ interface ReducerApplicable<in T : Any, out O : Any, in R : Any> { | |||||||
|      * @param params the arguments to apply to. |      * @param params the arguments to apply to. | ||||||
|      * @return the result of the application. |      * @return the result of the application. | ||||||
|      */ |      */ | ||||||
|     fun applyWithReducerInternal(reducer: Reducer<R>, params: Array<out T>): O? |     fun applyWithReducerInternal(implementation: NumberImplementation, reducer: Reducer<R>, params: Array<out T>): O? | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Applies this applicable to the given arguments, and reducer, |      * Applies this applicable to the given arguments, and reducer, | ||||||
| @ -35,9 +36,9 @@ interface ReducerApplicable<in T : Any, out O : Any, in R : Any> { | |||||||
|      * @param params the arguments to apply to. |      * @param params the arguments to apply to. | ||||||
|      * @return the result of the application, or null if the arguments are incompatible. |      * @return the result of the application, or null if the arguments are incompatible. | ||||||
|      */ |      */ | ||||||
|     fun applyWithReducer(reducer: Reducer<R>, vararg params: T): O? { |     fun applyWithReducer(implementation: NumberImplementation, reducer: Reducer<R>, vararg params: T): O? { | ||||||
|         if (!matchesParams(params)) return null |         if (!matchesParams(implementation, params)) return null | ||||||
|         return applyWithReducerInternal(reducer, params) |         return applyWithReducerInternal(implementation, reducer, params) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @ -25,15 +25,15 @@ class PromotionManager(val abacus: Abacus) { | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun promote(vararg numbers: NumberInterface): Array<NumberInterface>? { |     fun promote(vararg numbers: NumberInterface): PromotionResult? { | ||||||
|         val pluginManager = abacus.pluginManager |         val pluginManager = abacus.pluginManager | ||||||
|         val implementations = numbers.map { pluginManager.interfaceImplementationFor(it.javaClass) } |         val implementations = numbers.map { pluginManager.interfaceImplementationFor(it.javaClass) } | ||||||
|         val highestPriority = implementations.sortedBy { it.priority }.last() |         val highestPriority = implementations.sortedBy { it.priority }.last() | ||||||
|         return numbers.map { |         return PromotionResult(items = numbers.map { | ||||||
|             if(it.javaClass == highestPriority.implementation) it |             if(it.javaClass == highestPriority.implementation) it | ||||||
|             else getPathBetween(pluginManager.interfaceImplementationFor(it.javaClass), highestPriority) |             else getPathBetween(pluginManager.interfaceImplementationFor(it.javaClass), highestPriority) | ||||||
|                     ?.promote(it) ?: return null |                     ?.promote(it) ?: return null | ||||||
|         }.toTypedArray() |         }.toTypedArray(), promotedTo = highestPriority) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @ -0,0 +1,5 @@ | |||||||
|  | package org.nwapw.abacus.number | ||||||
|  | 
 | ||||||
|  | import org.nwapw.abacus.plugin.NumberImplementation | ||||||
|  | 
 | ||||||
|  | data class PromotionResult(val promotedTo: NumberImplementation, val items: Array<NumberInterface>) | ||||||
| @ -9,6 +9,7 @@ import org.nwapw.abacus.function.*; | |||||||
| import org.nwapw.abacus.lexing.pattern.Match; | import org.nwapw.abacus.lexing.pattern.Match; | ||||||
| import org.nwapw.abacus.number.NumberInterface; | import org.nwapw.abacus.number.NumberInterface; | ||||||
| import org.nwapw.abacus.parsing.LexerTokenizer; | import org.nwapw.abacus.parsing.LexerTokenizer; | ||||||
|  | import org.nwapw.abacus.plugin.NumberImplementation; | ||||||
| import org.nwapw.abacus.plugin.Plugin; | import org.nwapw.abacus.plugin.Plugin; | ||||||
| import org.nwapw.abacus.tree.TokenType; | import org.nwapw.abacus.tree.TokenType; | ||||||
| 
 | 
 | ||||||
| @ -20,12 +21,12 @@ public class TokenizerTests { | |||||||
|     private static LexerTokenizer lexerTokenizer = new LexerTokenizer(); |     private static LexerTokenizer lexerTokenizer = new LexerTokenizer(); | ||||||
|     private static NumberFunction subtractFunction = new NumberFunction() { |     private static NumberFunction subtractFunction = new NumberFunction() { | ||||||
|         @Override |         @Override | ||||||
|         public boolean matchesParams(NumberInterface[] params) { |         public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params.length == 2; |             return params.length == 2; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public NumberInterface applyInternal(NumberInterface[] params) { |         public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|             return params[0].subtract(params[1]); |             return params[0].subtract(params[1]); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -36,26 +37,26 @@ public class TokenizerTests { | |||||||
|                     0) { |                     0) { | ||||||
| 
 | 
 | ||||||
|                 @Override |                 @Override | ||||||
|                 public boolean matchesParams(NumberInterface[] params) { |                 public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|                     return true; |                     return true; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @Override |                                 @Override | ||||||
|                 public NumberInterface applyInternal(NumberInterface[] params) { |                 public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|                     return subtractFunction.apply(params); |                     return subtractFunction.apply(implementation, params); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|             registerOperator("-", new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, |             registerOperator("-", new NumberOperator(OperatorAssociativity.LEFT, OperatorType.BINARY_INFIX, | ||||||
|                     0) { |                     0) { | ||||||
| 
 | 
 | ||||||
|                 @Override |                 @Override | ||||||
|                 public boolean matchesParams(NumberInterface[] params) { |                 public boolean matchesParams(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|                     return true; |                     return true; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @Override |                                 @Override | ||||||
|                 public NumberInterface applyInternal(NumberInterface[] params) { |                 public NumberInterface applyInternal(NumberImplementation implementation, NumberInterface[] params) { | ||||||
|                     return subtractFunction.apply(params); |                     return subtractFunction.apply(implementation, params); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|             registerFunction("subtract", subtractFunction); |             registerFunction("subtract", subtractFunction); | ||||||
|  | |||||||
| @ -14,8 +14,7 @@ import org.nwapw.abacus.Abacus; | |||||||
| import org.nwapw.abacus.config.Configuration; | import org.nwapw.abacus.config.Configuration; | ||||||
| import org.nwapw.abacus.function.Documentation; | import org.nwapw.abacus.function.Documentation; | ||||||
| import org.nwapw.abacus.function.DocumentationType; | import org.nwapw.abacus.function.DocumentationType; | ||||||
| import org.nwapw.abacus.number.ComputationInterruptedException; | import org.nwapw.abacus.number.*; | ||||||
| import org.nwapw.abacus.number.NumberInterface; |  | ||||||
| import org.nwapw.abacus.plugin.ClassFinder; | import org.nwapw.abacus.plugin.ClassFinder; | ||||||
| import org.nwapw.abacus.plugin.PluginListener; | import org.nwapw.abacus.plugin.PluginListener; | ||||||
| import org.nwapw.abacus.plugin.PluginManager; | import org.nwapw.abacus.plugin.PluginManager; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user