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

/**
 *
 */
class NSLOG1P extends ObjFunc {

  @Override
  public String name() {
    return "NSLOG1P";
  }


  @Override
  public double eval(double[] obs, double[] sim, double missing) {
    checkArrays(obs, sim);
    /**
     * 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);
      }
    }
    if (Double.compare(e, 0.0) == 0)
      throw new RuntimeException("No valid e values.");
    double r = 1 - (rmse / e);
    return Double.isNaN(r) ? 0.0 : r;
  }


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


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

}