/* This file is part of the Neper software package. */
/* Copyright (C) 2003-2014, Romain Quey. */
/* See the COPYING file in the top-level directory. */

#include"net_seed_weight_.h"

void
net_seed_weight_custom (char *filename, struct SEEDSET *pGSet)
{
  FILE *file = NULL;

  (*pGSet).SeedWeight = ut_alloc_1d ((*pGSet).N + 1);

  file = ut_file_open (filename, "R");
  ut_array_1d_fscanf (file, (*pGSet).SeedWeight + 1, (*pGSet).N);
  ut_file_close (file, filename, "R");

  return;
}

void
net_seed_weight_rand (struct SEEDSET *pGSet)
{
  int i, status, minmax;
  double mean, sig, mean1, mean2, p, min, max;
  int distribqty;
  double *distribw = NULL;
  char **distribf = NULL;
  char **distribp = NULL;
  gsl_rng *r;

  // Reading distribution functions
  net_seed_weight_rand_distrib ((*pGSet).weight, &distribf, &distribp,
				&distribw, &distribqty);

  // Assigning distribution to the seeds
  int *seedd = ut_alloc_1d_int ((*pGSet).N + 1);
  net_seed_weight_rand_seeddistrib (*pGSet, distribw, distribqty, &seedd);

  // Computing seed weights
  r = gsl_rng_alloc (gsl_rng_ranlxd2);
  gsl_rng_set (r, (*pGSet).Random - 2);

  (*pGSet).SeedWeight = ut_alloc_1d ((*pGSet).N + 1);
  for (i = 1; i <= (*pGSet).N; i++)
  {
    minmax = 0;
    int d = seedd[i];
    if (!strcmp (distribf[d], "dirac"))
    {
      status = sscanf (distribp[d], "%lf%lf%lf", &mean, &min, &max);
      if (status !=1 && status != 3)
	ut_print_message (2, 4, "Failed to process expression.\n");

      (*pGSet).SeedWeight[i] = mean;
      if (status == 3)
	minmax = 1;
    }
    else if (!strcmp (distribf[d], "gaussian"))
    {
      status = sscanf (distribp[d], "%lf%lf%lf%lf", &mean, &sig, &min, &max);
      if (status !=2 && status != 4)
	ut_print_message (2, 4, "Failed to process expression.\n");

      (*pGSet).SeedWeight[i] = mean + gsl_ran_gaussian (r, sig);

      if (status == 4)
	minmax = 1;
    }
    else if (!strcmp (distribf[d], "flat"))
    {
      status = sscanf (distribp[d], "%lf%lf%lf%lf", &mean, &sig, &min, &max);
      if (status !=2 && status != 4)
	ut_print_message (2, 4, "Failed to process expression.\n");

      (*pGSet).SeedWeight[i] =
	gsl_ran_flat (r, mean - sig / 2, mean + sig / 2);
      if (status == 4)
	minmax = 1;
    }
    else if (!strcmp (distribf[d], "bernoulli"))
    {
      status =
	sscanf (distribp[d], "%lf%lf%lf%lf%lf", &mean1, &mean2, &p, &min,
		&max);
      if (status !=3 && status != 5)
	ut_print_message (2, 4, "Failed to process expression.\n");

      if (gsl_ran_bernoulli (r, p) == 0)
	(*pGSet).SeedWeight[i] = mean1;
      else
	(*pGSet).SeedWeight[i] = mean2;

      if (status == 5)
	minmax = 1;
    }
    else
      ut_print_message (2, 0, "Distribution not known.");

    (*pGSet).SeedWeight[i] = ut_num_max ((*pGSet).SeedWeight[i], 0);

    if (minmax)
      (*pGSet).SeedWeight[i] =
	ut_num_bound ((*pGSet).SeedWeight[i], min, max);
  }

  gsl_rng_free (r);
  ut_free_1d_int (seedd);
  ut_free_1d (distribw);
  ut_free_2d_char (distribf, distribqty);
  ut_free_2d_char (distribp, distribqty);

  return;
}
