ObjFuncs.java [src/java/util] Revision: default Date:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package util;
import oms3.ObjectiveFunction;
/**
*
* @author od
*/
public class ObjFuncs {
/**
*
*/
public static class PBIAS implements ObjectiveFunction {
@Override
public double calculate(double[] obs, double[] sim, double missing) {
if (sim.length != obs.length) {
throw new IllegalArgumentException("obs/sim length differ: " + obs.length + "!=" + sim.length);
}
double diffsum = 0;
double obssum = 0;
for (int i = 0; i < sim.length; i++) {
if (obs[i] > missing) {
diffsum += sim[i] - obs[i];
obssum += obs[i];
}
}
return (diffsum / obssum) * 100.0;
}
@Override
public boolean positiveDirection() {
return false;
}
}
/**
*
*/
public static class NSLOG1P implements ObjectiveFunction {
@Override
public double calculate(double[] obs, double[] sim, double missing) {
if (sim.length != obs.length) {
throw new IllegalArgumentException("obs/sim length differ: " + obs.length + "!=" + sim.length);
}
/**
* calculating logarithmic values of both data sets. Sets 0 if data is 0
*/
int valid = 0;
double avg = 0.0;
for (int i = 0; i < sim.length; i++) {
if (sim[i] >= 0.0 && obs[i] >= 0.0) {
// summing up
avg += Math.log1p(obs[i]);
valid++;
}
}
if (valid < 2) {
return Double.NEGATIVE_INFINITY;
}
// calculating mean
avg /= valid;
// calculating mean pow deviations
double rmse = 0.0;
double e = 0.0;
for (int i = 0; i < sim.length; i++) {
if (sim[i] >= 0 && obs[i] >= 0) {
double l1po = Math.log1p(obs[i]);
rmse += Math.pow(Math.abs(l1po - Math.log1p(sim[i])), 2);
e += Math.pow(Math.abs(l1po - avg), 2);
}
}
double r = 1 - (rmse / e);
return Double.isNaN(r) ? 0.0 : r;
}
@Override
public boolean positiveDirection() {
return true;
}
}
/**
*
*/
public static class NSLOG2 implements ObjectiveFunction {
@Override
public double calculate(double obs[], double sim[], double missing) {
if (obs.length != sim.length) {
throw new IllegalArgumentException("obs/sim length differ: " + obs.length + "!=" + sim.length);
}
double pow = 2;
double rsme = 0;
double var = 0;
double avg = 0;
double count = 0;
for (int i = 0; i < obs.length; i++) {
if (obs[i] > 0 && obs[i] != missing) {
avg += Math.log(obs[i]);
count += 1;
}
}
avg /= count;
for (int i = 0; i < obs.length; i++) {
if (obs[i] > 0 && sim[i] > 0 && obs[i] != missing) {
rsme += Math.pow(Math.abs(Math.log(obs[i]) - Math.log(sim[i])), pow);
var += Math.pow(Math.abs(Math.log(obs[i]) - avg), pow);
}
}
double result = 1.0 - (rsme / var);
if (Double.isNaN(result)) {
result = 0;
}
return result;
}
@Override
public boolean positiveDirection() {
return true;
}
}
/**
* KGE 2012
*/
public static class KGE implements ObjectiveFunction {
@Override
public double calculate(double obs[], double sim[], double missing) {
if (obs.length != sim.length) {
throw new IllegalArgumentException("obs/sim length differ: " + obs.length + "!=" + sim.length);
}
int contamedia = 0;
double sommamediaoss = 0;
double sommamediasim = 0;
for (int i = 0; i < obs.length; i++) {
if (obs[i] > missing) {
contamedia++;
sommamediaoss += obs[i];
sommamediasim += sim[i];
}
}
double mediaoss = sommamediaoss / contamedia;
double mediasim = sommamediasim / contamedia;
int count = 0;
double numvaprev = 0;
double coef1_den = 0;
double numR = 0;
double den1R = 0;
double den2R = 0;
for (int i = 0; i < obs.length; i++) {
if (obs[i] > missing) {
count++;
coef1_den += (obs[i] - mediaoss) * (obs[i] - mediaoss);
numR += (obs[i] - mediaoss) * (sim[i] - mediasim);
den1R += (obs[i] - mediaoss) * (obs[i] - mediaoss);
den2R += (sim[i] - mediasim) * (sim[i] - mediasim);
numvaprev += (sim[i] - mediasim) * (sim[i] - mediasim);
}
}
double sdosservati = Math.sqrt(coef1_den / (count - 1));
double sdsimulati = Math.sqrt(numvaprev / (count - 1));
double R = numR / (Math.sqrt(den1R) * Math.sqrt(den2R));
//double alpha = sdsimulati / sdosservati; // 2009
double beta = mediasim / mediaoss;
double gamma = (mediaoss * sdsimulati) / (sdosservati * mediasim); // 2012
//return 1 - Math.sqrt((R - 1) * (R - 1) + (alpha - 1) * (alpha - 1) + (beta - 1) * (beta - 1)); // 2009
return 1 - Math.sqrt((R - 1) * (R - 1) + (gamma - 1) * (gamma - 1) + (beta - 1) * (beta - 1)); // 2012
}
@Override
public boolean positiveDirection() {
return true;
}
}
}