#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "cdflib.h"

/* cdf.c: compute the cumulative distribution function of a
          set of values.

   Input format: list of numerical values separated by newlines

   Output format: x-y pairs separated by newlines, where the xs
   are values from the input list and the ys are probabilities

   Flags:

   -t <transform>

   Applies a transformation to the distribution, where the values
   of <transform> are logx, logy, loglog and norm.

   logx and logy perform a logarithmic transform of the x and y
   axes, respectively; loglog transforms both axes.

   If the y axis is log-transformed, it is also complemented.
   That is, the y values are log(1- cdf(x))

   norm transforms the y axis using the inverse normal cdf.  Under
   this transform, a normal distribution appears as a straight line.

   norm can be combined with logx, in which case a lognormal distribution
   appears as a straight line.

   -b <number>

   Specifies the base used for the log transformation.  Default is 2.

   -u <number>

   Specifies the upper bound after which the x values are truncated.
   Default is DBL_MAX = 1e300

   -n <number>

   Specifies the maximum number of unique x values that can appear
   in the output, which is useful for reducing the size of the output
   without changing its visual appearance when plotted.  This option
   tries to be smart about rounding off only when the approximation
   is visually minimal.  A value of 1000 should be pretty safe.

   This program requires functions from cdflib.c and the header
   file cdflib.h

   See the end of the file for licensing information.
*/


// flags
int logx = 0;
int logy = 0;
int norm = 0;
int res = 0;                 // number of distinguishable values
double base = 2.0;
double upper = 1e300;

void transform_cdf (Cdf *cdf)
{
  if (logx) {
    transform_cdf_logx (cdf);
    if (base != 2.0) {
      multiply_cdf (cdf, log(2.0)/log(base), 1.0);
    }
  }
  if (logy) {
    transform_cdf_logy (cdf);
    if (base != 2.0) {
      multiply_cdf (cdf, 1.0, log(2.0)/log(base));
    }
  }
  if (norm) {
    transform_cdf_norm (cdf);
  }
}

void set_flags (char *transform)
{
  if (strcmp (transform, "logx") == 0) {
    logx = 1;
  } else if (strcmp (transform, "logy") == 0) {
    logy = 1;
  } else if (strcmp (transform, "loglog") == 0) {
    logx = 1;
    logy = 1;
  } else if (strcmp (transform, "norm") == 0) {
    norm = 1;
  } else if (strcmp (transform, "lognorm") == 0) {
    norm = 1;
    logx = 1;
  } else {
    fprintf (stderr, "Unrecognized transform argument %s.\n", transform);
    fprintf (stderr, "Choices: logx, logy, loglog, norm, lognorm.\n");
    exit (1);
  }
}

int main (int argc, char *argv[])
{
  Vector *vector;
  Cdf *cdf;
  char *file_name = NULL;
  int i, c;

  opterr = 0;
  while ( (c = getopt (argc, argv, "t:n:b:u:")) != -1) {
    switch (c) {
    case 't':
      set_flags (optarg);
      break;
    case 'n':
      res = atoi (optarg);
      break;
    case 'b':
      base = atof (optarg);
      break;
    case 'u':
      upper = atof (optarg);
      break;
    case '?':
      if (isprint (optopt)) {
	fprintf (stderr, "Unknown option `-%c'.\n", optopt);
      } else {
	fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
	exit (1);
      }
    default:
      exit (1);
    }
  }

  file_name = argv[optind];

  vector = read_file (file_name);
  cdf = calc_cdf (vector);

  transform_cdf (cdf);

  if (res != 0) {
    round_cdf (cdf, res);
  }
  uniq_cdf (cdf);

  if (!logy && !norm) {
    printf ("%f\t%f\n", cdf->x[0], 0.0);
    printf ("%f\t%f\n", cdf->x[0], cdf->y[0]);
  }

  for (i=1; i<cdf->n; i++) {
    if (cdf->x[i] > upper) break;
    printf ("%f\t%f\n", cdf->x[i], cdf->y[i-1]);
    printf ("%f\t%f\n", cdf->x[i], cdf->y[i]);
  }

  return 0;
}


/* cdf.c: compute the cumulative distribution function of a
          set of values.

Copyright (C) 2003 Allen B. Downey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
