/*
    Theseus - maximum likelihood superpositioning of macromolecular structures

    Copyright (C) 2004-2015 Douglas L. Theobald

    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

    -/_|:|_|_\-
*/

#include <stdio.h>
#include <math.h>
#include <float.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include "statistics.h"
#include "DLTmath.h"
#include "uniform_dist.h"

/* The uniform distribution has the form
   */
double
uniform_dev(const double alpha, const double beta, const gsl_rng *r2)
{
    return ((beta - alpha) * gsl_rng_uniform(r2) + alpha);
}


double
uniform_pdf(const double x, const double alpha, const double beta)
{
   return(1.0 / (beta - alpha));
}


double
uniform_lnpdf(const double x, const double alpha, const double beta)
{
    return(-log(beta - alpha));
}


double
uniform_cdf(const double x, const double alpha, const double beta)
{
    return((x - alpha) / (beta - alpha));
}


double
uniform_sdf(const double x, const double alpha, const double beta)
{
    return((beta - x) / (beta - alpha));
}


double
uniform_int(const double x, const double y, const double alpha, const double beta)
{
    return((y - x) / (beta - alpha));
}


double
uniform_logL(const double alpha, const double beta)
{
    return(-log(beta - alpha));
}


/* maximum likelihood fit of data to a uniform distribution */
double
uniform_fit(const double *x, const int n, double *alpha, double *beta, double *logL)
{
/*     double           nd = (double) n; */
/*     double           ave, rawmom2, var; */
    int              i;
    double           smallest, largest;

    smallest = DBL_MAX;
    largest = -DBL_MAX;
    for (i = 0; i < n; ++i)
    {
        if (x[i] > largest)
            largest = x[i];
        if (x[i] < smallest)
            smallest = x[i];
    }

    *alpha = smallest;
    *beta = largest;

/*     ave = rawmom2 = 0.0; */
/*     for (i = 0; i < n; ++i) */
/*     { */
/*         ave += x[i]; */
/*         rawmom2 += mysquare(x[i]); */
/*     } */
/*     ave /= nd; */
/*     rawmom2 /= nd; */
/*  */
/*     var = rawmom2 - mysquare(ave); */
/*  */
/*     *alpha = ave - sqrt(3.0 * var); */
/*     *beta =  ave + sqrt(3.0 * var); */

    return(chi_sqr_adapt(x, n, 0, logL, *alpha, *beta, uniform_pdf, uniform_lnpdf, uniform_int));
}
