Package org.boris.expr.engine

Source Code of org.boris.expr.engine.IterationEngine

/*******************************************************************************
* This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
*     Peter Smith
*******************************************************************************/
package org.boris.expr.engine;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.boris.expr.Expr;
import org.boris.expr.ExprArray;
import org.boris.expr.ExprEvaluatable;
import org.boris.expr.ExprException;
import org.boris.expr.ExprNumber;

public class IterationEngine extends AbstractCalculationEngine
{
    private int maxIterations = 100;
    private double maxChange = 0.0001;
    private Map<Range, Expr> inputExprs = new HashMap();

    public IterationEngine(EngineProvider provider) {
        super(provider);
    }

    public void setMaxIterations(int iterations) {
        this.maxIterations = iterations;
    }

    public void setMaxChange(double change) {
        this.maxChange = Math.abs(change);
    }

    public void calculate(boolean force) throws ExprException {
        if (autoCalculate && !force)
            return;

        calc();
    }

    private void calc() throws ExprException {
        Set<Range> inputs = getInputRanges();
        Map<Range, Expr> valueChanges = new HashMap();
        for (int i = 0; i < maxIterations; i++) {
            double change = 0;
            for (Range r : inputs) {
                Expr e = inputExprs.get(r);
                if (e instanceof ExprEvaluatable) {
                    e = ((ExprEvaluatable) e).evaluate();
                    values.put(r, e);
                    valueChanges.put(r, e);
                    double c = findChange(values.get(r), e);
                    if (c > change)
                        change = c;
                }
            }

            if (change < maxChange)
                break;
        }

        for (Range r : valueChanges.keySet()) {
            provider.valueChanged(r, valueChanges.get(r));
        }
    }

    private double findChange(Expr old, Expr nu) {
        if (old == null || nu == null)
            return 0;

        if (old.type != nu.type)
            return 0;

        if (nu instanceof ExprNumber) {
            return Math.abs(((ExprNumber) old).doubleValue() -
                    ((ExprNumber) nu).doubleValue());
        }

        if (nu instanceof ExprArray) {
            Expr[] oldA = old.getArgs();
            Expr[] nuA = nu.getArgs();

            double change = 0;
            for (int i = 0; i < oldA.length && i < nuA.length; i++) {
                double c = findChange(oldA[i], nuA[i]);
                if (c > change)
                    change = c;
            }

            return change;
        }

        return 0;
    }

    public void set(Range range, String expression) throws ExprException {
        validateRange(range);

        // If null then remove all references
        if (expression == null) {
            rawInputs.remove(range);
            inputExprs.remove(range);
            values.remove(range);
            inputs.remove(range);
            return;
        }

        rawInputs.put(range, expression);

        Expr expr = parseExpression(expression);
        inputExprs.put(range, expr);

        // Set the inputs
        provider.inputChanged(range, expr);
        inputs.put(range, expr);

        // Always evaluate the expression entered
        if (expr.evaluatable) {
            Expr eval = ((ExprEvaluatable) expr).evaluate();
            provider.valueChanged(range, eval);
            values.put(range, eval);
        } else {
            provider.valueChanged(range, expr);
            values.put(range, expr);
        }

        // Recalculate the dependencies if required
        if (autoCalculate) {
            calc();
        }
    }
}
TOP

Related Classes of org.boris.expr.engine.IterationEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.