/* nag_tsa_cp_binary (g13ndc) Example Program.
 *
 * NAGPRODCODE Version.
 *
 * Copyright 2016 Numerical Algorithms Group.
 *
 * Mark 26, 2016.
 */
/* Pre-processor includes */
#include <stdio.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nagg13.h>

int main(void)
{
  /* Integer scalar and array declarations */
  Integer i, minss, n, ntau, mdepth;
  Integer exit_status = 0;
  Integer *tau = 0;

  /* NAG structures and types */
  NagError fail;
  Nag_TS_ChangeType ctype;
  Nag_Boolean param_supplied;

  /* Double scalar and array declarations */
  double beta;
  double *param = 0, *sparam = 0, *y = 0;

  /* Character scalar and array declarations */
  char cctype[40], cparam_supplied[40];

  /* Initialize the error structure */
  INIT_FAIL(fail);

  printf("nag_tsa_cp_binary (g13ndc) Example Program Results\n\n");

  /* Skip heading in data file */
  scanf("%*[^\n] ");

  /* Read in the problem size */
  scanf("%" NAG_IFMT "%*[^\n] ", &n);

  /* Allocate memory to hold the input series */
  if (!(y = NAG_ALLOC(n, double)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }

  /* Read in the input series */
  for (i = 0; i < n; i++) {
    scanf("%lf", &y[i]);
  }
  scanf("%*[^\n] ");

  /* Read in the type of change point, penalty, minimum segment size */
  /* and maximum depth */
  scanf("%39s%39s%lf%" NAG_IFMT "%" NAG_IFMT "%*[^\n] ", cctype,
        cparam_supplied, &beta, &minss, &mdepth);
  ctype = (Nag_TS_ChangeType) nag_enum_name_to_value(cctype);
  param_supplied = (Nag_Boolean) nag_enum_name_to_value(cparam_supplied);

  /* Read in the distribution parameter (if required) */
  if (param_supplied) {
    if (!(param = NAG_ALLOC(1, double)))
    {
      printf("Allocation failure\n");
      exit_status = -1;
      goto END;
    }
    scanf("%lf", &param[0]);
    scanf("%*[^\n] ");
  }

  /* Allocate output arrays */
  if (!(tau = NAG_ALLOC(n, Integer)) ||
      !(sparam = NAG_ALLOC(2 * n + 2, double)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }

  /* Call nag_tsa_cp_binary (g13ndc) to to detect change points */
  nag_tsa_cp_binary(ctype, n, y, beta, minss, param, mdepth, &ntau, tau,
                    sparam, &fail);
  if (fail.code != NE_NOERROR) {
    if (fail.code != NW_TRUNCATED) {
      printf("Error from nag_tsa_cp_binary (g13ndc).\n%s\n", fail.message);
      exit_status = 1;
      goto END;
    }
  }

  /* Display the results */
  if (ctype == Nag_ExponentialLambda || ctype == Nag_PoissonLambda) {
    /* Exponential or Poisson distribution */
    printf("  -- Change Points --      Distribution\n");
    printf("   Number     Position      Parameter\n");
    printf(" ======================================\n");
    for (i = 0; i < ntau; i++) {
      printf(" %4" NAG_IFMT "      %6" NAG_IFMT "    %12.2f\n",
             i + 1, tau[i], sparam[i]);
    }
  }
  else {
    /* Normal or Gamma distribution */
    printf("  -- Change Points --         --- Distribution ---\n");
    printf("  Number     Position              Parameters\n");
    printf(" ==================================================\n");
    for (i = 0; i < ntau; i++) {
      printf(" %4" NAG_IFMT "       %6" NAG_IFMT "    %12.2f    %12.2f\n",
             i + 1, tau[i], sparam[2 * i], sparam[2 * i + 1]);
    }
  }
  if (fail.code == NW_TRUNCATED) {
    printf("Some truncation occurred internally to avoid overflow.\n");
  }

END:
  NAG_FREE(y);
  NAG_FREE(param);
  NAG_FREE(tau);
  NAG_FREE(sparam);

  return (exit_status);
}