NS2LOG.java [src/csip/cosu] Revision: Date:
/*
* $Id$
*
* This file is part of the Cloud Services Integration Platform (CSIP),
* a Model-as-a-Service framework, API and application suite.
*
* 2012-2022, Olaf David and others, OMSLab, Colorado State University.
*
* OMSLab licenses this file to you under the MIT license.
* See the LICENSE file in the project root for more information.
*/
package csip.cosu;
/**
* Calculates the efficiency between the log values of a test data set and a
* verification data set after Nash & Sutcliffe (1970). The efficiency is
* described as the proportion of the cumulated cubic deviation between both
* data sets and the cumulated cubic deviation between the verification data
* set and its mean value.
*/
class NS2LOG extends ObjFunc {
@Override
public String name() {
return "Nash Sutcliffe";
}
@Override
public double eval(double[] obs, double[] sim, double missing) {
checkArrays(sim, obs);
int size = sim.length;
double sum_log_vd = 0;
/**
* calculating logarithmic values of both data sets. Sets 0 if data is 0
*/
double[] log_preData = new double[size];
double[] log_valData = new double[size];
int validPairs = 0;
for (int i = 0; i < size; i++) {
//either prediction or validation shows a value of zero
//in this case the pair is excluded from the further calculation,
//simply by setting the values to -1 and not increasing valid pairs
// this will also catch missing values
if (sim[i] <= 0 || obs[i] <= 0) {
log_preData[i] = -1;
log_valData[i] = -1;
}
//both prediction and validation shows a value of exact zero
//in this case the pair is taken as a perfect fit and included
//into the further calculation
if (sim[i] == 0 && obs[i] == 0) {
log_preData[i] = 0;
log_valData[i] = 0;
validPairs++;
}
//both prediction and validation are greater than zero
//no problem for the calculation
if (sim[i] > 0 && obs[i] > 0) {
log_preData[i] = Math.log(sim[i]);
log_valData[i] = Math.log(obs[i]);
validPairs++;
}
}
/*
* summing up both data sets
*/
for (int i = 0; i < size; i++) {
if (log_preData[i] >= 0) {
// sum_log_pd += log_preData[i];
sum_log_vd += log_valData[i];
}
}
/*
* calculating mean values for both data sets
*/
double mean_log_vd = sum_log_vd / validPairs;
/*
* calculating mean pow deviations
*/
double pd_log_vd = 0;
double vd_log_mean = 0;
for (int i = 0; i < size; i++) {
if (log_preData[i] >= 0) {
pd_log_vd += (Math.pow(Math.abs(log_valData[i] - log_preData[i]), 2.0));
vd_log_mean += (Math.pow(Math.abs(log_valData[i] - mean_log_vd), 2.0));
}
}
return 1 - (pd_log_vd / vd_log_mean);
}
@Override
public int direction() {
return 1;
}
@Override
public int optimum() {
return 1;
}
}