MNS.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 a test data set and a verification data set
 * after Advances in Geosciences, 5, 89–97, 2005 SRef-ID:
 * 1680-7359/adgeo/2005-5-89 European Geosciences Union © 2005 Author(s). This
 * work is licensed under a Creative Commons License. Advances in Geosciences
 * Comparison of different efficiency criteria for hydrological model assessment
 * P. Krause, D. P. Boyle, and F. Base Received: 7 January 2005 – Revised: 1
 * August 2005 – Accepted: 1 September 2005 – Published: 16 December 2005
 */
class MNS extends ObjFunc {

    @Override
    public String name() {
        return "Modified Nash Sutcliffe";
    }

    @Override
    public double eval(double[] obs, double[] sim, double missing) {
        checkArrays(sim, obs);
        int pre_size = sim.length;
        int steps = pre_size;
        double sum_vd = 0;
        int size = 0;

        for (int i = 0; i < obs.length; i++) {
            if (obs[i] > missing) {
                sum_vd += obs[i];
                size++;
            }
        }
        if (size == 0) {
            throw new RuntimeException("No valid observed values.");
        }
        double mean_vd = sum_vd / size;

        /*
         * calculating mean deviations
         */
        double td_vd = 0;
        double vd_mean = 0;
        for (int i = 0; i < steps; i++) {
            if (obs[i] > missing) {
                td_vd += Math.abs(obs[i] - sim[i]);
                vd_mean += Math.abs(obs[i] - mean_vd);
            }
        }
        if (Double.compare(vd_mean, 0.0) == 0) {
            throw new RuntimeException("No valid mean values.");
        }
        return 1 - (td_vd / vd_mean);

    }

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

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

}