/*
Copyright (C) 2012 The NEST Initiative
This file is part of NEST.
*/
#include "config.h"
#ifndef GSL_BINOMIAL_RANDOMDEV_H
#define GSL_BINOMIAL_RANDOMDEV_H
#include "randomgen.h"
#include "randomdev.h"
#include "lockptr.h"
#include "dictdatum.h"
#include "gslrandomgen.h"
#ifdef HAVE_GSL
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
/*BeginDocumentation
Name: rdevdict::gsl_binomial - GSL binomial random deviate generator
Description:
This function returns a random integer from the binomial distribution,
the number of successes in n independent trials with probability
p. The probability distribution for binomial variates is,
p(k) = (n! / k!(n-k)!) p^k (1-p)^(n-k) , 0<=k<=n, n>0
Please note that the RNG used to initialize gsl_binomial has to be
from the GSL (prefixed gsl_ in rngdict)
Parameters:
p - probability of success in a single trial (double)
n - number of trials (positive integer)
SeeAlso: CreateRDV, RandomArray, rdevdict
Author: Jochen Martin Eppler
*/
namespace librandom {
/**
Class GSL_BinomialRandomDev
Generates an RNG which returns Binomial(k;p;n)
distributed random numbers out of an RNG which returns
binomially distributed random numbers:
p(k) = (n! / k!(n-k)!) p^k (1-p)^(n-k) , 0<=k<=n, n<0
Arguments:
- pointer to an RNG
- parameter p (optional, default = 0.5)
- parameter n (optional, default = 1)
@see http://www.gnu.org/software/gsl/manual/html_node/The-Binomial-Distribution.html
@ingroup RandomDeviateGenerators
*/
class GSL_BinomialRandomDev : public RandomDev
{
public:
// accept only lockPTRs for initialization,
// otherwise creation of a lock ptr would
// occur as side effect---might be unhealthy
GSL_BinomialRandomDev(RngPtr, double p_s = 0.5, unsigned int n_s=1);
GSL_BinomialRandomDev(double p_s = 0.5, unsigned int n_s=1);
/**
* set parameters for p and n
* @parameters
* p - success probability for single trial
* n - number of trials
*/
void set_p_n (double, unsigned int);
void set_p (double); //!<set p
void set_n (unsigned int); //!<set n
/**
* Import sets of overloaded virtual functions.
* We need to explicitly include sets of overloaded
* virtual functions into the current scope.
* According to the SUN C++ FAQ, this is the correct
* way of doing things, although all other compilers
* happily live without.
*/
using RandomDev::uldev;
unsigned long uldev(); //!< draw integer
unsigned long uldev(RngPtr) const; //!< draw integer, threaded
bool has_uldev() const { return true; }
double operator()(); //!< return as double
double operator()(RngPtr) const; //!< return as double, threaded
//! set distribution parameters from SLI dict
void set_status(const DictionaryDatum&);
//! get distribution parameters from SLI dict
void get_status(DictionaryDatum&) const;
private:
double p_; //!<probability p of binomial distribution
unsigned int n_; //!<parameter n in binomial distribution
gsl_rng *rng_;
};
inline
double GSL_BinomialRandomDev::operator()()
{
return static_cast<double>(uldev());
}
inline
double GSL_BinomialRandomDev::operator()(RngPtr rthrd) const
{
return static_cast<double>(uldev(rthrd));
}
}
#endif
#endif