package de.congrace.exp4j;
public class BultinFunction extends CustomFunction {
/**
* Every standard function in this library.
*
* @author Kristian
*/
public enum StandardFunctions {
ABS(1),
ACOS(1),
ASIN(1),
ATAN(1),
CBRT(1),
CEIL(1),
COS(1),
COSH(1),
EXP(1),
EXPM1(1),
FLOOR(1),
LOG(1),
POW(2),
SIN(1),
SINH(1),
SQRT(1),
TAN(1),
TANH(1),
LERP(3),
NORM(3),
MAX(2),
MIN(2),
ROUND(1);
final int argCount;
private StandardFunctions(int argCount) {
this.argCount = argCount;
}
/**
* Retrieves the call name of this function.
* @return Function name.
*/
public String getFunctionName() {
return this.name().toLowerCase();
}
/**
* Retrieves the number of arguments this function uses.
* @return Number of arguments.
*/
public int getArgCount() {
return argCount;
}
}
// Our standard function type
final private StandardFunctions standard;
public BultinFunction(String name) throws InvalidCustomFunctionException {
super(name.toLowerCase());
try {
this.standard = StandardFunctions.valueOf(name.toUpperCase());
this.argc = standard.getArgCount();
} catch (IllegalArgumentException e) {
throw new InvalidCustomFunctionException("No such standard function exists.");
}
}
public BultinFunction(StandardFunctions standard) throws InvalidCustomFunctionException {
super(standard.getFunctionName());
this.standard = standard;
this.argc = standard.getArgCount();
}
@Override
public double applyFunction(double... args) {
// A big old switch statement. Uses less memory/space.
switch (standard) {
case ABS:
return Math.abs(args[0]);
case ACOS:
return Math.acos(args[0]);
case ASIN:
return Math.asin(args[0]);
case ATAN:
return Math.atan(args[0]);
case CBRT:
return Math.cbrt(args[0]);
case CEIL:
return Math.ceil(args[0]);
case COS:
return Math.cos(args[0]);
case COSH:
return Math.cosh(args[0]);
case EXP:
return Math.exp(args[0]);
case EXPM1:
return Math.expm1(args[0]);
case FLOOR:
return Math.floor(args[0]);
case LOG:
return Math.log(args[0]);
case POW:
return Math.pow(args[0], args[1]);
case MAX:
return Math.max(args[0], args[1]);
case MIN:
return Math.min(args[0], args[1]);
case LERP:
return lerp(args[0], args[1], args[2]);
case NORM:
return norm(args[0], args[1], args[2]);
case ROUND:
return Math.round(args[0]);
case SIN:
return Math.sin(args[0]);
case SINH:
return Math.sinh(args[0]);
case SQRT:
return Math.sqrt(args[0]);
case TAN:
return Math.tan(args[0]);
case TANH:
return Math.tanh(args[0]);
default:
throw new IllegalStateException("Illegal function name detected.");
}
}
private static double lerp(double start, double stop, double amount) {
return start + (stop - start) * amount;
}
private static double norm(double start, double stop, double value) {
return (value - start) / (stop - start);
}
public StandardFunctions getStandard() {
return standard;
}
}