package ec.app.semanticGP.func.numeric;

import ec.gp.GPNode;
import ec.gp.semantic.DoubleSemantics;
import ec.gp.semantic.ISemantics;
import ec.gp.semantic.func.BinaryNode;
import ec.gp.semantic.func.SimpleNodeBase;

public class Averager extends BinaryNode<Double> {

	private final double coefficient;

	// #ifdef NO_SEMANTICS_CACHE
//@		private ISemantics semantics = null;
	// #endif

	public Averager(SimpleNodeBase<Double> child1, SimpleNodeBase<Double> child2, double coefficient) {
		assert coefficient >= 0.0 && coefficient <= 1.0;

		this.coefficient = coefficient;
		this.children = new GPNode[] { child1, child2 };
	}

	// #ifdef NO_SEMANTICS_CACHE
//@		
//@		@Override
//@		public ISemantics getSemantics() {
//@			if (this.semantics == null) {
//@				ISemantics child0Sem = ((SimpleNodeBase<?>)children[0]).getSemantics();
//@				ISemantics child1Sem = ((SimpleNodeBase<?>)children[1]).getSemantics();
//@				
//@				this.semantics = this.execute(child0Sem, child1Sem);
//@			}
//@			
//@			return this.semantics;
//@		}
//@	
//@		@Override
//@		public void resetSemantics() {
//@			this.semantics = null;
//@		}
//@	
	// #endif

	@Override
	public boolean isSymmetric() {
		return false;
	}

	@Override
	protected ISemantics execute(ISemantics... arguments) {
		double[] arg0 = (double[]) arguments[0].getValue();
		double[] arg1 = (double[]) arguments[1].getValue();
		double[] semantics = new double[arg0.length];

		for (int i = 0; i < semantics.length; ++i) {
			semantics[i] = coefficient * arg0[i] + (1 - coefficient) * arg1[i];
		}

		return new DoubleSemantics(semantics);
	}

	@Override
	public Double[] invert(Double output, int missingArgIdx, Double... restOfArguments) {
		throw new UnsupportedOperationException("Not implemented");
	}

	@Override
	public String toString() {
		return String.format("* %.4f + %.4f *", this.coefficient, 1.0 - this.coefficient);
	}

}
