/*******************************************************************************
*
*       This file is part of the General Hidden Markov Model Library,
*       GHMM version __VERSION__, see http://ghmm.org
*
*       Filename: ghmm/ghmm/randvar.h
*       Authors:  Bernhard Knab, Alexander Schliep, Ben Rich, Janne Grunau
*
*       Copyright (C) 1998-2004 Alexander Schliep 
*       Copyright (C) 1998-2001 ZAIK/ZPR, Universitaet zu Koeln
*	Copyright (C) 2002-2004 Max-Planck-Institut fuer Molekulare Genetik, 
*                               Berlin
*                                   
*       Contact: schliep@ghmm.org             
*
*       This library is free software; you can redistribute it and/or
*       modify it under the terms of the GNU Library General Public
*       License as published by the Free Software Foundation; either
*       version 2 of the License, or (at your option) any later version.
*
*       This library 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
*       Library General Public License for more details.
*
*       You should have received a copy of the GNU Library General Public
*       License along with this library; if not, write to the Free
*       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*       This file is version $Revision: 2310 $ 
*                       from $Date: 2013-06-14 10:36:57 -0400 (Fri, 14 Jun 2013) $
*             last change by $Author: ejb177 $.
*
*******************************************************************************/
#ifndef GHMM_RANDVAR_H
#define GHMM_RANDVAR_H

/**@name Help functions for random values */
/*@{ (Doc++-Group: randvar) */


#define PI 3.141592653589793116

