package jcgp.backend.function; import jcgp.backend.population.Connection; public class DoubleArithmetic extends FunctionSet { public final static double DIVISION_LIMIT = 0.0001; public DoubleArithmetic() { name = "Double Arithmetic"; functionList = new Function[]{ new Absolute(), new SquareRoot(), new Reciprocal(), new Sine(), new Cosine(), new Tangent(), new Exponential(), new HyperbolicSine(), new HyperbolicCosine(), new HyperbolicTangent(), new NaturalLog(), new LogBaseTen(), new SineAB(), new CosineAB(), new Hypotenuse(), new Power(), new Addition(), new Subtraction(), new Multiplication(), new Division()}; enableAll(); } /** * Absolute returns the positive value of input 0. * * @see Math.abs() */ public static class Absolute extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return Math.abs(in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Absolute"; } } /** * Protected square root function, returns the square root of the absolute * value of input 0. * * @see Math.abs(), Math.sqrt() */ public static class SquareRoot extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return Math.sqrt(Math.abs(in0)); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Square root"; } } /** * Protected reciprocal function, returns (1 / input 0). If input 0 is less than * {@link DoubleArithmetic.}DIVISION_LIMIT, this returns it unchanged. * */ public static class Reciprocal extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return in0 < DIVISION_LIMIT ? in0 : (1 / in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Reciprocal"; } } /** * Sine function, in radians. * * @see Math.sin() */ public static class Sine extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return Math.sin(in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Sin"; } } /** * Cosine function, in radians. * * @see Math.cos() */ public static class Cosine extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return Math.cos(in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Cos"; } } /** * Protected tangent function, in radians. Returns the tangent of input 0. * If input 0 is less than {@link DoubleArithmetic.}DIVISION_LIMIT, * this returns it unchanged. * * @see Math.tan() */ public static class Tangent extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return in0 < DIVISION_LIMIT ? in0 : Math.tan(in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Tan"; } } /** * Exponential function. Returns the exponential of input 0. * * @see Math.exp() */ public static class Exponential extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return Math.exp(in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Exp"; } } /** * Returns the hyperbolic sine of input 0. * * @see Math.sinh() */ public static class HyperbolicSine extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return Math.sinh(in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Sinh"; } } /** * Returns the hyperbolic cosine of input 0. * * @see Math.cosh() */ public static class HyperbolicCosine extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return Math.cosh(in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Cosh"; } } /** * Returns the hyperbolic tangent of input 0. * * @see Math.tanh() */ public static class HyperbolicTangent extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return Math.tanh(in0); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Tanh"; } } /** * Protected natural log function. Returns the natural log of the absolute * value of input 0. If input 0 is less than {@link DoubleArithmetic.}DIVISION_LIMIT, * this returns it unchanged. * * @see Math.log(), Math.abs() */ public static class NaturalLog extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return in0 < DIVISION_LIMIT ? in0 : Math.log(Math.abs(in0)); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Ln"; } } /** * Protected log base 10 function. Returns the log to base 10 the absolute * value of input 0. If input 0 is less than {@link DoubleArithmetic.}DIVISION_LIMIT, * this returns it unchanged. * * @see Math.log10(), Math.abs() */ public static class LogBaseTen extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); return in0 < DIVISION_LIMIT ? in0 : Math.log10(Math.abs(in0)); } } @Override public int getArity() { return 1; } @Override public String getName() { return "Log"; } } /** * Sine of sum. Returns the sine of the sum of inputs 0 and 1. * * @see Math.sin() */ public static class SineAB extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); Double in1 = ((Double) connections[1].getValue()); return Math.sin(in0 + in1); } } @Override public int getArity() { return 2; } @Override public String getName() { return "Sin(a+b)"; } } /** * Cosine of sum. Returns the cosine of the sum of inputs 0 and 1. * * @see Math.cos() */ public static class CosineAB extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); Double in1 = ((Double) connections[1].getValue()); return Math.cos(in0 + in1); } } @Override public int getArity() { return 2; } @Override public String getName() { return "Cos(a+b)"; } } /** * Hypotenuse function. Returns the square root of input 0 squared * plus input 1 squared. * * @see Math.hypot() */ public static class Hypotenuse extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); Double in1 = ((Double) connections[1].getValue()); return Math.hypot(in0, in1); } } @Override public int getArity() { return 2; } @Override public String getName() { return "Hypotenuse"; } } /** * Power function. Returns the absolute value of input 0 to the power of input 1. * * @see Math.abs(), Math.pow */ public static class Power extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); Double in1 = ((Double) connections[1].getValue()); return Math.pow(Math.abs(in0), in1); } } @Override public int getArity() { return 2; } @Override public String getName() { return "Power"; } } /** * Addition returns the sum of inputs 0 and 1. * */ public static class Addition extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); Double in1 = ((Double) connections[1].getValue()); return in0 + in1; } } @Override public int getArity() { return 2; } @Override public String getName() { return "Addition"; } } /** * Subtraction returns the difference between inputs 0 and 1. * */ public static class Subtraction extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); Double in1 = ((Double) connections[1].getValue()); return in0 - in1; } } @Override public int getArity() { return 2; } @Override public String getName() { return "Subtraction"; } } /** * Multiplication returns the product of inputs 0 and 1. * */ public static class Multiplication extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); Double in1 = ((Double) connections[1].getValue()); return in0 * in1; } } @Override public int getArity() { return 2; } @Override public String getName() { return "Multiplication"; } } /** * Protected division, returns the quotient of input 0 (the dividend) and input 1 (the divisor). * If the divisor is less than {@link DoubleArithmetic.}DIVISION_LIMIT, this returns the it unchanged. * */ public static class Division extends Function { @Override public Double run(Connection... connections) { if (connections.length < getArity()) { throw new IllegalArgumentException(getName() + " received " + connections.length + " connections but arity is " + getArity() + "."); } else { Double in0 = ((Double) connections[0].getValue()); Double in1 = ((Double) connections[1].getValue()); return in1 < DIVISION_LIMIT ? in0 : (in0 / in1); } } @Override public int getArity() { return 2; } @Override public String getName() { return "Division"; } } }