org.tsho.dmc2.core.chart.CyclesRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.tsho.dmc2.core.chart.CyclesRenderer.java

Source

/*
 * iDMC the interactive Dynamical Model Calculator simulates and performs
 * graphical and numerical analysis of systems of differential and
 * difference equations.
 *
 * Copyright (C) 2004,2005,2006 Marji Lines and Alfredo Medio.
 *
 * Written by Daniele Pizzoni <auouo@tin.it>.
 * Extended by Alexei Grigoriev <alexei_grigoriev@libero.it>.
 *
 *
 *
 * The software program was developed within a research project financed
 * by the Italian Ministry of Universities, the Universities of Udine and
 * Ca'Foscari of Venice, the Friuli-Venezia Giulia Region.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */
package org.tsho.dmc2.core.chart;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;

import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.ui.RectangleEdge;
import org.tsho.dmc2.AlgorithmFailedException;
import org.tsho.dmc2.core.VariableDoubles;
import org.tsho.dmc2.core.dlua.Lua;
import org.tsho.dmc2.core.model.Model;
import org.tsho.dmc2.core.model.SimpleMap;

public class CyclesRenderer implements DmcPlotRenderer {

    private DmcRenderablePlot plot;
    private SimpleMap map;

    VariableDoubles rangeMin, rangeMax;

    // parameters

    private VariableDoubles parameters;
    private VariableDoubles initialPoint;
    private String xLabel;
    private String yLabel;
    private double epsilon;
    private int period;
    private int maxPoints;

    // options

    private boolean bigDots;

    // flags

    private boolean stopped;

    // internal state

    private int state;

    public CyclesRenderer(final SimpleMap map, final DmcRenderablePlot plot) {

        this.map = map;
        this.plot = plot;
    }

    public void initialize() {
        stopped = false;
    }

    public LegendItemCollection getLegendItems() {
        return null;
    }

    public void render(final Graphics2D g2, final Rectangle2D dataArea, final PlotRenderingInfo info) {
        ValueAxis domainAxis = plot.getDomainAxis();
        ValueAxis rangeAxis = plot.getRangeAxis();

        state = STATE_RUNNING;

        g2.setColor(Color.BLACK);

        VariableDoubles initialValues = map.getVariables();
        int xLabelIndex = VariableDoubles.indexOf(initialValues, xLabel);
        int yLabelIndex = VariableDoubles.indexOf(initialValues, yLabel);

        int x, y;
        String varNames[] = map.getVarNames();
        int dim = map.getNVar();
        double tmp[] = new double[dim];
        double tmp1[] = new double[dim];
        double vRangeMax[] = VariableDoubles.toArray(rangeMax);
        double vRangeMin[] = VariableDoubles.toArray(rangeMin);
        double[] cycle;
        double[] cycleModulus = new double[dim];

        double[][] list = new double[period][dim];

        int counter = 0;
        main: while (counter < maxPoints) {

            if (stopped) {
                state = STATE_STOPPED;
                return;
            }

            for (int iii = 0; iii < dim; iii++) {
                double val = (vRangeMax[iii] - vRangeMin[iii]) * Math.random();
                initialValues.put(varNames[iii], vRangeMin[iii] + val);
            }
            counter++;

            try {
                cycle = Lua.findCycles(map, parameters, period, initialValues, epsilon, 100, cycleModulus);
            } catch (AlgorithmFailedException e) {
                continue;
            }

            if (period > 1) {
                System.arraycopy(cycle, 0, list[0], 0, dim);

                for (int i = 0; i < period - 1; i++) { /*fill cycle data*/
                    map.evaluate(VariableDoubles.toArray(parameters), list[i], list[i + 1]);
                }

                // compare i + 1 with all previous
                for (int j = 0; j < period; j++) {
                    for (int i = j + 1; i < period; i++) {
                        if (equal(list[j], list[i], epsilon)) {
                            continue main;
                        }
                    }
                }

                // check if it's a real solution
                map.evaluate(VariableDoubles.toArray(parameters), list[period - 1], tmp);
                if (!equal(tmp, list[0], epsilon))
                    continue main;

                checkStability(cycleModulus, g2);

                for (int i = 0; i < period; i++) {
                    x = (int) domainAxis.valueToJava2D(list[i][xLabelIndex], dataArea, RectangleEdge.BOTTOM);

                    y = (int) rangeAxis.valueToJava2D(list[i][yLabelIndex], dataArea, RectangleEdge.LEFT);
                    if (bigDots) {
                        g2.fillRect(x - 1, y - 1, 3, 3);
                    } else {
                        g2.fillRect(x, y, 1, 1);
                    }
                }
            } else { // period == 1
                x = (int) domainAxis.valueToJava2D(cycle[xLabelIndex], dataArea, RectangleEdge.BOTTOM);

                y = (int) rangeAxis.valueToJava2D(cycle[yLabelIndex], dataArea, RectangleEdge.LEFT);

                // check if it's a real solution
                map.evaluate(VariableDoubles.toArray(parameters), cycle, tmp);
                if (!equal(tmp, cycle, epsilon))
                    continue main;

                checkStability(cycleModulus, g2);

                if (bigDots) {
                    g2.fillRect(x - 1, y - 1, 3, 3);
                } else {
                    g2.fillRect(x, y, 1, 1);
                }
            }

        }

        state = STATE_FINISHED;
    }

