def _get_value_log(self, x, mu, v): """log basic 2""" try: return loggamma(x+v) - loggamma(x+1) - loggamma(v) + v*log(v) - v*log(v+mu) + x*log(mu) - x*log(v+mu) except ValueError: #print('_get_value_log ValueError', x, mu, v, file=sys.stderr) return 1
def logbinomial(n, k): """ Natural logarithm of binomial(n, k). Examples -------- >>> import mpmath >>> mpmath.mp.dps = 25 >>> from mpsci.fun import logbinomial Compute the log of C(1500, 450). >>> logbinomial(1500, 450) mpf('912.5010192350457701746286796') Verify that it is the expected value. >>> mpmath.log(mpmath.binomial(1500, 450)) mpf('912.5010192350457701746286773') """ if n < 0: raise ValueError('n must be nonnegative') if k < 0: raise ValueError('k must be nonnegative') if k > n: raise ValueError('k must not exceed n') with mpmath.extradps(5): return (mpmath.loggamma(n + 1) - mpmath.loggamma(k + 1) - mpmath.loggamma(mpmath.fsum([n + 1, -k])))
def log_hyper_2F1(a, b, c, w): log_results_even = [] log_results_odd = [] for n in range(int(1 - b)): log_resu = logbinomial( -b, n) + mpmath.loggamma(a + n) + mpmath.loggamma(c) - mpmath.loggamma( c + n) - mpmath.loggamma(a) + n * mpmath.log(w) if is_even(n): log_results_even.append(log_resu) else: log_results_odd.append(log_resu) if len(log_results_even) == 0: return -np.inf else: log_results_even_partsum = custom_logsumexp_mpmath( log_results_even, np.ones(len(log_results_even))) if len(log_results_odd) == 0: return log_results_even_partsum[0] else: log_results_odd_partsum = custom_logsumexp_mpmath( log_results_odd, np.ones(len(log_results_odd))) if log_results_odd_partsum[0] > log_results_even_partsum[0]: print('Dang!') log_result = custom_logsumexp_mpmath( [log_results_even_partsum[0], log_results_odd_partsum[0]], np.array([1, -1])) return log_result[0]
def pdf(x, df, nc): """ Probability density function of the noncentral t distribution. The infinite series is estimated with `mpmath.nsum`. """ with mpmath.extradps(5): x = mpmath.mpf(x) df = mpmath.mpf(df) nc = mpmath.mpf(nc) if x == 0: logp = (-nc**2 / 2 - mpmath.log(mpmath.pi) / 2 - mpmath.log(df) / 2 + mpmath.loggamma( (df + 1) / 2) - mpmath.loggamma(df / 2)) p = mpmath.exp(logp) else: logc = (df * mpmath.log(df) / 2 - nc**2 / 2 - mpmath.loggamma(df / 2) - mpmath.log(mpmath.pi) / 2 - (df + 1) / 2 * mpmath.log(df + x**2)) c = mpmath.exp(logc) def _pdf_term(i): logterm = (mpmath.loggamma( (df + i + 1) / 2) + i * mpmath.log(x * nc) + i * mpmath.log(2 / (df + x**2)) / 2 - mpmath.loggamma(i + 1)) return mpmath.exp(logterm).real s = mpmath.nsum(_pdf_term, [0, mpmath.inf]) p = c * s return p
def test_special_printers(): from sympy.printing.lambdarepr import IntervalPrinter def intervalrepr(expr): return IntervalPrinter().doprint(expr) expr = sqrt(sqrt(2) + sqrt(3)) + S.Half func0 = lambdify((), expr, modules="mpmath", printer=intervalrepr) func1 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter) func2 = lambdify((), expr, modules="mpmath", printer=IntervalPrinter()) mpi = type(mpmath.mpi(1, 2)) assert isinstance(func0(), mpi) assert isinstance(func1(), mpi) assert isinstance(func2(), mpi) # To check Is lambdify loggamma works for mpmath or not exp1 = lambdify(x, loggamma(x), 'mpmath')(5) exp2 = lambdify(x, loggamma(x), 'mpmath')(1.8) exp3 = lambdify(x, loggamma(x), 'mpmath')(15) exp_ls = [exp1, exp2, exp3] sol1 = mpmath.loggamma(5) sol2 = mpmath.loggamma(1.8) sol3 = mpmath.loggamma(15) sol_ls = [sol1, sol2, sol3] assert exp_ls == sol_ls
def calc_model_evidence(self): vval = 0 mp.mp.dps = 50 for action in range(self.hparams.num_actions): # val=1 # aa = self.a[action] # for i in xrange(int(self.a[action]-self.a0)): # aa-=1 # val*=aa # val/=(2.0*math.pi) # val/=self.b[action] # val*=gamma(aa) # val/=(self.b[action]**aa) # val *= np.sqrt(np.linalg.det(self.lambda_prior * np.eye(self.hparams.context_dim + 1)) / np.linalg.det(self.precision[action])) # val *= (self.b0 ** self.a0) # val/= gamma(self.a0) # vval += val #val= 1/float((2.0 * math.pi) ** (self.a[action]-self.a0)) #val*= (float(gamma(self.a[action]))/float(gamma(self.a0))) #val*= np.sqrt(float(np.linalg.det(self.lambda_prior * np.eye(self.hparams.context_dim + 1)))/float(np.linalg.det(self.precision[action]))) #val*= (float(self.b0**self.a0)/float(self.b[action]**self.a[action])) val= mp.mpf(mp.fmul(mp.fneg(mp.log(mp.fmul(2.0 , mp.pi))) , mp.fsub(self.a[action],self.a0))) val+= mp.loggamma(self.a[action]) val-= mp.loggamma(self.a0) val+= 0.5*mp.log(np.linalg.det(self.lambda_prior * np.eye(self.hparams.context_dim + 1))) val -= 0.5*mp.log(np.linalg.det(self.precision[action])) val+= mp.fmul(self.a0,mp.log(self.b0)) val-= mp.fmul(self.a[action],mp.log(self.b[action])) vval+=mp.exp(val) vval/=float(self.hparams.num_actions) return vval
def logchoose(ni, ki): try: lgn1 = loggamma(ni + 1) lgk1 = loggamma(ki + 1) lgnk1 = loggamma(ni - ki + 1) except ValueError: raise ValueError return lgn1 - (lgnk1 + lgk1)
def logchoose(ni, ki): try: lgn1 = mpmath.loggamma(ni + 1) lgk1 = mpmath.loggamma(ki + 1) lgnk1 = mpmath.loggamma(ni - ki + 1) except ValueError: #print ni,ki raise ValueError return lgn1 - (lgnk1 + lgk1)
def var(df, nc): """ Variance of the noncentral t distribution. """ # XXX Require df > 2. with mpmath.extradps(5): df = mpmath.mpf(df) nc = mpmath.mpf(nc) c = mpmath.exp(mpmath.loggamma((df - 1) / 2) - mpmath.loggamma(df / 2)) return df / (df - 2) * (1 + nc**2) - df / 2 * nc**2 * c**2
def beta(self, a, b): """ Uses either mpmath's gamma or log-gamma function to compute values of the beta function. """ a, b = mpmath.mpf(a), mpmath.mpf(b) if self.use_log: beta = mpmath.exp(mpmath.loggamma(a) + mpmath.loggamma(b) - mpmath.loggamma(a + b)) else: beta = mpmath.gamma(a) * mpmath.gamma(b) / mpmath.gamma(a + b) return beta
def mean(df, nc): """ Mean of the noncentral t distribution. """ # XXX Require df > 1. with mpmath.extradps(5): df = mpmath.mpf(df) nc = mpmath.mpf(nc) logm = (mpmath.log(nc) + mpmath.log(df / 2) / 2 + mpmath.loggamma( (df - 1) / 2) - mpmath.loggamma(df / 2)) return mpmath.exp(logm)
def betaincreg(self, a, b, x): """ betaincreg(a,b,x) evaluates the incomplete beta function (regularized). It requires a, b > 0 and 0 <= x <= 1. Code translated from: GNU Scientific Library """ # In terms of methods, this function requires contfractbeta(), defined above. # HOTFIX prevent the original a, b or x from being numpy elements a = float(a) b = float(b) x = float(x) # Transpose a, x, x into mpmath objects. a, b, x = mpmath.mpf(a), mpmath.mpf(b), mpmath.mpf(x) def isnegint(X): return (X < 0) & (X == mpmath.floor(X)) # Trivial cases if (x < 0) | (x > 1): raise ValueError( "Bad x in betainc(a,b,x) - x must be between 0 and 1") elif isnegint(a) | isnegint(b) | isnegint(a + b): raise ValueError( "Bad a or b in betainc(a,b,x) -- neither a, b nor a+b can be negative integers" ) elif x == 0: return 0 elif x == 1: return 1 else: # Factors in front of the continued fraction lnbeta = mpmath.loggamma(a) + mpmath.loggamma(b) - mpmath.loggamma( a + b) prefactor = -lnbeta + a * mpmath.log(x) + b * mpmath.log(1 - x) # Use continued fraction directly ... if x < (a + 1) / (a + b + 2): fraction = self.contfractbeta(a, b, x) result = mpmath.exp(prefactor) * fraction / a # ... or make a symmetry transformation first else: fraction = self.contfractbeta(b, a, 1 - x) term = mpmath.exp(prefactor) * fraction / b result = 1 - term return result
def logchoose(ni, ki): #n = max(ni, ki) #k = min(ni, ki) try: lgn1 = loggamma(ni+1) lgk1 = loggamma(ki+1) lgnk1 = loggamma(ni-ki+1) except ValueError: #print ni,ki raise ValueError return lgn1 - (lgnk1 + lgk1)
def pofk_paramagnet(N, k): preterm = sqrt(2. / (pi * N)) if k == 0: exp_term = loggamma(N + 1) - loggamma(k + 1) - loggamma(N - k + 1) elif k == N: exp_term = loggamma(N + 1) - loggamma(k + 1) - loggamma(N - k + 1) else: exp_term = loggamma(N + 1) - loggamma(k + 1) - loggamma( N - k + 1) + k * log(k / N) + (N - k) * log(1. - (k / N)) return preterm * exp(exp_term)
def logbeta(x, y): """ Natural logarithm of beta(x, y). The beta function is Gamma(x) Gamma(y) beta(x, y) = ----------------- Gamma(x + y) where Gamma(z) is the Gamma function. """ with mpmath.extradps(5): return (mpmath.loggamma(x) + mpmath.loggamma(y) - mpmath.loggamma(mpmath.fsum([x, y])))
def make_lgamma_vals(): from mpmath import loggamma x = [mpf('0.01')] + linspace(mpf('0.1'), 10, 100) + [mpf(20), mpf(30)] lga = [loggamma(val) for val in x] return make_special_vals('lgamma_vals', ('x', x), ('lga', lga))
def logpdf(x, df): """ Logarithm of the PDF of Student's t distribution. """ if df <= 0: raise ValueError('df must be greater than 0') with mpmath.extradps(5): x = mpmath.mpf(x) df = mpmath.mpf(df) h = (df + 1) / 2 logp = (mpmath.loggamma(h) - mpmath.log(df * mpmath.pi)/2 - mpmath.loggamma(df/2) - h * mpmath.log1p(x**2/df)) return logp
def logpmf(k, lam): """ Natural log of the probability mass function of the binomial distribution. """ if k < 0: return -mpmath.mp.inf with mpmath.extradps(5): lam = mpmath.mpf(lam) return k * mpmath.log(lam) - lam - mpmath.loggamma(k + 1)
def logpdf(x, k, theta): """ Log of the PDF of the gamma distribution. """ _validate_k_theta(k, theta) x = mpmath.mpf(x) k = mpmath.mpf(k) theta = mpmath.mpf(theta) return (-mpmath.loggamma(k) - k*mpmath.log(theta) + (k - 1)*mpmath.log(x) - x/theta)
def beta(self, a, b): """ Uses either mpmath's gamma or log-gamma function to compute values of the beta function. """ # HOTFIX prevent the original a, b from being numpy elements a = float(a) b = float(b) a, b = mpmath.mpf(a), mpmath.mpf(b) if self.use_log: beta = mpmath.exp( mpmath.loggamma(a) + mpmath.loggamma(b) - mpmath.loggamma(a + b)) else: beta = mpmath.gamma(a) * mpmath.gamma(b) / mpmath.gamma(a + b) return beta
def _pdf_term(k, x, dfn, dfd, nc): halfnc = nc / 2 halfdfn = dfn / 2 halfdfd = dfd / 2 logr = (-halfnc + k * _mp.log(halfnc) - _logbeta(halfdfd, halfdfn + k) - _mp.loggamma(k + 1) + (halfdfn + k) * (_mp.log(dfn) - _mp.log(dfd)) + (halfdfn + halfdfd + k) * (_mp.log(dfd) - _mp.log(dfd + dfn * x)) + (halfdfn - 1 + k) * _mp.log(x)) return _mp.exp(logr)
def _cdf_term(k, x, dfn, dfd, nc): halfnc = nc / 2 halfdfn = dfn / 2 halfdfd = dfd / 2 log_coeff = _mp.fsum([k * _mp.log(halfnc), -halfnc, -_mp.loggamma(k + 1)]) coeff = _mp.exp(log_coeff) r = coeff * _mp.betainc(a=halfdfn + k, b=halfdfd, x1=0, x2=dfn * x / (dfd + dfn * x), regularized=True) return r
def logpdf(x, k, theta): """ Log of the PDF of the log-gamma distribution. k is the shape parameter of the gamma distribution. theta is the scale parameter of the log-gamma distribution. """ with mpmath.extradps(5): x = mpmath.mpf(x) k = mpmath.mpf(k) theta = mpmath.mpf(theta) z = x / theta return (k * z - mpmath.exp(z)) - mpmath.loggamma(k) - mpmath.log(theta)
def logpdf(x, k): """ Logarithm of the PDF for the chi distribution. """ _validate_k(k) if x < 0: return mpmath.mp.ninf with mpmath.extradps(5): x = mpmath.mpf(x) k = mpmath.mpf(k) p = ((k - 1)*mpmath.log(x) - x**2/2 - ((k/2) - 1)*mpmath.log(2) - mpmath.loggamma(k/2)) return p
def likelihood(Kq1, Kq2, mq1, mq2, Nq, M, a): Kq1 = float(Kq1) Kq2 = float(Kq2) mq1 = float(mq1) mq2 = float(mq2) Nq = float(Nq) M = float(M) a = float(a) term1 = loggamma(Kq1 + Kq2 + a) + loggamma(a) - loggamma(Kq1 + a) - loggamma(Kq2 + a) term2 = float(Kq1) * log(float(mq1) / float(mq1 + mq2)) + float(Kq2) * log( float(mq2) / float(mq1 + mq2)) term3 = loggamma(M + (a * Nq)) + loggamma( a * (Nq - 1)) - loggamma(M + (a * (Nq - 1))) - loggamma(a * Nq) return term1 + term2 + term3
def logpdf(x, nu): """ Logarithm of the PDF for the inverse chi-square distribution. """ _validate_nu(nu) if x <= 0: return mpmath.ninf with mpmath.extradps(5): x = mpmath.mpf(x) nu = mpmath.mpf(nu) hnu = nu/2 logp = (-hnu*mpmath.log(2) + (-hnu - 1)*mpmath.log(x) - 1/(2*x) - mpmath.loggamma(hnu)) return logp
def nll(x, k, theta): """ Gamma distribution negative log-likelihood. """ _validate_k_theta(k, theta) k = mpmath.mpf(k) theta = mpmath.mpf(theta) N = len(x) sumx = mpmath.fsum(x) sumlnx = mpmath.fsum(mpmath.log(t) for t in x) ll = ((k - 1)*sumlnx - sumx/theta - N*k*mpmath.log(theta) - N*mpmath.loggamma(k)) return -ll
def logpdf(x, nu, loc, scale, scale_inv=None): """ Natural logarithm of the PDF for the multivariate t distribution. `loc` must be a sequence. `scale` is the scale matrix; it must be an instance of `mpmath.matrix`. `scale` must be positive definite. If given, `scale_inv` must be the inverse of `scale`. """ p = mpmath.mpf(len(loc)) with mpmath.extradps(5): nu = mpmath.mpf(nu) if scale_inv is None: with mpmath.extradps(5): scale_inv = mpmath.inverse(scale) tmp = mpmath.matrix(scale.cols, 1) for k, v in enumerate(loc): tmp[k] = mpmath.mpf(v) loc = tmp tmp = mpmath.matrix(scale.cols, 1) for k, v in enumerate(x): tmp[k] = mpmath.mpf(v) x = tmp delta = x - loc c = (nu + p) / 2 t1 = -c * mpmath.log1p((delta.T * scale_inv * delta)[0, 0] / nu) t2 = mpmath.loggamma(c) t3 = mpmath.loggamma(nu / 2) t4 = (p / 2) * mpmath.log(nu) t5 = (p / 2) * mpmath.log(mpmath.pi) with mpmath.extradps(5): det = mpmath.det(scale) t6 = mpmath.log(det) / 2 return t2 - t3 - t4 - t5 - t6 + t1
def logpdf(x, nu, loc=0, scale=1): """ Natural logarithm of the PDF of the Nakagami distribution. """ _validate_params(nu, loc, scale) if x <= 0: return -mpmath.inf with mpmath.extradps(5): if x <= loc: return mpmath.mp.zero x = mpmath.mpf(x) nu = mpmath.mpf(nu) loc = mpmath.mpf(loc) scale = mpmath.mpf(scale) z = (x - loc)/scale return (mpmath.log(2) + nu*mpmath.log(nu) - mpmath.loggamma(nu) + (2*nu-1)*mpmath.log(z) - nu*z**2 - mpmath.log(scale))
def nll(x, nu, loc, scale): """ Negative log-likelihood function for the Nakagami distribution. """ _validate_params(nu, loc, scale) _validate_x(x, loc=loc) n = len(x) with mpmath.extradps(5): nu = mpmath.mpf(nu) loc = mpmath.mpf(loc) scale = mpmath.mpf(scale) z = [(t - loc)/scale for t in x] logsum = mpmath.fsum([mpmath.log(t) for t in z]) sqsum = mpmath.fsum([t**2 for t in z]) ll = n*(mpmath.log(2) + nu*mpmath.log(nu) - mpmath.loggamma(nu) - mpmath.log(scale)) + (2*nu - 1)*logsum - nu*sqsum return -ll
#!/usr/bin/python """ """ import sys import mpmath as mp import numpy as np mp.mp.dps = 60 a_lo = float(sys.argv[1]) a_hi = float(sys.argv[2]) n = int(sys.argv[3]) for x in np.logspace(a_lo, a_hi, 1000) : x = mp.mpf(x) print x, mp.loggamma(x)
def f73(x): # lngamma try: return mpmath.loggamma(x) except: return None
def dk_term(k): k = float(k) if k != 0: return k * log(k) - loggamma(k + 1) else: return -loggamma(k + 1)