blob: 94cd74633dd2a0d2927f1503078ec263ad7b91ae [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 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
*******************************************************************************/
package org.eclipse.stem.analysis.impl;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.stem.analysis.AnalysisFactory;
import org.eclipse.stem.analysis.AnalysisPackage;
import org.eclipse.stem.analysis.ErrorResult;
import org.eclipse.stem.analysis.ReferenceScenarioDataMap;
import org.eclipse.stem.analysis.ThresholdErrorFunction;
import org.eclipse.stem.analysis.impl.ReferenceScenarioDataMapImpl.ReferenceScenarioDataInstance;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>Threshold Error Function</b></em>'.
* <!-- end-user-doc -->
* <p>
* </p>
*
* @generated
*/
public class ThresholdErrorFunctionImpl extends ErrorFunctionImpl implements ThresholdErrorFunction {
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public ThresholdErrorFunctionImpl() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass() {
return AnalysisPackage.Literals.THRESHOLD_ERROR_FUNCTION;
}
/**
* Timeseries data for both data sets with common locations
*/
Map<String,List<Double>> commonInfectiousLocationsA = new HashMap<String,List<Double>>();
Map<String,List<Double>> commonInfectiousLocationsB = new HashMap<String,List<Double>>();
/**
* Max infectious per location
*/
Map<String,Double> maxInfA = new HashMap<String,Double>();
Map<String,Double> maxInfB = new HashMap<String,Double>();
/**
* The Result
*/
public double[] meanSqDiff;
/*
* time
*/
public double[] time;
protected AnalysisFactory aFactory = new AnalysisFactoryImpl();
// This is the threshold of the maximum peak for both data sets
// where we consider the error
protected static double THRESHOLD = 0.1;
/**
* calculate delta for a threshold error function
*
*
* @override
*/
public ErrorResult calculateError(ReferenceScenarioDataMap reference, ReferenceScenarioDataMap data) {
final ReferenceScenarioDataMapImpl _ref = (ReferenceScenarioDataMapImpl)reference;
final ReferenceScenarioDataMapImpl _data = (ReferenceScenarioDataMapImpl)data;
double denominator = 0.0;
// Clear
time = null;
Iterator<String> iteratorA = _ref.getLocations().iterator();
int maxTime = -1;
while(iteratorA.hasNext()) {
String id = iteratorA.next();
if(_data.containsLocation(id)) {
// get the lists of data only for those locations that are common to both maps ReferenceScenarioDataInstance dataMapA = mapA.getLocation(id);
ReferenceScenarioDataInstance dataMapA = _ref.getLocation(id);
List<Double> dataAI = getInfectious(dataMapA);
commonInfectiousLocationsA.put(id,dataAI);
// Map B
ReferenceScenarioDataInstance dataMapB = _data.getLocation(id);
List<Double> dataBI = getInfectious(dataMapB);
commonInfectiousLocationsB.put(id,dataBI);
// Find the peak in both data sets and remember. It will be used
// to determine the threshold
double maxA = -1;
for(double d : dataAI) if(d > maxA) maxA = d;
double maxB = -1;
for(double d : dataBI) if(d > maxB) maxB = d;
maxInfA.put(id, maxA);
maxInfB.put(id, maxB);
// init the array size
if (maxTime == -1) maxTime = dataAI.size();
// dimension the arrays to the length of the SMALLEST array for which we have data
if(maxTime >= dataBI.size() ) maxTime = dataBI.size();
if(maxTime >= dataAI.size() ) maxTime = dataAI.size();
}// if
}// while
if(maxTime<=0) maxTime = 0;
if(time==null) {
time = new double[maxTime];
meanSqDiff = new double[maxTime];
for(int i = 0; i < maxTime; i ++) {
time[i] = i;
meanSqDiff[i] = 0.0;
}
}
// Now figure out the actual error
double[] maxPopulation = new double[time.length];
for(int icount =0; icount < time.length; icount ++) {
maxPopulation[icount] = 0.0;
Iterator<String> iter = commonInfectiousLocationsA.keySet().iterator();
////////////////////////
// all locations
while(iter.hasNext()) {
String id = iter.next();
List<Double> dataAI = commonInfectiousLocationsA.get(id);
List<Double> dataBI = commonInfectiousLocationsB.get(id);
double iA = dataAI.get(icount).doubleValue();
double iB = dataBI.get(icount).doubleValue();
// double denom = (iA+iB)/2.0;
// square of the average fraction of infectious people
// denom *= denom;
double maxA = maxInfA.get(id);
double maxB = maxInfB.get(id);
if ((iA > maxA*THRESHOLD) || (iB > maxB*THRESHOLD)) {
// we have a location with nonzero data
// square of the DIFFERENCE
// Changed 2/4/09. Drop the S data comparison
//double term = ((iA - iB) * (iA - iB))
// + ((sA - sB) * (sA - sB));
double term = Math.abs(iA - iB);
meanSqDiff[icount] += term;
if(iA > iB) denominator+= iA; else denominator+= iB;
}
}// all locations
////////////////////////
}// for all time
// Sum all errors and divide by time
double result = 0.0;
BasicEList<Double> list = new BasicEList<Double>();
for(int i=0;i<time.length;++i) {
meanSqDiff[i] = meanSqDiff[i] / denominator;
result += meanSqDiff[i];
list.add(meanSqDiff[i]);
}
ErrorResult resultobj = aFactory.createErrorResult();
resultobj.setErrorByTimeStep(list);
resultobj.setError(result);
return resultobj;
}
} //ThresholdErrorFunctionImpl