Calc.java [src/java/crp/utils] 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 crp.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Utilities
 *
 * @TODO: GoF https://en.wikipedia.org/wiki/Goodness_of_fit
 * @author Francesco Serafin, Andre Dozier
 */
public class Calc {

  /**
   * Peak weighted root mean squared error
   *
   * @param obs
   * @param sim
   * @param missingValue
   * @return
   */
  public static double pwrmse(double[] obs, double[] sim, double missingValue) {
    sameArrayLen(obs, sim);
    double obsAvg = average(obs, missingValue);
    double twoObsAvg = obsAvg * 2;
    double error = 0.0;
    int count = 0;

    for (int i = 0; i < obs.length; i++) {
      if (obs[i] > missingValue) {
        double firstTerm = Math.pow((obs[i] - sim[i]), 2);
        double secondTerm = (obs[i] + obsAvg) / twoObsAvg;
        error += firstTerm * secondTerm;
        count++;
      }
    }
    return Math.sqrt(error / count);
  }


  public static double modelDeviation(double[] obs, double[] sim, double missingValue) {
    sameArrayLen(obs, sim);
    double obsSum = 0.0;
    double simSum = 0.0;

    for (int i = 0; i < obs.length; i++) {
      if (obs[i] > missingValue) {
        obsSum += obs[i];
        simSum += sim[i];
      }
    }
    return simSum / obsSum;
  }


  /**
   * Check if the arrays have the same length
   *
   * @param arr
   */
  private static void sameArrayLen(double[]... arr) {
    int len = arr[0].length;
    for (double[] a : arr) {
      if (a.length != len) {
        throw new IllegalArgumentException("obs and sim data have not same size (" + a.length + "/" + len + ")");
      }
    }
  }


  private static double average(double[] val, double missingValue) {
    double tmpval = 0.0;
    int count = 0;
    for (int i = 0; i < val.length; i++) {
      if (val[i] > missingValue) {
        tmpval += val[i];
        count++;
      }
    }
    return tmpval / count;
  }


  public static double denormalize(double val, double min, double max, double norm_min, double norm_max) {
    double numerator = (val * (min - max)) - (norm_max * min) + (norm_min * max);
    double denumerator = norm_min - norm_max;
    return numerator / denumerator;
  }


  public static double normalize(double val, double min, double max, double norm_min, double norm_max) {
    checkMinMax(val, min, max); // precondition
    double numerator = (val - min) * (norm_max - norm_min);
    double denumerator = max - min;
    return norm_min + (numerator / denumerator);
  }


  public static double[] toDoubleArray(List<Double> data) {
    return data.stream().mapToDouble(Double::doubleValue).toArray();
  }


  public static int[] toIntArray(List<Integer> list) {
    return list.stream().mapToInt(Integer::intValue).toArray();
  }


  private static void checkMinMax(double val, double min, double max) {
    if (val < min) {
      String msg = "Value: " + val + " is smaller than min " + min;
      throw new IllegalArgumentException(msg);
    }
    if (val > max) {
      String msg = "Value: " + val + " is bigger than max " + max;
      throw new IllegalArgumentException(msg);
    }
  }


  /**
   * Creates a a list with all combinations of tuples from vals
   *
   * @param vals the list of string
   * @return combination of elements in vals (C (vals.size(), 2)). Each string
   * array has the length of two.
   */
  public static List<String[]> comb(List<String> vals) {
    List<String[]> l = new ArrayList<>();
    for (int i = 0; i < vals.size(); i++) {
      for (int j = i + 1; j < vals.size(); j++) {
        l.add(new String[]{vals.get(i), vals.get(j)});
      }
    }
    return l;
  }


  /**
   * Creates a a list with all combinations of tuples from in/out
   *
   * @param in
   * @param out
   * @return combination of elements in vals (C (vals.size(), 2)). Each string
   * array has the length of two.
   */
  public static List<String[]> comb(List<String> in, List<String> out) {
    List<String[]> l = new ArrayList<>();
    for (int i = 0; i < in.size(); i++) {
      for (int j = 0; j < out.size(); j++) {
        l.add(new String[]{in.get(i), out.get(j)});
      }
    }
    return l;
  }


  public static void main(String[] args) {
    List<String> s = Arrays.asList("1", "2", "3", "4", "5", "6", "7");
    List<String> s1 = Arrays.asList("10", "20", "30");
    List<String[]> l = comb(s, s1);
    for (String[] st : l) {
      System.out.println(st[0] + "-" + st[1]);
    }
    System.out.println("---" + l.size());
  }

}