/* Operators.java * J Scott Cameron * creates functions and fitness function * specific to Symbolic regression */ import java.util.*; import GPPair; import GPNode; import GPVariableNode; import GPPopulation; public class Operators implements GPFunctionTemplate { /* vectors to hold the function/variable names */ private Vector binaryFunctions, unaryFunctions, variables; public Double x; public Random random; private double xMin; private double xMax; private GPNode test; /* default constructorthat initializes all the important vectors */ public Operators() { x = new Double(0); xMin = -10; xMax = 10; /*create binary functions vector *comment/uncomment fucntions as needed*/ binaryFunctions = new Vector(); binaryFunctions.add(new GPPair("add","+")); binaryFunctions.add(new GPPair("subtract","-")); binaryFunctions.add(new GPPair("multiply","*")); //binaryFunctions.add(new GPPair("divide","/")); //binaryFunctions.add(new GPPair("mod","%")); //binaryFunctions.add(new GPPair("pow","Pow")); /*create unary functions vector *comment/uncomment fucntions as needed*/ unaryFunctions = new Vector(); unaryFunctions.add(new GPPair("neg","Neg")); //unaryFunctions.add(new GPPair("sqrt","Sqrt")); //unaryFunctions.add(new GPPair("sin","Sin")); //unaryFunctions.add(new GPPair("cos","Cos")); //unaryFunctions.add(new GPPair("tan","Tan")); //unaryFunctions.add(new GPPair("abs","Abs")); //unaryFunctions.add(new GPPair("log","Log")); /* create variables vector */ variables = new Vector(); variables.add(new GPPair("x","x")); random = new Random(); } /* returns the vector of binary function */ public Vector getBinaryFunctions() { return binaryFunctions; } /* returns the vector of unary functions */ public Vector getUnaryFunctions() { return unaryFunctions; } /* returns the vector of variables */ public Vector getVariables() { return variables; } /* Binary Function for addition */ public Double add(Double a, Double b) { return new Double(a.doubleValue() + b.doubleValue()); } /* Binary Function for subtraction */ public Double subtract(Double a, Double b) { return new Double(a.doubleValue() - b.doubleValue()); } /* Binary Function for multiplication */ public Double multiply(Double a, Double b) { return new Double(a.doubleValue() * b.doubleValue()); } /* Binary Function for division */ public Double divide(Double a, Double b) { if (b.doubleValue() == 0) b= new Double(.0001); return new Double(a.doubleValue() / b.doubleValue()); } /* Binary Function for modulo arithmetic */ public Double mod(Double a, Double b) { if (b.doubleValue() == 0) b= new Double(.0001); return new Double(a.doubleValue() % b.doubleValue()); } /* Binary Function for powers */ public Double pow(Double a, Double b) { return new Double(Math.pow(a.doubleValue(),b.doubleValue())); } /* Unary Function for negation */ public Double neg(Double a) { return new Double(-a.doubleValue()); } /* Unary Function for getting a root */ public Double sqrt(Double a) { return new Double(Math.sqrt(a.doubleValue())); } /* Unary Function for absolute value */ public Double abs(Double a) { return new Double(Math.abs(a.doubleValue())); } /* Unary Function for sin */ public Double sin(Double a) { return new Double(Math.sin(a.doubleValue())); } /* Unary Function for cosine */ public Double cos(Double a) { return new Double(Math.cos(a.doubleValue())); } /* Unary Function for tangent */ public Double tan(Double a) { return new Double(Math.tan(a.doubleValue())); } /* Unary Function for logarithm */ public Double log(Double a) { return new Double(Math.log(a.doubleValue())); } /* sets the function to be tested against */ public void setFunction(GPNode gpn) { test = gpn; } /* returns the test function */ public GPNode getFunction() { return test; } /* sets the domain to be tested within */ public void setDomain(double xMin,double xMax) { this.xMin = xMin; this.xMax = xMax; } /* fitness function for GP's */ public Double fitnessFunction(GPNode gpn) { double difference=0; int validEvals = 0; /* try to get values from GP's */ try{ for(int i =0;i<40;i++) { x = new Double( (xMax-xMin)/40*i+xMin); double temp = Math.abs(test.value().doubleValue() - gpn.value().doubleValue()); /* if the values are Not numbers, punish harshly */ if(Double.isNaN(temp)) {difference += 10000;} /* otherwise add the difference of the values to the running * total */ else{ validEvals++; difference += temp; } } } catch(NoSuchMethodException e) { System.out.println("in " + gpn.toString() + "or" + test.toString()); } if(validEvals == 0) return new Double(1); /* take the total difference and subtract .2 for every * node in the tree. This encourages smaller trees */ return new Double(-difference/validEvals-(gpn.count()/5.0)); } }