#include <config.h>
#include <distributions/DBin.h>
#include <sarray/SArray.h>

#include <algorithm>

#include <Rmath.h>

using std::vector;
using std::max;
using std::min;

/* BUGS parameterization is in opposite order to R parameterization */

static inline double SIZE(vector<SArray const *> const &par)
{
    return *par[1]->value();
}

static inline double PROB(vector<SArray const *> const &par)
{
    return *par[0]->value();
}

DBin::DBin()
  : DistDiscrete("dbin", 2, DIST_SPECIAL, false)
{}

DBin::~DBin()
{}

bool 
DBin::checkParameterDim (vector<SArray const *> const &par) const
{
    return (par[0]->length() == 1) && (par[1]->length() == 1) 
	&& par[1]->isDiscreteValued();
}

bool DBin::checkParameterValue(vector<SArray const *> const &par) const
{
    return (SIZE(par) >= 1 && PROB(par) >= 0.0 && PROB(par) <= 1.0);
}

double DBin::d(double x, std::vector<SArray const *> const &par, 
	       bool give_log) const
{
    return dbinom(x, SIZE(par), PROB(par), give_log);
}

double DBin::p(double x, std::vector<SArray const *> const &par, 
	       bool lower, bool give_log) const
{
    return pbinom(x, SIZE(par), PROB(par), lower, give_log);
}

double DBin::q(double p, std::vector<SArray const *> const &par, 
	       bool lower, bool log_p) const
{
    return pbinom(p, SIZE(par), PROB(par), lower, log_p);
}

double DBin::r(std::vector<SArray const *> const &par) const
{
    return rbinom(SIZE(par), PROB(par));
}

double 
DBin::l(vector<SArray const *> const &par) const
{
    return 0;
}
	

double 
DBin::u(vector<SArray const *> const &par) const
{
    return SIZE(par);
}

double 
DBin::mean(std::vector<SArray const *> const &par) const
{
    return SIZE(par) * PROB(par);
}

double 
DBin::var(std::vector<SArray const *> const &par) const
{
    return SIZE(par) * PROB(par) * (1 - PROB(par));
}


syntax highlighted by Code2HTML, v. 0.9.1