    private void checkStability(double cycleModulus[], Graphics2D g2) {
        /*check eigval modulus. Depending on it, set color.*/
        boolean stable = false;
        boolean unstable = false;
        boolean one = false;
        int dim = cycleModulus.length;
        for (int i = 0; i < dim; i++) {
            if (stable)
                if (cycleModulus[i] >= 1) {
                    stable = false;
                    break;
                } else
                    continue;
            if (unstable)
                if (cycleModulus[i] <= 1) {
                    unstable = false;
                    break;
                } else
                    continue;
            if (Math.abs(cycleModulus[i] - 1) <= epsilon) {
                one = true;
                break;
            } else if (cycleModulus[i] < 1)
                stable = true;
            else if (cycleModulus[i] > 1)
                unstable = true;
            else
                break;
        }
        if (one)
            g2.setColor(Color.BLACK);
        else if (stable)
            g2.setColor(Color.GREEN);
        else if (unstable)
            g2.setColor(Color.RED);
        else
            g2.setColor(Color.BLUE);
    }

    static boolean _equal(double[] a, double[] b, double epsilon) {
        for (int k = 0; k < a.length; k++) {
            if (Math.abs(b[k] - a[k]) > epsilon) {
                return false;
            }
        }
        return true;
    }

    // euclidean
    static boolean equal(double[] a, double[] b, double epsilon) {
        double norm = 0;
        for (int k = 0; k < a.length; k++) {
            norm += Math.pow(b[k] - a[k], 2);
        }
        if (norm > epsilon) {
            return false;
        } else {
            return true;
        }
    }

    public void stop() {
        stopped = true;
    }

    public void initialize(VariableDoubles parameters, VariableDoubles initialPoint, VariableDoubles rangeMin,
            VariableDoubles rangeMax, String xLabel, String yLabel, double epsilon, int period, int maxPoints) {

        this.parameters = parameters;
        this.initialPoint = initialPoint;
        this.rangeMin = rangeMin;
        this.rangeMax = rangeMax;
        this.xLabel = xLabel;
        this.yLabel = yLabel;
        this.epsilon = epsilon;
        this.period = period;
        this.maxPoints = maxPoints;
    }

    public double getEpsilon() {
        return epsilon;
    }

    public VariableDoubles getInitialPoint() {
        return initialPoint;
    }

    public int getMaxPoints() {
        return maxPoints;
    }

    public VariableDoubles getParameters() {
        return parameters;
    }

    public int getPeriod() {
        return period;
    }

    public int getState() {
        return state;
    }

    public String getXLabel() {
        return xLabel;
    }

    public String getYLabel() {
        return yLabel;
    }

    public void setEpsilon(double d) {
        epsilon = d;
    }

    public void setInitialPoint(VariableDoubles doubles) {
        initialPoint = doubles;
    }

    public void setMaxPoints(int i) {
        maxPoints = i;
    }

    public void setParameters(VariableDoubles doubles) {
        parameters = doubles;
    }

    public void setPeriod(int i) {
        period = i;
    }

    public void setState(byte b) {
        state = b;
    }

    public void setXLabel(String string) {
        xLabel = string;
    }

    public void setYLabel(String string) {
        yLabel = string;
    }

    public void setState(int i) {
        state = i;
    }

    public boolean isBigDots() {
        return bigDots;
    }

    public void setBigDots(boolean b) {
        bigDots = b;
    }

}