//=============================================================================
// Copyright 2006-2010 Daniel W. Dyer
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//=============================================================================
package org.uncommons.watchmaker.examples.geneticprogramming;
/**
* Simple multiplication operator {@link Node}.
* @author Daniel Dyer
*/
public class Multiplication extends BinaryNode
{
/**
* Creates a node that evaluates to the product of the values of its two
* child nodes ({@literal left} and {@literal right}).
* @param left The first operand.
* @param right The second operand.
*/
public Multiplication(Node left, Node right)
{
super(left, right, '*');
}
/**
* Evaluates the two sub-trees and returns the product of these two values.
* @param programParameters Program parameters (ignored by the multiplication operator
* but may be used in evaluating the sub-trees).
* @return The sum of the values of both child nodes.
*/
public double evaluate(double[] programParameters)
{
return left.evaluate(programParameters) * right.evaluate(programParameters);
}
/**
* {@inheritDoc}
*/
public Node simplify()
{
Node simplifiedLeft = left.simplify();
Node simplifiedRight = right.simplify();
// If the two arguments are constants, we can simplify by calculating the result, it won't
// ever change.
if (simplifiedLeft instanceof Constant && simplifiedRight instanceof Constant)
{
return new Constant(simplifiedLeft.evaluate(NO_ARGS) * simplifiedRight.evaluate(NO_ARGS));
}
// Multiplying by one is pointless, the expression can be reduced to its other argument.
else if (simplifiedRight instanceof Constant)
{
double constant = simplifiedRight.evaluate(NO_ARGS);
if (constant == 1)
{
return simplifiedLeft;
}
else if (constant == 0)
{
return new Constant(0);
}
}
else if (simplifiedLeft instanceof Constant)
{
double constant = simplifiedLeft.evaluate(NO_ARGS);
if (constant == 1)
{
return simplifiedRight;
}
else if (constant == 0)
{
return new Constant(0);
}
}
return simplifiedLeft != left || simplifiedRight != right
? new Multiplication(simplifiedLeft, simplifiedRight)
: this;
}
}