org.drugis.mtc.yadas.YadasResults.java Source code

Java tutorial

Introduction

Here is the source code for org.drugis.mtc.yadas.YadasResults.java

Source

/*
 * This file is part of the GeMTC software for MTC model generation and
 * analysis. GeMTC is distributed from http://drugis.org/gemtc.
 * Copyright (C) 2009-2012 Gert van Valkenhoef.
 *
 * 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 3 of the License, or
 * (at your option) 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.drugis.mtc.yadas;

import gov.lanl.yadas.MCMCParameter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.ArrayUtils;
import org.drugis.mtc.MCMCResults;
import org.drugis.mtc.MCMCResultsEvent;
import org.drugis.mtc.MCMCResultsListener;
import org.drugis.mtc.Parameter;

public class YadasResults implements MCMCResults {
    private Parameter[] d_directParameters;
    private Parameter[] d_derivedParameters;
    private Derivation[] d_derivations;
    private int d_nChains;
    private int d_availableSamples;
    private int d_reservedSamples;
    private List<List<double[]>> d_results;
    private List<MCMCResultsListener> d_listeners = new ArrayList<MCMCResultsListener>();

    private class YadasParameterWriter extends ParameterWriter {
        private final int d_pIdx;
        private final int d_cIdx;
        private int d_idx;

        /**
         * @param pIdx Index of the parameter in the results.
         * @param cIdx Chain index.
         * @param mp MCMCParameter to monitor.
         * @param i The component of the MCMCParameter to monitor.
         */
        public YadasParameterWriter(int pIdx, int cIdx, MCMCParameter mp, int i) {
            super(mp, i);
            d_pIdx = pIdx;
            d_cIdx = cIdx;
            d_idx = 0;
        }

        @Override
        protected void write(double value) {
            d_results.get(d_cIdx).get(d_pIdx)[d_idx++] = value;
        }
    }

    public YadasResults() {
        initialize();
    }

    public void clear() {
        d_availableSamples = 0;
        d_reservedSamples = 0;
        initResults();
    }

    private void initialize() {
        d_directParameters = new Parameter[] {};
        d_derivedParameters = new Parameter[] {};
        d_derivations = new Derivation[] {};
        d_nChains = 0;
        clear();
    }

    /**
     * Set the parameters for which results will be produced by the Yadas simulation.
     */
    public void setDirectParameters(List<Parameter> parameters) {
        d_directParameters = new Parameter[parameters.size()];
        for (int i = 0; i < parameters.size(); ++i) {
            d_directParameters[i] = parameters.get(i);
        }
        initResults();
    }

    /**
     * Set the derived parameters, which are to be calculated from the direct ones using the given Derivation.
     */
    public void setDerivedParameters(Map<? extends Parameter, Derivation> derivations) {
        d_derivedParameters = new Parameter[derivations.size()];
        d_derivations = new Derivation[derivations.size()];
        int i = 0;
        for (Entry<? extends Parameter, Derivation> e : derivations.entrySet()) {
            d_derivedParameters[i] = e.getKey();
            d_derivations[i] = e.getValue();
            ++i;
        }
    }

    /**
     * Get the direct parameters.
     * @see MCMCResults
     */
    public Parameter[] getParameters() {
        return d_directParameters;
    }

    public int findParameter(Parameter p) {
        int idx = ArrayUtils.indexOf(d_directParameters, p);
        if (idx >= 0) {
            return idx;
        }
        idx = ArrayUtils.indexOf(d_derivedParameters, p);
        if (idx >= 0) {
            idx += d_directParameters.length;
        }
        return idx;
    }

    /**
     * Create the ParameterWriter for the given Parameter.
     * @param p Model parameter to write results for.
     * @param cIdx Chain index.
     * @param mp MCMCParameter to monitor results from.
     * @param i Component of the MCMCParameter to monitor.
     * @return A new ParameterWriter.
     */
    public ParameterWriter getParameterWriter(Parameter p, int cIdx, MCMCParameter mp, int i) {
        return new YadasParameterWriter(findParameter(p), cIdx, mp, i);
    }

    public double getSample(int p, int c, int i) {
        if (c < 0 || c >= d_nChains) {
            throw new IndexOutOfBoundsException(
                    "Chain " + c + " out of bounds: " + d_nChains + " chains available.");
        }
        final int nDirect = d_directParameters.length;
        final int nDerived = d_derivedParameters.length;
        if (p < 0 || p >= nDirect + nDerived) {
            throw new IndexOutOfBoundsException(
                    "Parameter " + p + " out of bounds: " + nDirect + " + " + nDerived + " parameters available.");
        }
        if (i < 0 || i >= d_availableSamples) {
            throw new IndexOutOfBoundsException(
                    "Iteration " + i + " out of bounds: " + d_availableSamples + " iterations available.");
        }
        return p < nDirect ? d_results.get(c).get(p)[i] : d_derivations[p - nDirect].calculate(this, c, i);
    }

    public void setNumberOfChains(int nChains) {
        d_nChains = nChains;
        initResults();
    }

    private void initResults() {
        d_results = new ArrayList<List<double[]>>(d_nChains);
        for (int i = 0; i < d_nChains; ++i) {
            List<double[]> list = new ArrayList<double[]>(d_directParameters.length);
            for (int j = 0; j < d_directParameters.length; ++j) {
                list.add(new double[d_reservedSamples]);
            }
            d_results.add(list);
        }
    }

    public int getNumberOfChains() {
        return d_nChains;
    }

    public void setNumberOfIterations(int iter) {
        d_reservedSamples = iter;
        for (List<double[]> chain : d_results) {
            for (int i = 0; i < chain.size(); ++i) {
                double[] newResults = new double[iter];
                System.arraycopy(chain.get(i), 0, newResults, 0, chain.get(i).length);
                chain.set(i, newResults);
            }
        }
    }

    public int getNumberOfIterations() {
        return d_reservedSamples;
    }

    public int getNumberOfSamples() {
        return d_availableSamples;
    }

    public void simulationFinished() {
        d_availableSamples = d_reservedSamples;
        MCMCResultsEvent event = new MCMCResultsEvent(this);
        List<MCMCResultsListener> listeners = new ArrayList<MCMCResultsListener>(d_listeners);
        for (MCMCResultsListener l : listeners) {
            l.resultsEvent(event);
        }
    }

    public void addResultsListener(MCMCResultsListener l) {
        d_listeners.add(l);
    }

    public void removeResultsListener(MCMCResultsListener l) {
        d_listeners.remove(l);
    }
}