#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector ProbBinsCpp1(NumericMatrix fore, NumericVector qum) {
  int nfcyrs = fore.nrow();
  int nmembers = fore.ncol();
  int ntresh = qum.size();
  int nrows = nmembers * nfcyrs;
  int y, m, t, mbin;
  // Create the output matrix.
  NumericMatrix pbf((ntresh + 1), nrows);
  // Create a vector with extended thresholds (-INF, thresholds, INF).
  // This allows to do all heavy computation in a single loop after.
  NumericVector tresh_extended(ntresh + 2);
  tresh_extended[0] = -INFINITY;
  for (t = 0; t < ntresh; t++) {
    tresh_extended[t + 1] = qum[t];
  }
  tresh_extended[ntresh + 1] = INFINITY;

  // Computing the counts for each threshold.
  for (t = 0; t < (ntresh + 1); t++) {
    for (y = 0; y < nfcyrs; y++) {
      for (m = 0; m < nmembers; m++) {
	pbf(t, (m * nfcyrs) + y) = (int)((fore(y, m) > tresh_extended[t]) && (fore(y, m) <= tresh_extended[t + 1]));
      }
    }
  }
  return pbf;
}

// [[Rcpp::export]]
NumericVector ProbBinsCpp2(NumericMatrix fore, NumericVector qum) {
  int nfcyrs = fore.nrow();
  int nmembers = fore.ncol();
  int ntresh = qum.size();
  int y, m, t, msum;
  // Create the output matrix.
  NumericMatrix pbf(nfcyrs, (ntresh + 1));
  // Create a vector with extended thresholds (-INF, thresholds, INF).
  // This allows to do all heavy computation in a single loop after.
  NumericVector tresh_extended(ntresh + 2);
  tresh_extended[0] = -INFINITY;
  for (t = 0; t < ntresh; t++) {
    tresh_extended[t + 1] = qum[t];
  }
  tresh_extended[ntresh + 1] = INFINITY;

  // Computing the counts for each threshold.
  for (t = 0; t < (ntresh + 1); t++) {
    for (y = 0; y < nfcyrs; y++) {
      msum = 0;
      for (m = 0; m < nmembers; m++) {
        msum += (int)(fore(y, m) > tresh_extended[t]) && (fore(y, m) <= tresh_extended[t + 1]);
      }
      // here we could divide if needed
      pbf(y, t) = msum;
    }
  }
  return pbf;
}

// [[Rcpp::export]]
NumericVector ProbBinsCpp3(NumericMatrix fore, NumericVector qum) {
  int nfcyrs = fore.nrow();
  int nmembers = fore.ncol();
  int ntresh = qum.size();
  int y, m, t, msum;
  // Create the output matrix.
  NumericMatrix pbf(nfcyrs, (ntresh + 1));
  // Create a vector with extended thresholds (-INF, thresholds, INF).
  // This allows to do all heavy computation in a single loop after.
  NumericVector tresh_extended(ntresh + 2);
  tresh_extended[0] = -INFINITY;
  for (t = 0; t < ntresh; t++) {
    tresh_extended[t + 1] = qum[t];
  }
  tresh_extended[ntresh + 1] = INFINITY;

  // Computing the counts for each threshold.
  for (t = 0; t < (ntresh + 1); t++) {
    for (y = 0; y < nfcyrs; y++) {
      msum = 0;
      for (m = 0; m < nmembers; m++) {
        msum += (int)((fore(y, m) > tresh_extended[t]) && (fore(y, m) <= tresh_extended[t + 1]));
      }
      // here we could divide if needed
      pbf(y, t) = msum;
    }
  }

  return pbf / nmembers;
}

