/* nag_tsa_varma_diagnostic (g13dsc) Example Program.
 *
 * Copyright 2014 Numerical Algorithms Group.
 *
 * Mark 8, 2004.
 */

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

int main(void)
{
  /* Scalars */
  double          cgetol, chi, rlogl, siglev;
  Integer         exit_status = 0, i, icm, idf, kmax, ip, iprint, iq, pdrcm,
                  ishow;
  Integer         j, k, m, maxcal, n, niter, npar;
  Nag_Boolean     exact;
  Nag_IncludeMean mean;
  /* Arrays */
  char            nag_enum_arg[40];
  double          *cm = 0, *g = 0, *par = 0, *qq = 0, *r0 = 0, *r = 0;
  double          *rcm = 0, *v = 0, *w = 0;
  Integer         *iw = 0;
  /* Nag types */
  Nag_Boolean     *parhld = 0;
  NagError        fail;

#define W(I, J)  w[(J - 1) * kmax + I - 1]
#define QQ(I, J) qq[(J - 1) * kmax + I - 1]

  INIT_FAIL(fail);

  printf("nag_tsa_varma_diagnostic (g13dsc) Example Program Results\n");
  fflush(stdout);

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

  if (k > 0 && n >= 3)
    {
      kmax = k;
      /* Allocate memory */
      if (!(qq = NAG_ALLOC(k * kmax, double)) ||
          !(r0 = NAG_ALLOC(k * kmax, double)) ||
          !(v = NAG_ALLOC(n * kmax, double)) ||
          !(w = NAG_ALLOC(n * kmax, double)))
        {
          printf("Allocation failure\n");
          exit_status = -1;
          goto END;
        }
    }
  else
    {
      printf("Invalid parameter values\n");
      exit_status = -1;
      goto END;
    }

  for (i = 1; i <= k; ++i)
    {
      for (j = 1; j <= n; ++j)
        {
          scanf("%lf", &W(i, j));
        }
    }
  scanf("%*[^\n]");
  scanf("%ld%ld %39s %ld%*[^\n] ", &ip, &iq,
        nag_enum_arg, &m);
  /* nag_enum_name_to_value (x04nac).
   * Converts NAG enum member name to value
   */
  mean = (Nag_IncludeMean) nag_enum_name_to_value(nag_enum_arg);
  if (ip >= 0 && iq >= 0)
    {
      npar = (ip + iq) * k * k;
      if (mean == Nag_MeanInclude)
        {
          npar += k;
        }
      icm = npar;
      pdrcm = m * k * k;
    }
  else
    {
      printf("Invalid parameter values\n");
      exit_status = -1;
      goto END;
    }

  /* Allocate memory */
  if (!(cm = NAG_ALLOC(npar * icm, double)) ||
      !(g = NAG_ALLOC(npar, double)) ||
      !(par = NAG_ALLOC(npar, double)) ||
      !(r = NAG_ALLOC(k * k * m, double)) ||
      !(rcm = NAG_ALLOC(m*k*k * pdrcm, double)) ||
      !(parhld = NAG_ALLOC(npar, Nag_Boolean)))
    {
      printf("Allocation failure\n");
      exit_status = -1;
      goto END;
    }

  for (i = 1; i <= npar; ++i)
    {
      par[i-1] = 0.0;
      parhld[i-1] = Nag_FALSE;
    }

  for (j = 1; j <= k; ++j)
    {
      for (i = j; i <= k; ++i)
        {
          QQ(i, j) = 0.0;
        }
    }
  parhld[2] = Nag_TRUE;
  exact = Nag_TRUE;
  /* ** Set iprint > 0 to obtain intermediate output ** */
  iprint = -1;
  cgetol = 1.0e-4;
  maxcal = npar * 40 * (npar + 5);
  ishow = 2;

  /* nag_tsa_varma_estimate (g13ddc).
   * Multivariate time series, estimation of VARMA model
   */
  fflush(stdout);
  nag_tsa_varma_estimate(k, n, ip, iq, mean, par, npar, qq, kmax, w, parhld,
                         exact, iprint, cgetol, maxcal, ishow, 0, &niter,
                         &rlogl, v, g, cm, icm, &fail);
  if (fail.code != NE_NOERROR)
    {
      printf("\n nag_tsa_varma_estimate (g13ddc) message: %s\n\n",
              fail.message);
      exit_status = 1;
      goto END;
    }

  if (fail.code == NE_NOERROR || fail.code == NE_G13D_MAXCAL ||
      fail.code == NE_MAX_LOGLIK || fail.code == NE_G13D_BOUND ||
      fail.code == NE_G13D_DERIV ||
      fail.code == NE_HESS_NOT_POS_DEF)
    {
      printf("\nOutput from nag_tsa_varma_diagnostic (g13dsc)\n");
      fflush(stdout);
      ishow = 1;
      /* nag_tsa_varma_diagnostic (g13dsc).
       * Multivariate time series, diagnostic checking of
       * residuals, following nag_tsa_varma_estimate (g13ddc)
       */
      nag_tsa_varma_diagnostic(k, n, v, k, ip, iq, m, par, parhld, qq, ishow,
                               0, r0, r, rcm, pdrcm, &chi, &idf, &siglev,
                               &fail);
      if (fail.code != NE_NOERROR)
        {
          printf("nag_tsa_varma_diagnostic (g13dsc) message: %s\n\n",
                  fail.message);
          exit_status = 1;
        }
    }

 END:
  NAG_FREE(cm);
  NAG_FREE(g);
  NAG_FREE(par);
  NAG_FREE(qq);
  NAG_FREE(r0);
  NAG_FREE(r);
  NAG_FREE(rcm);
  NAG_FREE(v);
  NAG_FREE(w);
  NAG_FREE(iw);
  NAG_FREE(parhld);

  return exit_status;
}