/**
 * 
 */
package org.eclipse.stem.util.analysis;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;


/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/


/**
 * This class holds all the parameters that we might want to estimate
 * and their standard deviations and variances.
 */
public class ModelParameters {

	/**
	 * All model parameters are stored in this map
	 */
	private final HashMap<String, Parameter> parameters = new HashMap<String, Parameter>();


	/**
	 * All selected data as a List<double[][]> keyed by location
	 * for display. The double indices are data[state][chartIndex][time]
	 * where state indicates either raw data (state=0) or the selected time region of the data (state=1) 
	 * chart index selected for each of the state variables S,E,I,R (chartIndex 0-3)
	 */
	private final HashMap<String, List<double[][]> > selectedData = new HashMap<String, List<double[][]>>();

	/**
	 * All selected regression as a List<double[][]> keyed by location
	 * for display. The double indices are data[state][time]
	 * where state indicates either x axis (state=0) or y axis (state=1) 
	 * chart index selected for each of the state equations (chartIndex 0-3)
	 */
	private final HashMap<String, List<double[][]> > regressionData = new HashMap<String, List<double[][]>>();


	/**
	 * All selected fits to the regression as a List<double[][]> keyed by location
	 * for display. The double indices are data[state][time]
	 * where state indicates either x axis (state=0) or y axis (state=1) 
	 * chart index selected for each of the state equations (chartIndex 0-3)
	 */
	private final HashMap<String, List<double[][]> > fittedData = new HashMap<String, List<double[][]>>();




	/**
	 * the reference population density
	 * required to do an average across locations with varying density
	 */
	public static final double REFERENCE_POPULATION_DENSITY = 100.0;


	/**
	 * empty constructor
	 */
	public ModelParameters() {
		// Nothing here
	}


	/**
	 * average the data in a map of model parameters
	 * @param parameterIdMap
	 * @return the averaged modelParameters
	 */
	public ModelParameters average(Map<String,ModelParameters> parameterIdMap) {
		//Iterator<String> iter = parameterIdMap.keySet().iterator();
		for (Entry<String,ModelParameters> entry : parameterIdMap.entrySet()) {

			//while((iter!=null)&&(iter.hasNext())) {
			//String key = iter.next();
			ModelParameters parms = entry.getValue();
			this.accumulateNumerator(parms);
			this.accumulateDenominator(parms);

			// and for display purposes save the data, by location, that went into the fit
			Iterator<String> iter2 = parms.selectedData.keySet().iterator();
			while((iter2!=null)&&(iter2.hasNext())) {
				String id = iter2.next();
				List<double[][]> data = parms.selectedData.get(id);
				this.selectedData.put(id, data);
			}	
			// and for display purposes save the regression, by location, that went into the fit
			Iterator<String> iter3 = parms.regressionData.keySet().iterator();
			while((iter3!=null)&&(iter3.hasNext())) {
				String id = iter3.next();
				List<double[][]> data = parms.regressionData.get(id);
				this.regressionData.put(id, data);
			}	

			// and for display purposes save the fitted data, by location, that went into the fit
			Iterator<String> iter4 = parms.fittedData.keySet().iterator();
			while((iter4!=null)&&(iter4.hasNext())) {
				String id = iter4.next();
				List<double[][]> data = parms.fittedData.get(id);
				this.fittedData.put(id, data);
			}	
		}// all locations
		this.average();
		this.calculateStdAvg();
		return this;
	}


	HashMap <String, Double> numerators = new HashMap<String, Double>();

	/**
	 * accumulate numerator values from another ModelParameters instance for calculating average
	 * @param other
	 */
	@SuppressWarnings("boxing")
	private void accumulateNumerator(ModelParameters other) {

		for(Parameter parm : other.getParameters().values()) {
			if(numerators.containsKey(parm.name))
				numerators.put(parm.name, 
						numerators.get(parm.name) + (parm.value / parm.variance));
			else
				numerators.put(parm.name, 
						parm.value / parm.variance);
		}
	}

	HashMap <String, Double> denominators = new HashMap<String, Double>();

	/**
	 * accumulate denominator values from another ModelParameters instance for calculating average
	 * @param other
	 */
	@SuppressWarnings("boxing")
	private void accumulateDenominator(ModelParameters other) {

		for(Parameter parm : other.getParameters().values()) {
			if(denominators.containsKey(parm.name))
				denominators.put(parm.name, 
						denominators.get(parm.name) + (1.0 / parm.variance));
			else
				denominators.put(parm.name, 
						(1.0 / parm.variance));
		}
	}

	/**
	 * divide to get average
	 */
	private void average() {
		for(String parm : this.numerators.keySet()) {
			double num = numerators.get(parm).doubleValue();
			double denom = denominators.get(parm).doubleValue();
			this.addParameter(parm, new Parameter(parm, num / denom  ));
		}// for
	}// average

