def _lerchphi(self, z: float, a: int) -> float: """ Wrapper function for mpmath.lerchphi(z,s,a) with three changes: 1. Returns phi(-inf, 1, n+1) -> 0 2. Returns real part only 3. For this application, s=1 always """ # lim z to -inf lerchphi(z, 1, n+1) -> 0 if z == -np.inf: return 0.0 # recurse (dramatic speedup) # REF: http://mpmath.org/doc/current/functions/zeta.html#lerchphi if a > 1 and abs(z) > 0.01: return (self._lerchphi(z, a - 1) - 1 / (a - 1)) / z # delegate to mpmath mpc = lerchphi(z, 1, a) # assume no imaginary component mpf = float(mpc.real) # return return mpf
def plwcconst(alpha, lam, xmin): """ Computes the normalization constant on the discrete power law; i.e., computes C so that 1/C * sum from xmin to infinity of ( x^(-alpha) * e^(-lam x)] ) = 1 The formula below is obtained by noting that the sum above is equal to sum from xmin to infinity of ( x^(-alpha) * e^(-lam x)] ) = e^(-xmin * lam) * HurwitzLerchPhi(e^(-lam), alpha, xmin) where HurwitzLerchPhi is the Lerch Phi function: Phi(z,s,a) = sum from 0 to infinity of ( z^k / (a+k)^s ) (as defined in sympy docs). If one is disinclined to note this fact by deriving it, one is encouraged to look at it in Mathematica and blindly trust the result. Note: The standard notation for the Lerch Phi function above uses "a" as a parameter. This does not correspond to the alpha we pass to the function. Inputs: alpha float, exponent on x, must be > -1 lam float, exponential cutoff, must be > 0 xmin int, starting point for sum, must be >= 1 Outputs: C float, normalization constant """ mp.mp.dps = 40 result = mp.exp(-xmin * lam) * mp.lerchphi(mp.exp(-lam), alpha, xmin) C = float(result) return C
def apply(self, z, s, a, evaluation): "%(name)s[z_, s_, a_]" py_z = z.to_python() py_s = s.to_python() py_a = a.to_python() try: return from_mpmath(mpmath.lerchphi(py_z, py_s, py_a)) except: pass
def x_calc(x, SA, N2A): return (S2A_calc(x,SA,N2A) / N2A * x*(x**N2A-1)/(x-1) - (x**N2A * (-lerchphi(x,1,N2A+1))-np.log(1-x)) ) - 1e-23
def mylerch(z, s, a): lt = lerchphi(z, s, a) lt_real = fp.re(lt) lt_imag = fp.im(lt) return complex(lt_real, lt_imag)
def x_calc(x, SA, N2A): return (S2A_calc(x, SA, N2A) / N2A * x * (x**N2A - 1) / (x - 1) - (x**N2A * (-lerchphi(x, 1, N2A + 1)) - np.log(1 - x))) - 1e-23