/* nag_rand_sample_unequal (g05nec) Example Program.
 *
 * Copyright 2014 Numerical Algorithms Group.
 *
 * Mark 23, 2011.
 */

#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;

  /* Initialise 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%ld%ld%*[^\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;
    }

  /* Initialise 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("%ld%ld%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("%ld%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("%5ld", isampl[i]);
  printf("\n");

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

  return exit_status;
}