	/**
	 * find std of each parameter average
	 */
	@SuppressWarnings("boxing")
	private void calculateStdAvg() {
		for(String parm : this.numerators.keySet()) {
			Parameter p = this.getParameter(parm);
			p.stddev = Math.sqrt(1.0 / denominators.get(parm));
		}

		// I assume the += below was a bug? - SED
		/*		stdBeta += Math.sqrt(1/denominatorBeta);
		stdAlpha += Math.sqrt(1/denominatorAlpha);
		stdGamma += Math.sqrt(1/denominatorGamma);
		stdEpsilon += Math.sqrt(1/denominatorEpsilon);
		stdBeta2 += Math.sqrt(1/denominatorBeta2);
		stdAlpha2 += Math.sqrt(1/denominatorAlpha2);
		stdGamma2 += Math.sqrt(1/denominatorGamma2);
		stdEpsilon2 += Math.sqrt(1/denominatorEpsilon2);
		stdLambda += Math.sqrt(1/denominatorLambda);
		 */
	}


	/**
	 * add a new parameter to the map
	 * @param name Parameter name
	 * @param parm Parameter instance
	 */
	public void addParameter(String name, Parameter parm) {
		this.parameters.put(name, parm);
	}

	/**
	 * add selected data for display
	 * @param name location name
	 * @param data the selected data
	 */
	public void addSelectedData(String name, List<double[][]> data) {
		this.selectedData.put(name, data);
	}

	/**
	 * add selected regression for display
	 * @param name location name
	 * @param data the selected data
	 */
	public void addRegressionData(String name, List<double[][]> data) {
		this.regressionData.put(name, data);
	}


	/**
	 * add fitted data for display
	 * @param name location name
	 * @param data the selected data
	 */
	public void addFittedData(String name, List<double[][]> data) {
		this.fittedData.put(name, data);
	}


	/**
	 * Returns the raw data (state 0) and the selected data (state 1) 
	 * for each of the state variables S,E,I,R (chartIndex 0-3)
	 * @param id 
	 * @param chartIndex 
	 * @param state
	 * @return the data to plot
	 */
	public double[] getDataValues(String id, int chartIndex, int state) {
		List<double[][]> dataList = selectedData.get(id);
		double[][] data = dataList.get(chartIndex);
		// pick the right data for the right chart
		return data[state];
	}

	/**
	 * Returns the regression data (x = state 0, y = state 1) 
	 * for each of the state equations (chartIndex 0-3)
	 * @param id 
	 * @param chartIndex 
	 * @param state
	 * @return the data to plot
	 */
	public double[] getRegressionValues(String id, int chartIndex, int state) {
		List<double[][]> dataList = regressionData.get(id);
		double[][] data = dataList.get(chartIndex);
		// pick the right data for the right chart
		return data[state];
	}

	/**
	 * Returns the fitted data (x = state 0, y = state 1) 
	 * for each of the state equations (chartIndex 0-3)
	 * @param id 
	 * @param chartIndex 
	 * @param state
	 * @return the data to plot
	 */
	public double[] getFittedValues(String id, int chartIndex, int state) {
		List<double[][]> dataList = fittedData.get(id);
		double[][] data = dataList.get(chartIndex);
		// pick the right data for the right chart
		return data[state];
	}

	/**
	 * validate the key
	 * @param id
	 * @return true if valid
	 */
	public boolean validDataID(String id) {
		boolean retVal = false;
		if ((id != null)&&(selectedData.containsKey(id))) retVal = true;
		return retVal;
	}

	/**
	 * Returns the location IDs for which we analyzed data and
	 * stored the lists of selected data
	 * @return the location keys
	 */
	public String[] getDataLocations() {
		Set<String> keys = selectedData.keySet();
		// pick the right data for the right chart
		String[] ids = new String[keys.size()];
		Iterator<String> iter = keys.iterator();
		int i = 0;
		while(iter!=null&&iter.hasNext()) {
			ids[i] = iter.next();
			i++;
		}
		Arrays.sort(ids);
		return ids;
	}



	/**
	 * Return the parameters
	 * @return Map<String, Parameter> The parameters
	 */

	public Map<String, Parameter> getParameters() {
		return this.parameters;
	}

	/**
	 * Returns the specified parameter
	 * @param p The parameter name
	 * @return Parameter 
	 */

	public Parameter getParameter(String p) {
		return this.parameters.get(p);
	}
	/**
	 * containsParameter Check if the given parameter is in this model
	 * 
	 * @param p The parameter
	 * @return boolean True if p is in the model
	 */

	public boolean containsParameter(String p) {
		return this.parameters.containsKey(p);
	}
	/**
	 * return values as a string
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();

		for(Parameter parm:this.parameters.values()) {
			buffer.append(parm.name).append("=").append(parm.value).append("\n");
			buffer.append("deviation(").append(parm.name).append(")").append("=").append(parm.stddev).append("\n");
			buffer.append("variance(").append(parm.name).append(")").append("=").append(parm.variance).append("\n");	
		}		
		return buffer.toString();
	} 

}
