/* nag_tsa_resid_corr (g13asc) Example Program.
 *
 * Copyright 2017 Numerical Algorithms Group.
 *
 * Mark 26.1, 2017.
 */

#include <stdio.h>
#include <string.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nagg13.h>

int main(void)
{
  Integer exit_status = 0, i, idf, j, m, *mr = 0, narma, ni, npar;
  Integer nres, nseries, nx;
  NagError fail;
  Nag_ArimaOrder arimav;
  Nag_G13_Opt options;
  Nag_TransfOrder transfv;
  double chi, df, objf, *par = 0, *r = 0, *rc = 0, *res, s, *sd = 0,
         siglev, *x = 0;

  INIT_FAIL(fail);

  printf("nag_tsa_resid_corr (g13asc) Example Program Results\n\n");

  /* Skip heading in data file */
  scanf("%*[^\n]");
  scanf("%" NAG_IFMT "%*[^\n]", &nx);
  if (!(x = NAG_ALLOC(nx, double))
      || !(mr = NAG_ALLOC(7, Integer)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }

  for (i = 1; i <= nx; ++i)
    scanf("%lf", &x[i - 1]);
  scanf("%*[^\n]");
  for (i = 1; i <= 7; ++i)
    scanf("%" NAG_IFMT "", &mr[i - 1]);
  scanf("%*[^\n]");

  npar = mr[0] + mr[2] + mr[3] + mr[5] + 1;
  if (!(par = NAG_ALLOC(npar, double))
      || !(sd = NAG_ALLOC(npar, double)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }
  for (i = 1; i <= npar; ++i)
    par[i - 1] = 0.0;

  nseries = 1;
  arimav.p = mr[0];
  arimav.d = mr[1];
  arimav.q = mr[2];
  arimav.bigp = mr[3];
  arimav.bigd = mr[4];
  arimav.bigq = mr[5];
  arimav.s = mr[6];
  /* nag_tsa_options_init (g13bxc).
   * Initialization function for option setting
   */
  nag_tsa_options_init(&options);
  /* nag_tsa_transf_orders (g13byc).
   * Allocates memory to transfer function model orders
   */
  nag_tsa_transf_orders(nseries, &transfv, &fail);
  /* nag_tsa_multi_inp_model_estim (g13bec).
   * Estimation for time series models
   */
  fflush(stdout);
  nag_tsa_multi_inp_model_estim(&arimav, nseries, &transfv, par, npar, nx, x,
                                nseries, sd, &s, &objf, &df, &options, &fail);
  nres = options.lenres;
  res = options.res;
  if (fail.code != NE_NOERROR) {
    printf("Error from nag_tsa_multi_inp_model_estim (g13bec).\n%s\n",
           fail.message);
    exit_status = 1;
    goto END;
  }

  m = 10;
  if (!(r = NAG_ALLOC(m, double))
      || !(rc = NAG_ALLOC(m * m, double)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }

  narma = mr[0] + mr[2] + mr[3] + mr[5];
  /* nag_tsa_resid_corr (g13asc).
   * Univariate time series, diagnostic checking of residuals,
   * following nag_tsa_multi_inp_model_estim (g13bec)
   */
  nag_tsa_resid_corr(&arimav, nres, res, m, par, narma, r, rc,
                     m, &chi, &idf, &siglev, &fail);
  if (fail.code != NE_NOERROR) {
    printf("Error from nag_tsa_resid_corr (g13asc).\n%s\n", fail.message);
    exit_status = 1;
    goto END;
  }
  printf("\nRESIDUAL AUTOCORRELATION FUNCTION");
  printf("\n---------------------------------\n\n");
  for (j = 0; j <= (m - 1) / 7; j++) {
    ni = MIN(7, m - j * 7);
    printf("LAG  K  ");
    for (i = 0; i < ni; i++)
      printf("%5" NAG_IFMT "  ", i + j * 7 + 1);
    printf("\nR(K)    ");
    for (i = 0; i < ni; i++)
      printf("%7.3f", r[i + j * 7]);
    printf("\nST.ERROR");
    for (i = 0; i < ni; i++)
      printf("%7.3f", rc[(m + 1) * (i + j * 7)]);
    printf("\n---------------------------------------------------------\n");
  }
  /* nag_tsa_free (g13xzc).
   * Freeing function for use with g13 option setting
   */
  nag_tsa_free(&options);

END:
  NAG_FREE(x);
  NAG_FREE(mr);
  NAG_FREE(par);
  NAG_FREE(sd);
  NAG_FREE(r);
  NAG_FREE(rc);
  return exit_status;
}