def a_lm(self, l, m): ll_m = mp.mpf(l) if l == 0 and m == 0: return np.sqrt(np.pi) elif m == 0 and np.mod(l, 2) == 1: return float(self.sign * mp.sqrt(1 + 2 * ll_m) * mp.pi / (ll_m * mp.gamma(-ll_m / 2) * mp.gamma( (3 + ll_m) / 2.))) else: return 0.
def Ht_AFE_A(z, t): """ This is the much more accurate approx functional eqn posted by Terry at https://terrytao.wordpress.com/2018/02/02/polymath15-second-thread-generalising-the-riemann-siegel-approximate-functional-equation/#comment-492182 :param z: point at which H_t is computed :param t: the "time" parameter :return: the A part in Ht """ z, t = mp.mpc(z), mp.mpc(t) s = (1 + 1j * z.real - z.imag) / 2 tau = mp.sqrt(s.imag / (2 * mp.pi())) N = int(tau) A_pre = (1/16) * s * (s-1) \ * mp.power(mp.pi(), -1*s/2) * mp.gamma(s/2) A_sum = 0.0 for n in range(1, N + 1): if t.real > 0: A_sum += mp.exp( (t / 16) * mp.power(mp.log( (s + 4) / (2 * mp.pi() * n * n)), 2)) / mp.power(n, s) else: A_sum += 1 / mp.power(n, s) return A_pre * A_sum
def lourenco_dist_mp( mgamma, z, n, m, sigma, Ne, Ne_scal, scal_fac=1): # not sure if I do it right with the scale factor... s = mgamma / 2. / Ne_scal * scal_fac if s == 0: return numpy.nan #s = mgamma # prob = mp.power(2, (1-m)/2.)*mp.power(Ne, 0.5)*mp.power(mp.fabs(s), (m-1)/2.)*(1+1/(Ne*mp.power(sigma, 2.)))*mp.exp(-Ne*s) / (mp.power(mp.pi,0.5)*mp.power(sigma, m)*mp.gamma(m/2.)) * mp.besselk((m-1)/2., Ne*mp.fabs(s)*mp.power(1+1/(Ne*mp.power(sigma, 2.)),0.5)) prob = mp.power(2, -(m + 1) / 2) * mp.exp( -n * s / 4 / mp.power(z, 2.)) * mp.sqrt(n) * mp.power( (1 + 4. * mp.power(z, 2.) / n / mp.power(sigma, 2.)) / mp.power(s, 2.), (1 - m) / 4) * mp.power(sigma, -m) / ( mp.sqrt(mp.pi) * z * mp.gamma(m / 2.)) * mp.besselk( (m - 1) / 2., 1 / (4. * mp.sqrt( mp.power(z, 2.) / (n * mp.power(s, 2.) * (n / mp.power(z, 2.) + 4. / mp.power(sigma, 2.)))))) return float(prob / 2 / Ne_scal * scal_fac)
def Ht_AFE_B(z, t): """ This is the much more accurate approx functional eqn posted by Terry at https://terrytao.wordpress.com/2018/02/02/polymath15-second-thread-generalising-the-riemann-siegel-approximate-functional-equation/#comment-492182 :param z: point at which H_t is computed :param t: the "time" parameter :return: the B part in Ht """ z, t = mp.mpc(z), mp.mpc(t) s = (1 + 1j * z.real - z.imag) / 2 tau = mp.sqrt(s.imag / (2 * mp.pi())) M = int(tau) B_pre = (1 / 16.0) * s * (s - 1) * mp.power(mp.pi(), 0.5 * (s - 1)) * mp.gamma(0.5 * (1 - s)) B_sum = 0.0 for m in range(1, M + 1): if t.real > 0: B_sum += mp.exp( (t / 16.0) * mp.power(mp.log( (5 - s) / (2 * mp.pi() * m * m)), 2)) / mp.power(m, 1 - s) else: B_sum += 1 / mp.power(m, 1 - s) return B_pre * B_sum
def F0(s): # works only for x > 14 approx due to the sqrt(x/4PI) factor term1 = mp.power(PI,-1*s/2)*mp.gamma((s+4)/2) x=2*s.imag N = int(mp.sqrt(x/(4*PI))) running_sum=0 for n in range(1,N+1): running_sum += 1/mp.power(n,s) return term1*running_sum
def F0(s): # works only for x > 14 approx due to the sqrt(x/4PI) factor term1 = mp.power(mp.pi(), -0.5 * s) * mp.gamma(0.5 * (s + 4)) x = 2 * s.imag N = int(mp.sqrt(x / (4 * mp.pi()))) running_sum = 0 for n in range(1, N + 1): running_sum += 1 / mp.power(n, s) return term1 * running_sum
def Ft(s,t): # works only for x > 14 approx due to the sqrt(x/4PI) factor term1 = mp.power(PI,-1*s/2)*mp.gamma((s+4)/2) x=2*s.imag N = int(mp.sqrt(x/(4*PI))) running_sum=0 for n in range(1,N+1): running_sum += mp.exp((t/16)*mp.power(mp.log((s+4)/(2*PI*n*n)),2))/mp.power(n,s) # main eqn return term1*running_sum
def gauss_genlaguerre(n, alpha): d = mp.matrix([i + alpha for i in mp.arange(1, 2 * n, 2)]) e = [-mp.sqrt(k * (k + alpha)) for k in mp.arange(1, n)] e.append(mp.mpf('0.0')) e = mp.matrix(e) z = mp.eye(n)[0, :] tridiag_eigen(mp, d, e, z) z = mp.gamma(alpha + 1) * z.apply(lambda x: x**2) return d, z.T
def lourenco_eq_dist_mp(mgamma, m, sigma, Ne, Ne_scal, scal_fac=1): s = mgamma / 2. / Ne_scal * scal_fac #s = mgamma prob = mp.power(2, (1 - m) / 2.) * mp.power(Ne, 0.5) * mp.power( mp.fabs(s), (m - 1) / 2.) * (1 + 1 / (Ne * mp.power(sigma, 2.))) * mp.exp( -Ne * s) / (mp.power(mp.pi, 0.5) * mp.power(sigma, m) * mp.gamma(m / 2.)) * mp.besselk( (m - 1) / 2., Ne * mp.fabs(s) * mp.power(1 + 1 / (Ne * mp.power(sigma, 2.)), 0.5)) return float(prob / 2 / Ne_scal * scal_fac)
def Ft(s, t): # works only for x > 14 approx due to the sqrt(x/4PI) factor term1 = mp.power(mp.pi(), -0.5 * s) * mp.gamma(0.5 * (s + 4)) x = 2 * s.imag N = int(mp.sqrt(x / (4 * mp.pi()))) running_sum = 0 for n in range(1, N + 1): running_sum += mp.exp( (t / 16.0) * mp.power(mp.log( (s + 4) / (2 * mp.pi() * n * n)), 2)) / mp.power(n, s) # main eqn return term1 * running_sum
def Ht_AFE_C(z, t): """ This is the much more accurate approx functional eqn posted by Terry at https://terrytao.wordpress.com/2018/02/02/polymath15-second-thread-generalising-the-riemann-siegel-approximate-functional-equation/#comment-492182 :param z: point at which H_t is computed :param t: the "time" parameter :return: the C part in Ht """ z, t = mp.mpc(z), mp.mpc(t) s = (1 + 1j * z.real - z.imag) / 2 tau = mp.sqrt(s.imag / (2 * mp.pi())) N = int(tau) M = int(tau) C_pre1 = -(1 / 16.0) * s * (s - 1) * mp.power(mp.pi(), -0.5 * s) * mp.gamma(0.5 * s) C_pre2 = mp.gamma(1 - s) * mp.exp(-1j * mp.pi() * s) / (2j * mp.pi()) C_pre3 = mp.power(2j * mp.pi() * M, s - 1) * mp.exp( -1 * t * mp.pi() * mp.pi() / 64.0) C_psi = psi((s / (2j * M * mp.pi())) - N) return C_pre1 * C_pre2 * C_pre3 * C_psi
def v(sigma, s, t): T0 = s.imag T0dash = T0 + mp.pi() * t / 8.0 a0 = mp.sqrt(T0dash / (2 * mp.pi())) if (sigma >= 0): return 1 + 0.4 * mp.power(9, sigma) / a0 + 0.346 * mp.power( 2, 3 * sigma / 2.0) / (a0**2) if (sigma < 0): K = int(mp.floor(-1 * sigma) + 3) ksum = 0.0 for k in range(1, K + 2): ksum += mp.power(1.1 / a0, k) * mp.gamma(mp.mpf(k) / 2.0) return 1 + mp.power(0.9, mp.ceil(-1 * sigma)) * ksum
def AB_analysis(z, t): z, t = mp.mpc(z), mp.mpc(t) s = (1 + 1j * z.real - z.imag) / 2 tau = mp.sqrt(s.imag / (2 * mp.pi())) N = int(tau) M = int(tau) A_pre = (1 / 16) * s * (s - 1) * mp.power(mp.pi(), -1 * s / 2) * mp.gamma( s / 2) A_sum = 0.0 for n in range(1, N + 1): if t.real > 0: A_sum += mp.exp( (t / 16) * mp.power(mp.log( (s + 4) / (2 * mp.pi() * n * n)), 2)) / mp.power(n, s) else: A_sum += 1 / mp.power(n, s) A = A_pre * A_sum B_pre = (1 / 16) * s * (s - 1) * mp.power(mp.pi(), (s - 1) / 2) * mp.gamma( (1 - s) / 2) B_sum = 0.0 for m in range(1, M + 1): if t.real > 0: B_sum += mp.exp( (t / 16) * mp.power(mp.log( (5 - s) / (2 * mp.pi() * m * m)), 2)) / mp.power(m, 1 - s) else: B_sum += 1 / mp.power(m, 1 - s) B = B_pre * B_sum B0 = B_pre * mp.exp((t / 16) * mp.power(mp.log( (5 - s) / (2 * mp.pi())), 2)) AplusB = A + B ABB0 = AplusB / B0 return (AplusB, B0, ABB0, abs(ABB0))
def vwf_err(s_orig, t, lim=10, h=0.01): '''This is the new optimized vwf function where v,w,f are passed only the relevant parameters''' def v(sigma, t, a0, ksumcache): if (sigma >= 0): return 1 + 0.4 * mp.power(9, sigma) / a0 + 0.346 * mp.power( 2, 3 * sigma / 2.0) / (a0**2) if (sigma < 0): K = int(mp.floor(-1 * sigma) + 3) return 1 + mp.power(0.9, mp.ceil(-1 * sigma)) * ksumcache[K] def w(sigma, t, T0dash): wterm1 = 1 + (sigma**2) / (T0dash**2) wterm2 = 1 + ((1 - sigma)**2) / (T0dash**2) wterm3 = (sigma - 1) * mp.log(wterm1) / 4.0 + nonnegative( (T0dash / 2.0) * mp.atan(sigma / T0dash) - sigma / 2.0) + 1 / (12.0 * (T0dash - 0.33)) return mp.sqrt(wterm1) * mp.sqrt(wterm2) * mp.exp(wterm3) def f(sigma, t, sigma0): fterm1 = 0.5 / mp.sqrt(mp.pi() * t) fterm2 = mp.exp((-1 / t) * ((sigma - sigma0)**2)) + mp.exp( (-1 / t) * ((1 - sigma - sigma0)**2)) return fterm1 * fterm2 sigma0 = s_orig.real T = s_orig.imag T0 = T T0dash = T0 + mp.pi() * t / 8.0 a0 = mp.sqrt(T0dash / (2 * mp.pi())) ktermcache = [ mp.power(1.1 / a0, k) * mp.gamma(mp.mpf(k) / 2.0) for k in range(1, lim + 5) ] ksumcache = list(accumulate(ktermcache)) lower_limit, higher_limit = -1.0 * lim, 1.0 * lim integral_sum = 0.0 sigma = lower_limit while (sigma <= higher_limit): sumterm = v(sigma, t, a0, ksumcache) * w(sigma, t, T0dash) * f( sigma, t, sigma0) if ((sigma == lower_limit) or (sigma == higher_limit)): sumterm /= 2 integral_sum += sumterm sigma += h integral_sum *= h return integral_sum
def FixedResGlobal(nsigma): n_levels = len(nsigma) q_perlevel = np.empty(n_levels, dtype=object) for l, lev in enumerate(nsigma): q_total = 0 nQs = len(lev) for j, sig in enumerate(lev): pval = mp.erfc(abs(sig)/mp.sqrt(2)) q = -2*mp.log(pval) q_total += q q_perlevel[l] = [q_total, nQs] nsigma_fixedres = np.zeros(n_levels) for i, entry in enumerate(q_perlevel): qT = entry[0] nQ = entry[1] Dchi2 = mp.gammainc(nQ, 0, 0.5*qT)/mp.gamma(nQ) nsigma_ell = mp.sqrt(2)*mp.erfinv(Dchi2) nsigma_fixedres[i] = nsigma_ell return nsigma_fixedres
ocl_function=make_ocl("return sas_gamma(q);", "sas_gamma", ["lib/sas_gamma.c"]), limits=(-3.1, 10), ) add_function( name="gammaln(x)", mp_function=mp.loggamma, np_function=scipy.special.gammaln, ocl_function=make_ocl("return sas_gammaln(q);", "sas_gammaln", ["lib/sas_gammainc.c"]), #ocl_function=make_ocl("return lgamma(q);", "sas_gammaln"), ) add_function( # Note: "a" is given as A=... on the command line via parse_extra_pars name="gammainc(x)", mp_function=lambda x, a=A: mp.gammainc(a, a=0, b=x) / mp.gamma(a), np_function=lambda x, a=A: scipy.special.gammainc(a, x), ocl_function=make_ocl("return sas_gammainc(%.15g,q);" % A, "sas_gammainc", ["lib/sas_gammainc.c"]), ) add_function( # Note: "a" is given as A=... on the command line via parse_extra_pars name="gammaincc(x)", mp_function=lambda x, a=A: mp.gammainc(a, a=x, b=mp.inf) / mp.gamma(a), np_function=lambda x, a=A: scipy.special.gammaincc(a, x), ocl_function=make_ocl("return sas_gammaincc(%.15g,q);" % A, "sas_gammaincc", ["lib/sas_gammainc.c"]), ) add_function( name="erf(x)", mp_function=mp.erf,
def gamma(z): return mp.gamma(z)
# NOTE: This file implements an slightly different version of li_criter. # It finds the taylor expansion coefficients of log(xi(z/(z-1)), instead if its derivative, # which is in the original li_criterion # # the following code is from # http://fredrikj.net/blog/2013/03/testing-lis-criterion/ # It uses mpmath to calculate taylor expansion of xi function # # It will produce the 1st 21 coefficients for Li-criter # [-0.69315, 0.023096, 0.046173, 0.069213, 0.092198, 0.11511, 0.13793, 0.16064, 0.18322, 0.20566, # 0.22793, 0.25003, 0.27194, 0.29363, 0.31511, 0.33634, 0.35732, 0.37803, 0.39847, 0.41862, 0.43846] # # More information about mpmath can be found at: mpmath.org # http://mpmath.org/ from mpmath import mp mp.dps = 5 mp.pretty = True xi = lambda s: (s - 1) * mp.pi ** (-0.5 * s) * mp.gamma(1 + 0.5 * s) * mp.zeta(s) # calculate 1st 21 coefficients of taylor expansion of log(xi(z/(z-1)) tmp = mp.taylor(lambda z: mp.log(xi(z / (z - 1))), 0, 20) print tmp
def probAmu1mu2(A, mu1, mu2): logAfact = mp.log(mp.gamma(A + 1)) log_probAmu1mu2 = -(mu1 + mu2) + A * mp.log(mu1 + mu2) - logAfact return mp.exp(log_probAmu1mu2)