def log_add_double(x, y): """ Return log(x + y) given log(x) and log(y); see [1]. [1] Digital Filtering Using Logarithmic Arithmetic. Kingsbury and Rayner, 1970. """ if "log_add_d" in get_qy().module.global_variables: log_add_d = Function.get_named("log_add_d") else: @Function.define(float, [float, float]) def log_add_d(x_in, y_in): s = x_in >= y_in a = qy.select(s, x_in, y_in) @qy.if_else(a == -numpy.inf) def _(then): if then: qy.return_(-numpy.inf) else: qy.return_(a + qy.log1p(qy.exp(qy.select(s, y_in, x_in) - a))) return log_add_d(x, y)
def binomial_log_pdf(k, p, n): """ Compute the binomial PMF. """ name = "binomial_log_pdf_ddd" if name in get_qy().module.global_variables: pdf = Function.get_named(name) else: @Function.define(float, [float, float, float]) def binomial_log_pdf_ddd(k, p, n): from qy.math import ln_choose @qy.if_(k > n) def _(): qy.return_(-numpy.inf) @qy.if_(p == 0.0) def _(): qy.return_(qy.select(k == 0.0, 0.0, -numpy.inf)) @qy.if_(p == 1.0) def _(): qy.return_(qy.select(k == n, 0.0, -numpy.inf)) qy.return_(ln_choose(n, k) + k * qy.log(p) + (n - k) * qy.log1p(-p)) return binomial_log_pdf_ddd(k, p, n)
def binomial_log_pdf(k, p, n): """ Compute the binomial PMF. """ name = "binomial_log_pdf_ddd" if name in get_qy().module.global_variables: pdf = Function.get_named(name) else: @Function.define(float, [float, float, float]) def binomial_log_pdf_ddd(k, p, n): from qy.math import ln_choose @qy.if_(k > n) def _(): qy.return_(-numpy.inf) @qy.if_(p == 0.0) def _(): qy.return_(qy.select(k == 0.0, 0.0, -numpy.inf)) @qy.if_(p == 1.0) def _(): qy.return_(qy.select(k == n, 0.0, -numpy.inf)) qy.return_( ln_choose(n, k) + k * qy.log(p) + (n - k) * qy.log1p(-p)) return binomial_log_pdf_ddd(k, p, n)
def _ll(self, parameter, sample, out): """ Compute log probability under this distribution. """ p = parameter.data.load() k = sample.data.gep(0, 0).load() n = sample.data.gep(0, 1).load() if get_qy().test_for_nan: qy.assert_(p >= 0.0, "invalid p = %s", p) qy.assert_(p <= 1.0, "invalid p = %s", p) qy.assert_(k >= 0, "invalid k = %s", k) qy.assert_(n >= 0, "invalid n = %s", n) qy.assert_(k <= n, "invalid k = %s (> n = %s)", k, n) binomial_log_pdf(k, p, n).store(out)
def _ll(self, parameter, sample, out): """ Compute log probability under this distribution. """ p = parameter.data.load() k = sample.data.gep(0, 0).load() n = sample.data.gep(0, 1).load() if get_qy().test_for_nan: qy.assert_(p >= 0.0, "invalid p = %s" , p ) qy.assert_(p <= 1.0, "invalid p = %s" , p ) qy.assert_(k >= 0 , "invalid k = %s" , k ) qy.assert_(n >= 0 , "invalid n = %s" , n ) qy.assert_(k <= n , "invalid k = %s (> n = %s)", k, n) binomial_log_pdf(k, p, n).store(out)
def binomial_pdf(k, p, n): """ Compute the binomial PDF function. """ name = "gsl_ran_binomial_pdf" if name in get_qy().module.global_variables: pdf = Function.get_named(name) else: import llvm.core from ctypes import c_uint pdf = Function.named(name, float, [c_uint, float, c_uint]) pdf._value.add_attribute(llvm.core.ATTR_READONLY) pdf._value.add_attribute(llvm.core.ATTR_NO_UNWIND) return pdf(k, p, n)