/* nag_modwt (c09dac) Example Program.
 *
 * Copyright 2014 Numerical Algorithms Group.
 *
 * Mark 24, 2013.
 */
/* Pre-processor includes */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nagc09.h>

int main(void)
{
  /* Constants */
  Integer         licomm = 100;
  /*Integer scalar and array declarations */
  Integer         exit_status = 0;
  Integer         i, n, nf, nwc, nwl;
  Integer         *icomm = 0;
  NagError        fail;
  Nag_Wavelet     wavnamenum;
  Nag_WaveletMode modenum;
  /*Double scalar and array declarations */
  double          *ca = 0, *cd = 0, *x = 0, *y = 0;
  /*Character scalar and array declarations */
  char            mode[24], wavnam[20];

  INIT_FAIL(fail);

  printf("nag_modwt (c09dac) Example Program Results\n\n");
  fflush(stdout);

  /*     Skip heading in data file*/
  scanf("%*[^\n] ");
  /*     Read n*/
  scanf("%ld%*[^\n] ", &n);
  if (!(x = NAG_ALLOC(n, double)) ||
      !(y = NAG_ALLOC(n, double)) ||
      !(icomm = NAG_ALLOC(licomm, Integer)))
    {
      printf("Allocation failure\n");
      exit_status = -1;
      goto END;
    }
  /*     Read wavnam, mode*/
  scanf("%19s%23s%*[^\n] ", wavnam, mode);
  /*
   * nag_enum_name_to_value (x04nac).
   * Converts NAG enum member name to value
   */
  wavnamenum = (Nag_Wavelet) nag_enum_name_to_value(wavnam);
  modenum = (Nag_WaveletMode) nag_enum_name_to_value(mode);
  if (n >= 2)
    {
      printf("MODWT :: \n");
      printf("     Wavelet  :%16s\n", wavnam);
      printf("     End mode :%16s\n", mode);
      printf("     N        :%16ld\n\n", n);
      /*        Read array*/
      printf("%s\n", "Input Data                  X :");
      for (i = 0; i < n; i++)
        {
          scanf("%lf ", &x[i]);
          printf("%8.4f%s", x[i], (i+1)%8?" ":"\n");
        }
      printf("\n");
      /*
       * nag_wfilt (c09aac)
       * Wavelet filter query
       */
      nag_wfilt(wavnamenum, Nag_MODWTSingle, modenum, n, &nwl, &nf, &nwc,
                icomm, &fail);
      if (fail.code != NE_NOERROR)
        {
          printf("Error from nag_wfilt (c09aac).\n%s\n", fail.message);
          exit_status = 1;
          goto END;
        }
      if (!(ca = NAG_ALLOC(nwc, double)) ||
          !(cd = NAG_ALLOC(nwc, double)))
        {
          printf("Allocation failure\n");
          exit_status = -1;
          goto END;
        }
      /*
       * nag_modwt (c09dac)
       * one-dimensional discrete wavelet transform (modwt)
       */
      nag_modwt(n, x, nwc, ca, cd, icomm, &fail);
      if (fail.code != NE_NOERROR)
        {
          printf("Error from nag_modwt (c09dac).\n%s\n", fail.message);
          exit_status = 1;
          goto END;
        }

      printf("Approximation coefficients CA : \n");
      for (i = 0; i < nwc; i++)
        printf("%8.4f%s", ca[i], (i+1)%8?" ":"\n");
      printf("\n");
      printf("Detail coefficients        CD : \n");
      for (i = 0; i < nwc; i++)
        printf("%8.4f%s", cd[i], (i+1)%8?" ":"\n");
      printf("\n\n");
      /*
       * nag_imodwt (c09dbc)
       * one-dimensional inverse discrete wavelet transform (IMODWT)
       */
      nag_imodwt(nwc, ca, cd, n, y, icomm, &fail);
      if (fail.code != NE_NOERROR)
        {
          printf("Error from nag_imodwt (c09dbc).\n%s\n", fail.message);
          exit_status = 1;
          goto END;
        }
      printf("Reconstruction              Y : \n");
      for (i = 0; i < n; i++)
        printf("%8.4f%s", y[i], (i+1)%8?" ":"\n");
    }

 END:
  NAG_FREE(ca);
  NAG_FREE(cd);
  NAG_FREE(x);
  NAG_FREE(y);
  NAG_FREE(icomm);

  return exit_status;
}