typename boost::math::tools::promote_args<T_prob,T_prior_sample_size>::type dirichlet_log(const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta, const Eigen::Matrix<T_prior_sample_size,Eigen::Dynamic,1>& alpha) { static const char* function = "stan::prob::dirichlet_log(%1%)"; using boost::math::lgamma; using boost::math::tools::promote_args; using stan::math::check_consistent_sizes; using stan::math::check_positive; using stan::math::check_simplex; using stan::math::multiply_log; typename promote_args<T_prob,T_prior_sample_size>::type lp(0.0); check_consistent_sizes(function, theta, alpha, "probabilities", "prior sample sizes", &lp); check_positive(function, alpha, "prior sample sizes", &lp); check_simplex(function, theta, "probabilities", &lp); if (include_summand<propto,T_prior_sample_size>::value) { lp += lgamma(alpha.sum()); for (int k = 0; k < alpha.rows(); ++k) lp -= lgamma(alpha[k]); } if (include_summand<propto,T_prob,T_prior_sample_size>::value) for (int k = 0; k < theta.rows(); ++k) lp += multiply_log(alpha[k]-1, theta[k]); return lp; }
bool check_simplex(const char* function, const char* name, const Eigen::Matrix<T_prob, Eigen::Dynamic, 1>& theta) { using Eigen::Dynamic; using Eigen::Matrix; using stan::math::index_type; typedef typename index_type<Matrix<T_prob, Dynamic, 1> >::type size_t; check_nonzero_size(function, name, theta); if (!(fabs(1.0 - theta.sum()) <= CONSTRAINT_TOLERANCE)) { std::stringstream msg; T_prob sum = theta.sum(); msg << "is not a valid simplex."; msg.precision(10); msg << " sum(" << name << ") = " << sum << ", but should be "; std::string msg_str(msg.str()); domain_error(function, name, 1.0, msg_str.c_str()); return false; } for (size_t n = 0; n < theta.size(); n++) { if (!(theta[n] >= 0)) { std::ostringstream msg; msg << "is not a valid simplex. " << name << "[" << n + stan::error_index::value << "]" << " = "; std::string msg_str(msg.str()); domain_error(function, name, theta[n], msg_str.c_str(), ", but should be greater than or equal to 0"); return false; } } return true; }
inline double sum(const Eigen::Matrix<T,R,C>& v) { return v.sum(); }
int main(int argc, char** argv) { HyperGeometricDistribution<2> dist; std::cout << "Distribution default parameters: " << std::endl << dist << std::endl << std::endl; std::cout << "dist.getNumTrials(): " << dist.getNumTrials() << std::endl << std::endl; std::cout << "dist.getMarbles(): " << std::endl << dist.getMarbles() << std::endl << std::endl; Eigen::Matrix<size_t, 2, 1> marbles; marbles(0) = 5; marbles(1) = 10; const size_t numTrials = 5; std::cout << "dist.setMarbles(5, 10)" << std::endl << std::endl; dist.setMarbles(marbles); std::cout << "dist.setNumTrials(5)" << std::endl << std::endl; dist.setNumTrials(numTrials); std::cout << "Distribution new parameters: " << std::endl << dist << std::endl << std::endl; if (dist.getMarbles() != marbles) return 1; if (dist.getNumTrials() != numTrials) return 1; const int min = -10.0; const int max = 10.0; std::cout << "Evaluating distribution with GNU-R" << std::endl << std::endl; RInside R(argc, argv); R["white"] = marbles(0); R["black"] = marbles(1); R["n"] = numTrials; R["min"] = min; R["max"] = max; std::string expression = "dhyper(min:max, white, black, n)"; SEXP ans = R.parseEval(expression); Rcpp::NumericVector v(ans); int value = min; for (size_t i = 0; i < (size_t)v.size(); ++i) { if (fabs(dist(value) - v[i]) > 1e-12) { std::cout << v[i] << " " << dist(value) << std::endl; return 1; } value++; } const double sum = marbles.sum(); std::cout << "dist.getMean(): " << std::fixed << dist.getMean()(0) << std::endl << std::endl; if (fabs(dist.getMean()(0) - numTrials / sum * marbles(0)) > std::numeric_limits<double>::epsilon()) return 1; std::cout << "dist.getVariance(): " << std::fixed << dist.getCovariance()(0, 0) << std::endl << std::endl; if (fabs(dist.getCovariance()(0, 0) - numTrials * marbles(0) / sum * (sum - marbles(0)) / sum * (sum - numTrials) / (sum - 1)) > std::numeric_limits<double>::epsilon()) return 1; try { std::cout << "dist.setNumTrials(20)" << std::endl; dist.setNumTrials(20); } catch (BadArgumentException<size_t>& e) { std::cout << e.what() << std::endl; } std::cout << std::endl; // std::cout << "dist.getSample(): " << std::endl << dist.getSample() // << std::endl << std::endl; // std::vector<double> samples; // dist.getSamples(samples, 10); // std::cout << "dist.getSamples(samples, 10): " << std::endl; // for (size_t i = 0; i < 10; ++i) // std::cout << std::endl << samples[i] << std::endl; // std::cout << std::endl; HyperGeometricDistribution<2> distCopy(dist); std::cout << "Copy constructor: " << std::endl << distCopy << std::endl << std::endl; if (distCopy.getNumTrials() != dist.getNumTrials()) return 1; if (distCopy.getMarbles() != dist.getMarbles()) return 1; HyperGeometricDistribution<2> distAssign = dist; std::cout << "Assignment operator: " << std::endl << distAssign << std::endl; if (distAssign.getNumTrials() != dist.getNumTrials()) return 1; if (distCopy.getMarbles() != dist.getMarbles()) return 1; return 0; }