#ifdef __cplusplus
extern "C" {
#endif

/**
   Calculates the one dimensional density function phi( mean, u ) for the
   normal distribution at point x.
   @return       function value
   @param x:      point value
   @param mean:   mean value for the normal distribution
   @param u:      variance for the normal distribution (\f$\sigma^2\f$)
   */
  double ighmm_rand_normal_density (double x, double mean, double u);

/**
   Calculates the two dimensional density function phi( mean vector, covariance
   matrix ) for the bivariate normal distribution at point x.
   @return          function value
   @param x:        point value (vector of x1 and x2)
   @param mean:     mean values for the bivariate
   @param cov:      linearized covariance matrix
   */
  double ighmm_rand_binormal_density (const double *x, double *mean, double *cov);

/**
   Calculates the multidimensional density function of a multivariate normal
   distribution at point x.
   @return          0 on success
   @param length    dimension of the multivariate normal
   @param x         vector of point values
   @param mean      vector of means
   @param sigmainv  linearized inverse of covariance matrix
   @param det       determinant of covariance matrix
   */
  double ighmm_rand_multivariate_normal_density(int length, const double *x, double *mean,
                                                double *sigmainv, double det);

  /** density function of a uniform distribution in the range [min,max]
   @return          F(x)
   @param x:        point value
   @param max:      right limit 
   @param min:      left limit
 */
  double ighmm_rand_uniform_density (double x, double max, double min);

/**
   Determinates the value of the one dimensional density function 
   phi( mean, u ) for the normal distribution at point x. The value is
   got from a previoously calculated list, which is made in first call
   to this function.
   @return       function value
   @param x:      point value
   @param mean:   mean value for the normal distribution
   @param u:      variance for the normal distribution (\f$\sigma^2\f$)
   */
  double ighmm_rand_normal_density_approx (double x, double mean, double u);

/**
   Calculates the one dimensional Gauss density function phi( mean, u ) 
   at point x. In this case: phi = 0 for x < 0. 
   @return       function value
   @param x:      point value
   @param mean:   mean value for the normal distribution
   @param u:      variance for the normal distribution (\f$\sigma^2\f$)
   */
  double ighmm_rand_normal_density_pos (double x, double mean, double u);

/**
   Calculates the one dimensional Gauss density function phi( mean, u ) 
   at point x. In this case: phi = 0 for x on the interval (\f$-\infty\f$, a).
   @return       function value
   @param x:      point value
   @param mean:   mean value for the normal distribution
   @param u:      variance for the normal distribution (\f$sigma^2\f$)
   @param a:      left limit for the density function
   */
  double ighmm_rand_normal_density_trunc (double x, double mean, double u,
                                       double a);

/** 
   Generates a Uniform( 0, K-1 ) distributed random integer. 
   @return          random integer
   @param seed:      1: initialize only the Uniform( 0, 1 ) generator, 
                     0: return a uniform distributed integer 
   @param K:         right limit for uniform distribution
  */
  double ighmm_rand_uniform_int (int seed, int K);
  
/**
  Generates a dirichlet distributed random number
  @return random number
  @param seed:
  @param len: length of alpha, theta
  @param alpha: parameter for dirichlet distrubution
  @param theta: probability density
*/
  double ighmm_rand_dirichlet(int seed, int len, double *alpha, double *theta);

/** 
   Generates a N( 0, 1 ) distributed random number.
   @return          random value
   @param seed:      1: only initialize the U(0,1) generator,
                    0: returns a standard normal distributed random number 
  */
  double ighmm_rand_std_normal (int seed);

/**
   Generates a N( mue, u ) distributed random number.
   @return           random number
   @param mue:       mean value for the normal distribution 
   @param u:         variance for the random distribution
   @param seed:      1: only initialization
                     0: returns a standard normal distributed random number 
  */
  double ighmm_rand_normal (double mue, double u, int seed);

/**
 Generates a N(mue,cov) distributed random vector of a multivariate normal
        @return        0: success, !0: an error occured
        @param dim     dimension of multivariate
        @param x       vector that stores the result
        @param mue     mean vector of the multivariate normal
        @param sigmacd linearized cholesky decomposition of variance covariance
                        matrix
        @param seed    1: only initialization, 0: rng state is unmodified
  */
  int ighmm_rand_multivariate_normal (int dim, double *x, double *mue, double *sigmacd, int seed);

  /** Genrates a uniformly distributed random number from the range [min,max]
   @return          random number
   @param seed    1: only initialization, 0: rng state is unmodified
   @param max:      right limit 
   @param min:      left limit
 */

  double ighmm_rand_uniform_cont (int seed, double max, double min);

/** 
   Generates a ,N( mue, u ) truncated at the right limit a distributed random number.
   @return          random number
   @param a:         right limit
   @param mue:       mean value for the normal distribution 
   @param u:         variance for the random distribution
   @param seed:      1: only initialize the N( 0, 1 ) generator
                     0: returns a standard normal distributed random number 
  */
  double ighmm_rand_normal_right (double a, double mue, double u, int seed);

/**
   Determinates the N( 0, 1 ) distribution function at point x.
   The distribution is read in as a table and points between the
   sampling points are generated with interpolation.
   @return           function value
   @param x:         point value
   */
  double ighmm_rand_get_PHI (double x);

/**
   Calculates scaling factor 1/a for the truncated normal distribution.
   a corresponds to the value of the integral from x to infinity over
   the normal density function.
   @return           1/a
   @param x:         left limit for integral
   @param mean:      mean value for the normal distribution
   @param u:         variance for the normal distribution
   */
  double ighmm_rand_get_1overa (double x, double mean, double u);

/**
   Determinates the first sampling point x, for which PHI(x) = 1 for the first
   time.
   @return          x with PHI(x)==1, PHI(y) < 1 for all y < x
   */
  double ighmm_rand_get_xPHIless1();

/**                                 
   Cumalative distribution function F(x;mean,u) for the N(mean, u).
   @return           F(x)
   @param x:         point value
   @param mean:      mean value for the normal distribution
   @param u:         variance for the normal distribution
*/
  double ighmm_rand_normal_cdf (double x, double mean, double u);

/**                                 _
   Cumalative distribution function F(x;mean,u) for the truncated N(mean, u).
   @return          F(x)
   @param x:         point value
   @param mean:      mean value for the normal distribution
   @param u:         variance for the normal distribution
   @param a          cutoff value
*/
  double ighmm_rand_normal_right_cdf (double x, double mean, double u, double a);


  /** cumalative distribution function of a uniform distribution in the range [min,max]
   @return          F(x)
   @param x:        point value
   @param max:      right limit 
   @param min:      left limit */
  double ighmm_rand_uniform_cdf (double x, double max, double min);

  /**
   Small help function for interpolation, returns a constant.
  */
  double ighmm_rand_get_xfaktphi();

/**
   Small help function for interpolation, returns a constant.
  */
  double ighmm_rand_get_xstepphi();

  /** 
   Small help function for interpolation, returns a constant.
  */
  double ighmm_rand_get_philen();


#ifdef __cplusplus
}
#endif
#endif                          /* RGHMM_ANDVAR_H */
/*@} (Doc++-Group: randvar) */
