/* * Copyright 2007-2010 Lawrence Beadle & Tom Castle * Licensed under GNU General Public License * * This file is part of Epoch X - (The Genetic Programming Analysis Software) * * Epoch X is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Epoch X is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Epoch X. If not, see <http://www.gnu.org/licenses/>. */ package org.epochx.semantics; import java.util.*; import org.epochx.epox.*; import org.epochx.epox.dbl.CoefficientPowerFunction; /** * Regression representation is for canonically modelling the behaviour of * symbolic regression domains. */ public class RegressionRepresentation implements Representation, Cloneable { private ArrayList<CoefficientPowerFunction> regressionRepresentation; /** * Constructor for regression representation object * @param regressionRepresentation list of the coefficients */ public RegressionRepresentation(ArrayList<CoefficientPowerFunction> regressionRepresentation) { this.regressionRepresentation = regressionRepresentation; } /** * Constructor for repression representation object - will create blank representation */ public RegressionRepresentation() { this.regressionRepresentation = new ArrayList<CoefficientPowerFunction>(); } /** * Returns the regression representation (the formula coefficients) * @return A list of the formula coefficients */ public ArrayList<CoefficientPowerFunction> getRegressionRepresentation() { return regressionRepresentation; } /** * Simplifies any CVPs with same variable and power */ public void simplify() { outer: for (int i=0; i<regressionRepresentation.size(); i++) { CoefficientPowerFunction cvp1 = regressionRepresentation.get(i); DoubleNode coefficient1 = (DoubleNode) cvp1.getChild(0); DoubleNode term1 = (DoubleNode) cvp1.getChild(1); DoubleNode exponent1 = (DoubleNode) cvp1.getChild(2); // Compare against every one AFTER it in the list. for (int j=i+1; j<regressionRepresentation.size(); j++) { CoefficientPowerFunction cvp2 = regressionRepresentation.get(j); DoubleNode coefficient2 = (DoubleNode) cvp2.getChild(0); DoubleNode term2 = (DoubleNode) cvp2.getChild(1); DoubleNode exponent2 = (DoubleNode) cvp2.getChild(2); if (term1.equals(term2) && exponent1.equals(exponent2)) { double newCoefficient = coefficient1.evaluate() + coefficient2.evaluate(); // Update the second element with the new coefficient. cvp2.setChild(0, new DoubleLiteral(newCoefficient)); // Nullify the current one and then we'll skip to the next... regressionRepresentation.set(i, null); // Once we've done one merge go onto the next element - others will be caught later. continue outer; } } } // kill any 0 or -0 coefficients for(int i = 0; i<regressionRepresentation.size(); i++) { if(regressionRepresentation.get(i) instanceof CoefficientPowerFunction) { double coefficient = (Double) regressionRepresentation.get(i).getChild(0).evaluate(); if(coefficient==0 || coefficient==-0) { regressionRepresentation.set(i, null); } } } // Add non-nulls to this new list. List<CoefficientPowerFunction> combinedCVPs = new ArrayList<CoefficientPowerFunction>(); for (CoefficientPowerFunction cvp: regressionRepresentation) { if (cvp != null) { combinedCVPs.add(cvp); } } // Clear the old list. regressionRepresentation.clear(); // Then throw the new ones back in to the old list. regressionRepresentation.addAll(combinedCVPs); // if representation is zero if(regressionRepresentation.size()==0) { CoefficientPowerFunction cvp = new CoefficientPowerFunction(new DoubleLiteral(0d), new DoubleVariable("X"), new DoubleLiteral(0d)); regressionRepresentation.add(cvp); } } /** * Orders the CVP clauses - starting with the lowest power. */ public void order() { Collections.sort(regressionRepresentation, new Comparator<CoefficientPowerFunction>(){ @Override public int compare(CoefficientPowerFunction cvp1, CoefficientPowerFunction cvp2) { double power1 = (Double) ((Node) cvp1.getChild(2)).evaluate(); double power2 = (Double) ((Node) cvp2.getChild(2)).evaluate(); return Double.compare(power1, power2); } }); } @Override public String toString() { String output = ""; for(CoefficientPowerFunction c: regressionRepresentation) { output = output + c.toString() + " "; } return output; } /* (non-Javadoc) * @see com.epochx.semantics.Representation#equals(com.epochx.semantics.Representation) */ @Override public boolean equals(Representation anotherBehaviour) { boolean marker = false; if(anotherBehaviour instanceof RegressionRepresentation) { RegressionRepresentation regRep = (RegressionRepresentation) anotherBehaviour; if(regRep.getRegressionRepresentation().equals(this.regressionRepresentation)) { marker = true; } } return marker; } /* (non-Javadoc) * @see com.epochx.semantics.Representation#isConstant() */ @Override public boolean isConstant() { // if length = 1 there is only a constant in the x side of f(x) if(regressionRepresentation.size()==1) { if(regressionRepresentation.get(0).getChild(2).equals(new DoubleLiteral(0d))) { return true; } if(regressionRepresentation.get(0).getChild(2).equals(new DoubleLiteral(-0d))) { return true; } } else if(regressionRepresentation.size()==0) { return true; } return false; } @SuppressWarnings("unchecked") @Override protected Object clone() throws CloneNotSupportedException { RegressionRepresentation newRep = (RegressionRepresentation) super.clone(); newRep.regressionRepresentation = (ArrayList<CoefficientPowerFunction>) this.regressionRepresentation.clone(); // Clone each cvp element. for (int i=0; i<newRep.regressionRepresentation.size(); i++) { CoefficientPowerFunction cvp = newRep.regressionRepresentation.get(i); newRep.regressionRepresentation.set(i, (CoefficientPowerFunction) cvp.clone()); } return newRep; } }