/* nag_tsa_cp_binary (g13ndc) Example Program.
 *
 * Copyright 2014 Numerical Algorithms Group.
 *
 * Mark 25, 2014.
 */
/* 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];

  /* Initialise 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("%ld%*[^\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%ld%ld%*[^\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(" %4ld      %6ld    %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(" %4ld       %6ld    %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);
}