/*******************************************************************************
* Copyright (c) 2009 University of Edinburgh.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the BSD Licence, which accompanies this feature
* and can be downloaded from http://groups.inf.ed.ac.uk/pepa/update/licence.txt
******************************************************************************/
package uk.ac.ed.inf.biopepa.core.compiler;
import uk.ac.ed.inf.biopepa.core.BioPEPAException;
import uk.ac.ed.inf.biopepa.core.compiler.CompiledFunction.Function;
import uk.ac.ed.inf.biopepa.core.dom.Expression;
import uk.ac.ed.inf.biopepa.core.dom.FunctionCall;
public class FunctionEvaluators {
public static class GenericOneArgumentFunction implements IPredefinedFunctionEvaluator {
private ModelCompiler compiler;
private FunctionCall call;
private Function function;
public GenericOneArgumentFunction(ModelCompiler compiler, FunctionCall call) throws CompilerException {
this.compiler = compiler;
this.call = call;
function = CompiledFunction.checkFunction(compiler, call);
}
public CompiledExpression evaluate() throws EvaluationException {
Expression e = call.arguments().get(0);
ExpressionEvaluatorVisitor v = new ExpressionEvaluatorVisitor(compiler);
try {
e.accept(v);
} catch (BioPEPAException e1) {
throw new EvaluationException();
}
// A literal translation of the function into a
// compiled function. This will serve as the return
// result if the whole function call is dynamic (such as fMA(r))
// or the expanded form if the whole call can be statically
// evaluated, such as floor (r1 * r2) where r1 and r2 are static.
CompiledFunction efn = new CompiledFunction();
efn.setFunction(function);
efn.setArgument(0, v.getExpressionNode());
if (v.getExpressionNode() instanceof CompiledNumber) {
CompiledNumber number = null;
double d = ((CompiledNumber) v.getExpressionNode()).doubleValue();
switch (function) {
case H:
number = new CompiledNumber((d > 0.00 ? new Long(1) : new Long(0)));
break;
case FLOOR:
number = new CompiledNumber(((long) Math.floor(d)));
break;
case CEILING:
number = new CompiledNumber(((long) Math.ceil(d)));
break;
case LOG:
number = new CompiledNumber(Math.log(d));
break;
case EXP:
number = new CompiledNumber(Math.exp(d));
break;
case TANH:
number = new CompiledNumber(Math.tanh(d));
break;
default:
System.err.println("shouldn't get here?");
}
number.setExpandedForm(efn);
return number;
}
return efn;
}
}
}