/* nag_kernel_density_estim (g10bac) Example Program.
 *
 * Copyright 2014 Numerical Algorithms Group.
 *
 * Mark 6, 2000.
 * Mark 7b revised, 2004.
 */

#include <stdio.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nagg01.h>
#include <nagg05.h>
#include <nagg10.h>

int main(void)
{

  /* Integer scalar and array declarations */
  Integer     exit_status = 0, i, increment, j, lstate;
  Integer     *state = 0, *isort = 0;

  /* NAG structures */
  NagError    fail;

  /* Double scalar and array declarations */
  double      high, low, window;
  double      *s = 0, *smooth = 0, *x = 0;

  /* Choose the base generator */
  Nag_BaseRNG genid = Nag_Basic;
  Integer     subid = 0;

  /* Set the seed */
  Integer     seed[] = { 1762543 };
  Integer     lseed = 1;

  /* Set the distribution parameters for the simulated data */
  double      xmu = 0.0e0;
  double      var = 1.0e0;

  /* Generate 1000 data points in the simulated data */
  Integer     n = 1000;

  /* Number of points at which to estimate density */
  Integer     ns = 100;

  INIT_FAIL(fail);

  printf("nag_kernel_density_estim (g10bac) Example Program Results\n");

  /* Get the length of the state array */
  lstate = -1;
  nag_rand_init_repeatable(genid, subid, seed, lseed, state, &lstate, &fail);
  if (fail.code != NE_NOERROR)
    {
      printf("Error from nag_rand_init_repeatable (g05kfc).\n%s\n",
              fail.message);
      exit_status = 1;
      goto END;
    }

  /* Allocate some memory for the arrays */
  if (!(x = NAG_ALLOC(n, double))
     || !(s = NAG_ALLOC(ns, double))
     || !(state = NAG_ALLOC(lstate, Integer))
     || !(smooth = NAG_ALLOC(ns, double))
     || !(isort = NAG_ALLOC(ns, Integer)))
    {
      printf("Allocation failure\n");
      exit_status = -1;
      goto END;
    }

  /* Initialise the generator to a repeatable sequence */
  nag_rand_init_repeatable(genid, subid, seed, lseed, state, &lstate, &fail);
  if (fail.code != NE_NOERROR)
    {
      printf("Error from nag_rand_init_repeatable (g05kfc).\n%s\n",
              fail.message);
      exit_status = 1;
      goto END;
    }

  /* Generate the variates */
  nag_rand_normal(n, xmu, var, state, x, &fail);
  if (fail.code != NE_NOERROR)
    {
      printf("Error from nag_rand_normal (g05skc).\n%s\n",
              fail.message);
      exit_status = 1;
      goto END;
    }

  /* Skip heading in data file */
  scanf("%*[^\n] ");
  /* Read in the windowing information */
  scanf("%lf ", &window);
  scanf("%lf,  %lf", &low, &high);

  /* Perform kernel density estimation */
  /* nag_kernel_density_estim (g10bac).
   * Kernel density estimate using Gaussian kernel
   */
  nag_kernel_density_estim(n, x, window, low, high, ns, smooth, s, &fail);
  if (fail.code != NE_NOERROR)
    {
      printf("Error from nag_kernel_density_estim (g10bac).\n%s\n",
              fail.message);
      exit_status = 1;
      goto END;
    }

  printf("\n   Points  Density  Points  Density  Points  "
          "Density  Points  Density\n");
  printf("           Value            Value            "
          "Value            Value\n\n");

  increment = 25;
  for (i = 1; i <= ns/4; i++)
    {
      printf("%9.4f %7.4f", s[i-1], smooth[i-1]);
      for (j = 1; j <= 3; j++)
        {
          printf("%9.4f %7.4f", s[i-1+j*increment],
                  smooth[i-1+j*increment]);
        }
      printf("\n");
    }
 END:
  NAG_FREE(x);
  NAG_FREE(s);
  NAG_FREE(smooth);
  NAG_FREE(isort);
  NAG_FREE(state);
  return exit_status;
}