double beta_logp(const T& x, const U& alpha, const V& beta) { if(!arma::all(x > 0) || !arma::all(x < 1) || !arma::all(alpha > 0) || !arma::all(beta > 0)) return -std::numeric_limits<double>::infinity(); return arma::accu(lgamma(alpha+beta) - lgamma(alpha) - lgamma(beta) + schur_product(alpha - 1.0f, log_approx(x)) + schur_product(beta - 1.0f, log_approx(1.0f - x))); }
double gamma_logp(const T& x, const U& alpha, const V& beta) { if(!arma::all(x > 0)) return -std::numeric_limits<double>::infinity(); return arma::accu(schur_product((alpha - 1.0f),log_approx(x)) - schur_product(beta,x) - lgamma(alpha) + schur_product(alpha,log_approx(beta))); }
// sigma denotes cov matrix rather than precision matrix double multivariate_normal_sigma_logp(const arma::vec& x, const arma::vec& mu, const arma::mat& sigma) { const double log_2pi = log(2 * arma::math::pi()); arma::mat R(arma::zeros<arma::mat>(sigma.n_cols,sigma.n_cols)); // non-positive definite test via chol if(chol(R,sigma) == false) { return -std::numeric_limits<double>::infinity(); } // otherwise calc logp return -(x.n_elem * log_2pi + log_approx(arma::det(sigma)) + mahalanobis(x,mu,sigma))/2; }
inline double calc() const { return arma::accu(arma::schur(delta_, log_approx(lambda_)) - arma::schur(lambda_, x_)); }
double bernoulli_logp(const T& x, const U& p) { if(!arma::all(x >= 0) || !arma::all(x <= 1)) return -std::numeric_limits<double>::infinity(); return arma::accu(schur_product(x,log_approx(p)) + schur_product((1-x), log_approx(1-p))); }
double binom_logp(const T& x, const U& n, const V& p) { if(!arma::all(x >= 0) || !arma::all(x <= n)) return -std::numeric_limits<double>::infinity(); return arma::accu(schur_product(x,log_approx(p)) + schur_product((n-x),log_approx(1-p)) + arma::factln(n) - arma::factln(x) - arma::factln(n-x)); }
double uniform_logp(const T& x, const U& lower, const V& upper) { if(!arma::all(x > lower) || !arma::all(x < upper)) return -std::numeric_limits<double>::infinity(); return -arma::accu(log_approx(upper - lower)); }
double normal_logp(const T& x, const U& mu, const V& tau) { return arma::accu(0.5f*log_approx(0.5f*tau/arma::math::pi()) - 0.5f * schur_product(tau, square(x - mu))); }