package de.gaalop.visualizer.zerofinding;
import de.gaalop.cfg.AssignmentNode;
import de.gaalop.dfg.*;
import de.gaalop.visualizer.ia_math.IAMath;
import de.gaalop.visualizer.ia_math.RealInterval;
import java.util.HashMap;
/**
* Evaluates the control flow graph with interval arithmetic
* @author christian
*/
public class IntervalEvaluater implements ExpressionVisitor {
private HashMap<MultivectorComponent, RealInterval> values;
public IntervalEvaluater(HashMap<MultivectorComponent, RealInterval> values) {
this.values = values;
}
public HashMap<MultivectorComponent, RealInterval> getValues() {
return values;
}
private RealInterval result;
public void evaluate(CodePiece codePiece) {
for (AssignmentNode node: codePiece)
visit(node);
}
@Override
public void visit(Subtraction node) {
node.getLeft().accept(this);
RealInterval left = result;
node.getRight().accept(this);
result = IAMath.sub(left, result);
}
@Override
public void visit(Addition node) {
node.getLeft().accept(this);
RealInterval left = result;
node.getRight().accept(this);
result = IAMath.add(left, result);
}
@Override
public void visit(Division node) {
node.getLeft().accept(this);
RealInterval left = result;
node.getRight().accept(this);
result = IAMath.div(left,result);
}
@Override
public void visit(Multiplication node) {
node.getLeft().accept(this);
RealInterval left = result;
node.getRight().accept(this);
result = IAMath.mul(left,result);
}
@Override
public void visit(Negation node) {
node.getOperand().accept(this);
result = IAMath.uminus(result);
}
@Override
public void visit(MathFunctionCall node) {
node.getOperand().accept(this);
switch (node.getFunction()) {
case ABS:
result = new RealInterval(Math.min(result.lo(),result.hi()),Math.max(result.lo(),result.hi()));
break;
case ACOS:
result = IAMath.acos(result);
break;
case ASIN:
result = IAMath.asin(result);
break;
case ATAN:
result = IAMath.atan(result);
break;
case CEIL:
result = new RealInterval(Math.ceil(result.lo()),Math.ceil(result.hi()));
break;
case COS:
result = IAMath.cos(result);
break;
case EXP:
result = IAMath.exp(result);
break;
case FACT:
int n = (int) result.lo();
double r = 1.0;
for (int i = 2; i <= (int) n; i++) {
r *= i;
}
result = new RealInterval(r);
break;
case FLOOR:
result = new RealInterval(Math.floor(result.lo()),Math.floor(result.hi()));
break;
case LOG:
result = IAMath.log(result);
break;
case SIN:
result = IAMath.sin(result);
break;
case SQRT:
result = new RealInterval(Math.sqrt(result.lo()),Math.sqrt(result.hi()));
break;
case TAN:
result = IAMath.tan(result);
break;
}
}
@Override
public void visit(MultivectorComponent node) {
RealInterval r = values.get(node);
result = new RealInterval(r.lo(),r.hi());
}
@Override
public void visit(Exponentiation node) {
node.getLeft().accept(this);
RealInterval left = result;
node.getRight().accept(this);
double hi = result.hi();
if (Math.abs(hi-result.lo()) < 0.001 && Math.abs(hi-((int) hi)) < 0.001 && hi>=0) {
result = new RealInterval(1);
for (int i=0;i<((int) hi);i++)
result = IAMath.mul(result, left);
} else
result = IAMath.power(left, result);
}
@Override
public void visit(FloatConstant node) {
result = new RealInterval(node.getValue());
}
public void visit(AssignmentNode node) {
node.getValue().accept(this);
values.put((MultivectorComponent) node.getVariable(), result);
}
@Override
public void visit(Variable node) {
MultivectorComponent m = new MultivectorComponent(node.getName(), 0);
if (!values.containsKey(m)) {
System.err.println("Interval Evaluater: Kein Wert gefunden! "+m.toString());
return;
}
RealInterval r = values.get(m);
if (r != null)
result = new RealInterval(r.lo(),r.hi());
else {
result = null;
System.err.println("Interval Evaluater: Kein Wert 2 gefunden! "+m.toString());
}
}
// ====================== Illegal methods ======================
@Override
public void visit(OuterProduct node) {
throw new UnsupportedOperationException("OuterProducts should have been removed by TBA.");
}
@Override
public void visit(BaseVector node) {
throw new UnsupportedOperationException("BaseVectors should have been removed by TBA.");
}
@Override
public void visit(Reverse node) {
throw new UnsupportedOperationException("Reverses should have been removed by TBA.");
}
@Override
public void visit(LogicalOr node) {
throw new UnsupportedOperationException("LogicalOrs should have been removed by TBA.");
}
@Override
public void visit(LogicalAnd node) {
throw new UnsupportedOperationException("LogicalAnds should have been removed by TBA.");
}
@Override
public void visit(LogicalNegation node) {
throw new UnsupportedOperationException("LogicalNegations should have been removed by TBA.");
}
@Override
public void visit(Equality node) {
throw new UnsupportedOperationException("Equalities should have been removed by TBA.");
}
@Override
public void visit(Inequality node) {
throw new UnsupportedOperationException("Inequalities should have been removed by TBA.");
}
@Override
public void visit(Relation relation) {
throw new UnsupportedOperationException("Relations should have been removed by TBA.");
}
@Override
public void visit(FunctionArgument node) {
throw new UnsupportedOperationException("FunctionArguments should have been removed by TBA.");
}
@Override
public void visit(MacroCall node) {
throw new UnsupportedOperationException("MacroCalls should have been removed by TBA.");
}
@Override
public void visit(InnerProduct node) {
throw new UnsupportedOperationException("Inner products should have been removed by TBA.");
}
}