/* nag_rand_sample_unequal (g05nec) Example Program.
 *
 * NAGPRODCODE Version.
 *
 * Copyright 2016 Numerical Algorithms Group.
 *
 * Mark 26, 2016.
 */

#include <nag.h>
#include <nag_stdlib.h>
#include <nagg05.h>

int main(void)
{
  /* Scalars */
  Integer exit_status = 0, lseed = 1;
  Integer i, lstate, m, n, subid;

  /* Arrays */
  Integer *ipop = 0, *isampl = 0, *state = 0;
  Integer seed[1];
  double *wt = 0;
  char cgenid[40], csortorder[40], cpop_supplied[40];

  /* NAG structures */
  NagError fail;
  Nag_BaseRNG genid;
  Nag_SortOrder sortorder;
  Nag_Boolean pop_supplied;

  /* Initialize the error structure to print out any error messages */
  INIT_FAIL(fail);

  printf("nag_rand_sample_unequal (g05nec) Example Program Results\n\n");

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

  /* Read in the base generator information and seed */
  scanf("%39s%" NAG_IFMT "%" NAG_IFMT "%*[^\n] ", cgenid, &subid, &seed[0]);
  genid = (Nag_BaseRNG) nag_enum_name_to_value(cgenid);

  /* Query to obtain the length of the state array using
   * nag_rand_init_repeatable (g05kfc).
   */
  lstate = 0;
  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 memory to state */
  if (!(state = NAG_ALLOC(lstate, Integer)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }

  /* Initialize the RNG using 
   * nag_rand_init_repeatable (g05kfc)
   */
  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 = 2;
    goto END;
  }

  /* Read in the problem size, pop_supplied is a True / False flag indicating
   * whether population flags are supplied (Nag_TRUE) or taken as the integers
   * 1 to n (Nag_FALSE)
   */
  scanf("%" NAG_IFMT "%" NAG_IFMT "%39s%39s%*[^\n] ", &n, &m, csortorder,
        cpop_supplied);
  sortorder = (Nag_SortOrder) nag_enum_name_to_value(csortorder);
  pop_supplied = (Nag_Boolean) nag_enum_name_to_value(cpop_supplied);

  /* Allocate memory for input arrays */
  if (!(wt = NAG_ALLOC(n, double)) || !(isampl = NAG_ALLOC(m, Integer))
         )
  {
    printf("Allocation failure\n");
    exit_status = -2;
    goto END;
  }

  if (pop_supplied) {
    /* Read in the population and weights */
    if (!(ipop = NAG_ALLOC(n, Integer)))
    {
      printf("Allocation failure\n");
      exit_status = -3;
      goto END;
    }
    for (i = 0; i < n; i++)
      scanf("%" NAG_IFMT "%lf%*[^\n] ", &ipop[i], &wt[i]);
  }
  else {
    /* Read in just the weights */
    for (i = 0; i < n; i++)
      scanf("%lf%*[^\n] ", &wt[i]);
  }

  /* Generate the sample without replacement, unequal weights using
   * nag_rand_sample_unequal (g05nec)
   */
  nag_rand_sample_unequal(sortorder, wt, ipop, n, isampl, m, state, &fail);
  if (fail.code != NE_NOERROR) {
    printf("Error from nag_rand_sample_unequal (g05nec).\n%s\n",
           fail.message);
    exit_status = 3;
    goto END;
  }

  /* Display the results */
  for (i = 0; i < m; i++)
    printf("%5" NAG_IFMT "", isampl[i]);
  printf("\n");

END:
  NAG_FREE(wt);
  NAG_FREE(ipop);
  NAG_FREE(isampl);
  NAG_FREE(state);

  return exit_status;
}