KGE09.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;

/**
 * KGE 2012
 */
class KGE09 extends ObjFunc {

    @Override
    public String name() {
        return "Klinge Gupta Efficienciy (2012)";
    }

    @Override
    public double eval(double[] obs, double[] sim, double missing) {
        checkArrays(sim, obs);
        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];
            }
        }
        if (contamedia == 0) {
            throw new RuntimeException("no valid value count in KGE");
        }
        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;
        return 1 - Math.sqrt((R - 1) * (R - 1) + (alpha - 1) * (alpha - 1) + (beta - 1) * (beta - 1)); // 2009
    }

    @Override
    public int direction() {
        return 1;
    }

    @Override
    public int optimum() {
        return 1;
    }

}