def wyns_formulaJ(sigma_los, r_half, distance, angle, gamma=1., walker_or_wolf="wolf"): ''' J factor from M_half for power-law profile (slope = gamma) sigma_los in km/s, r_half in pc, distance in kpc, angle in deg, r_s in kpc ''' r_half = 0.001 * r_half angle = np.deg2rad(angle) delta_Omega = 2. * np.pi * (1 - np.cos(angle)) fac = (2.5 / 4.)**2 if (walker_or_wolf == "wolf"): fac = (0.25 * (27. / 16.) * (4. / 3.)**gamma)**2 if (gamma != 1. and gamma > .5 and gamma < 1.5): factor = 2. * (3. - gamma)**2 * Gamma(gamma - 0.5) / ( np.pi**(2 - gamma) * (3. - 2 * gamma) * Gamma(gamma)) return np.log10(factor * sigma_los**4 * delta_Omega**(1.5 - gamma) / G**2 * distance**(1 - 2. * gamma) * r_half** (2 * gamma - 4.) / GEV2cm5toMsol2kpc5) + np.log10(fac) else: return np.log10(8. / np.sqrt(np.pi) * sigma_los**4 * np.sqrt(delta_Omega) / G**2 / distance / (r_half**2) / GEV2cm5toMsol2kpc5) + np.log10(fac)
def wyns_formulaD(sigma_los, r_half, distance, angle, gamma=1., walker_or_wolf="wolf"): ''' D factor from M_half for power-law profile (slope = gamma) sigma_los in km/s, r_half in pc, distance in kpc, angle in deg, r_s in kpc ''' r_half = 0.001 * r_half angle = np.deg2rad(angle) delta_Omega = 2. * np.pi * (1 - np.cos(angle)) fac = (2.5 / 4.) if (walker_or_wolf == "wolf"): fac = (0.25 * (27. / 16.) * (4. / 3.)**gamma) if (gamma > 1. and gamma < 3.): factor = 2. * Gamma(gamma * 0.5 - 0.5) / (np.pi**(1 - 0.5 * gamma) * Gamma(gamma * 0.5)) return np.log10( factor * sigma_los**2 * delta_Omega**(1.5 - gamma * 0.5) / G * distance**(1. - gamma) * r_half**(gamma - 2.) / GEVcm2toMsolkpc2) + np.log10(fac)
def cCalc(self): """ Calculate normalisation coefficient c """ c = infinite_sum( lambda j: Gamma(j + 1. / 2.) / Gamma(j + 1) * self.beta**(2. * j) * (self.kappa / 2.)** (-2. * j - 1. / 2.) * ModifiedBessel(2. * j + 1. / 2., self.kappa)) return c
def levy(self, D): r"""Levy function. Returns: float: Next Levy number. """ sigma = (Gamma(1 + self.beta) * sin(pi * self.beta / 2) / (Gamma( (1 + self.beta) / 2) * self.beta * 2**((self.beta - 1) / 2)))**( 1 / self.beta) return 0.01 * (self.normal(0, 1, D) * sigma / fabs(self.normal(0, 1, D))**(1 / self.beta))
def qli(l, i): """Return the scalar (q_\lambda^{l})_{i}.""" if i % 2 == 0: return ( 2 ** l / np.pi * Gamma(0.5 * (1 + i)) * Gamma(l + 0.5 * (1 - i)) / Gamma(l + 1) ) else: return 0.0
def _update_mat_a(self): self.a = np.zeros((self.n + 2, self.n + 2)) for k in range(0, self.n + 1): for j in range(0, k + 2): if j == 0: self.a[j, k + 1] = self.delta ** self._params['ALPHA'] / Gamma(self._params['ALPHA'] + 2) * \ (k ** (self._params['ALPHA'] + 1) - (k - self._params['ALPHA']) * ((k + 1) ** self._params['ALPHA'])) elif j == k: self.a[j, k + 1] = self.delta ** self._params['ALPHA'] / Gamma(self._params['ALPHA'] + 2) else: self.a[j, k + 1] = self.delta ** self._params['ALPHA'] / Gamma(self._params['ALPHA'] + 2) * \ ((k - j + 2) ** (self._params['ALPHA'] + 1) + (k - j) ** (self._params['ALPHA'] + 1) - 2 * (k - j + 1) ** (self._params['ALPHA'] + 1))
def f_init(self, eps): A1 = self.r_sp / (G_N * self.M_BH) return ( self.rho_sp * ( self.gamma * (self.gamma - 1) * A1 ** self.gamma * np.pi ** -1.5 / np.sqrt(8) ) * (Gamma(-1 + self.gamma) / Gamma(-1 / 2 + self.gamma)) * self.eps_grid ** (-(3 / 2) + self.gamma) )
def Levy(self): beta = 1.5 sigma = (Gamma(1 + beta) * np.sin(np.pi * beta / 2) / (Gamma((1 + beta) / 2) * beta * 2**((beta - 1) / 2)))**(1 / beta) u = [[0] for j in range(self.D)] v = [[0] for j in range(self.D)] step = [[0] for j in range(self.D)] L = [[0] for j in range(self.D)] for j in range(self.D): u[j] = np.random.normal(0, 1) * sigma v[j] = np.random.normal(0, 1) step[j] = u[j] / abs(v[j])**(1 / beta) L[j] = 0.01 * step[j] return L
def luminosity(Rb, rho0, gamma, mx=e_high_excess): factor = sv / (2 * fx * mx**2) # No annihilation plateau Rb_cm = kpc_to_cm * Rb L_clump = 2**( -1 + 2 * gamma) * np.pi * Rb_cm**3 * rho0**2 * Gamma(3 - 2 * gamma) return factor * L_clump
def gen_normal_dist(x, C_off=0., C_sc=1., mu=0., alpha=1.0, beta=2.0): """ Calculates a generalized normal distribution function. If beta = 2, then normal. If you increase beta it gets more top-hatty. Initialized for a regular normal distribution. INPUTS: x np. array C_off offset constant C_sc scaling constant mu mean beta shape alpha scale (or ~sigma) RETURNS: Generalized normal EXAMPLE: x = np.linspace(-3,3,100) y = gen_normal_dist(x,mu=0,alpha=1,beta=5.) plt.plot(x,y) NOTES: See PDF here: https://en.wikipedia.org/wiki/Generalized_normal_distribution """ return C_sc * ((beta) / (2. * alpha * Gamma(1. / beta)) ) * np.exp(-(np.abs(x - mu) / alpha)**beta) + C_off
def group_size_distribution_asymptotics(N, P, mmax=None, simple_pochhammer_approximation=True): """Get the asymptotic equilibrium group size distribution of a Flockwork-P model given node number N and probability to reconnect P. Parameters ---------- N : int Number of nodes P : float Probability to reconnect mmax : int, default = None The maximum group size for which to calculate the asymptotics simple_pochhammer_approximation : bool, default = True Whether to use a simple first order Pochhammer approximation or the Gamma-function approximation. Returns ------- ms : numpy.ndarray group size vector dist : numpy.ndarray Asymptotic group size distribution """ N = int(N) P = float(P) assert N > 2 assert P >= 0. assert P < 1. if mmax is None: mmax = int(N) // 2 ms = np.arange(1, mmax + 1) if P == 0.: ms = np.arange(N + 1) dist = np.zeros((N + 1, )) dist[1] = N else: dist = [(1. - P)] for m in ms[1:]: if simple_pochhammer_approximation: factor = (1 - P / (N - 1) * (m - 1) * (m - 2) / 2)**(-1) else: factor = ((-1)**(m % 2) * (P * m / (N - 1) / np.exp(1))**m * 2 * np.pi / Gamma(-(N - 1) / P) * m**(-(N - 1) / P - 0.5))**(-1) this = 1 / m * (P / np.exp(1))**(m - 1) * ( (N - 1) / (N - m))**(N - m + 0.5) * factor dist.append(this) return ms, N * np.array(dist)
def _update_mat_b(self): self.b = np.zeros((self.n + 2, self.n + 2)) for k in range(0, self.n + 1): for j in range(0, k + 1): self.b[j, k + 1] = self.delta ** self._params['ALPHA'] / Gamma(self._params['ALPHA'] + 1) * \ ((k - j + 1) ** self._params['ALPHA'] - (k - j) ** self._params['ALPHA'])
def f_init(eps): if G_N * self.M_BH / self.r_sp < eps and eps <= G_N * self.M_BH / self.r_p: return ( self.rho_sp * ((eps * self.r_sp) / (G_N * self.M_BH)) ** self.gamma * ( (1 - self.gamma) * self.gamma * Beta( -1 + self.gamma, 0.5, (G_N * self.M_BH) / (eps * self.r_sp) ) + (np.sqrt(np.pi) * Gamma(1 + self.gamma)) / Gamma(-0.5 + self.gamma) ) ) / (2.0 * np.sqrt(2) * eps ** 1.5 * np.pi ** 2) else: return 0.0
def PandelPDF(r, tres): a = r / lambda_s_ b = 1. / tau_ + c_ice_ / lambda_a_ p = 1. / Gamma(a) p *= tau_**(-a) p *= numpy.exp(-r / lambda_a_) p *= (tres)**(a - 1) p *= numpy.exp(-b * tres) return p
def rough_heston_implied_variance_asymptotic(ttm, log_strike, params, critical_time=None, critical_moment=None): if critical_moment is None: critical_moment = rough_heston_critical_moment(ttm, params) if critical_time is None: critical_time = lambda u: rough_heston_critical_time(u, params) theta = 2 * Gamma(2 * params['ALPHA']) / Gamma( params['ALPHA']) / params['XI']**2 def f2(s): return s**-params['ALPHA'] * (1 + s)**-params['ALPHA'] lambda0 = params['V0'] * theta * Gamma(2 * params['ALPHA'] - 1) / Gamma( params['ALPHA']) / ttm # lambda1 = ... slope = rough_heston_critical_slope(ttm, params, critical_time=critical_time, critical_moment=critical_moment) beta = (lambda0 * (2 * params['ALPHA'] - 1) * slope**(1 - 2 * params['ALPHA']))**(1 / 2 / params['ALPHA']) # a1 = ... a2 = 2 * beta / (2 * params['ALPHA'] - 1) a3 = critical_moment + 1 b1 = np.sqrt(2) * (np.sqrt(a3 - 1) - np.sqrt(a3 - 2)) b2 = a2 / np.sqrt(2) * (1 / np.sqrt(a3 - 2) - 1 / np.sqrt(a3 - 1)) b3 = 1 / np.sqrt(2) * (3 / 4 - 1 / 4 / params['ALPHA']) * ( 1 / np.sqrt(a3 - 1) - 1 / np.sqrt(a3 - 2)) print(f"b1: {b1}; b2: {b2}; b3: {b3}") return (b1 * log_strike**0.5 + b2 * log_strike**(1 / 2 - 1 / 2 / params['ALPHA']))**2 / ttm
def inv_chi_squared_entropy(self): """ Entropy of self's Inverse-Chi-Squared distribution. Returns: x: entropy of self's Inverse-Chi-Squared distribution. """ mu, sigmasq, kappa, nu = self.get_params() return (nu * 0.5 + np.log(sigmasq * nu * 0.5 * abs(Gamma(0.5 * nu))) - (1. + 0.5 * nu) * dg(0.5 * nu))
def inv_chi_squared_log_partition(self): """ Log partition function of self's Inverse-Chi-Squared distribution. Returns: x: log partition of self's Inverse-Chi-Squared distribution. """ mu, sigmasq, kappa, nu = self.get_params() return np.log(abs(Gamma( 0.5 * nu))) - nu * 0.5 * np.log(sigmasq * nu * 0.5)
def inv_wishart_log_partition(self): """ Log partition function of self's Inverse-Chi-Squared distribution. Returns: x: log partition of self's Inverse-Chi-Squared distribution. """ mu, sigma, kappa, nu = self.get_params() D = self.dim return -(nu*0.5*np.log(np.linalg.det(sigma)) - nu*D/2.*np.log(2) - D*(D - 1.)/4.*np.log(np.pi) - sum([np.log(abs(Gamma(0.5*(nu + 1. - i)))) for i in range(1, D + 1)]))
def negbin(x, theta): """ Alternative formulation of the negative binomial distribution pmf. scipy does not support the extended definition so we have to supply it ourselves. Parameters ---------- x: int The random variable. theta: real array [p, r] p is the probability of success of the Bernoulli test and r the number of "failures". Returns ------- Probability that a discrete random variable is exactly equal to some value. """ p, r = theta if p == 0 and r == 0: return 1 if x == 0 else 0 else: return (Gamma(r + x) * (1 - p)**r * p**x / (Gamma(r) * sp.special.factorial(x)))
def rough_heston_critical_time(u, params, n=100): def c1(s): return s * (s - 1) / 2 def c2(s): return params['RHO'] * params['XI'] * s - params['LAMBDA'] c3 = params['XI']**2 / 2 def d1(s): return c1(s) * c3 def d2(s): return c2(s) assert c1(u) > 0 assert c2(u) / 2 >= 0 def v(k): return Gamma(params['ALPHA'] * k + 1) / Gamma(params['ALPHA'] * k - params['ALPHA'] + 1) a = [d1(u) / v(1)] for i in range(1, n): a += [(d2(u) * a[-1] + np.sum(a[:-1] * np.flip(a[:-1]))) / v(i + 1)] # case A, left-hand side if u < params['LAMBDA'] / params['XI'] / params['RHO']: return (a[-1] * (n**(1 - params['ALPHA'])) * (Gamma(params['ALPHA'])**2) / (params['ALPHA']**params['ALPHA']) / Gamma(2 * params['ALPHA']))**(-1 / params['ALPHA'] / (n + 1)) # case B, right-hand side, get lower bound else: return np.abs(a[-1])**(-1 / params['ALPHA'] / n)
def h_pade_small_time(u, t, params): def beta(n): betas = [-u * (u + 1j) / 2] for k in range(1, n + 1): betas += [ np.sum([ betas[i] * betas[j] * Gamma(1 + i * params['ALPHA']) / Gamma(1 + (i + 1) * params['ALPHA']) * Gamma(1 + j * params['ALPHA']) / Gamma(1 + (j + 1) * params['ALPHA']) if i + j == k - 2 else 0 for i in range(k - 1) for j in range(k - 1) ]) + 1j * params['RHO'] * u * betas[k - 1] * Gamma(1 + (k - 1) * params['ALPHA']) / Gamma(1 + k * params['ALPHA']) ] return betas[n] return np.sum([ Gamma(1 + j * params['ALPHA']) / Gamma(1 + (j + 1) * params['ALPHA']) * beta(j) * params['XI']**j * t**((j + 1) * params['ALPHA']) for j in range(30) ])
def beta(n): betas = [-u * (u + 1j) / 2] for k in range(1, n + 1): betas += [ np.sum([ betas[i] * betas[j] * Gamma(1 + i * params['ALPHA']) / Gamma(1 + (i + 1) * params['ALPHA']) * Gamma(1 + j * params['ALPHA']) / Gamma(1 + (j + 1) * params['ALPHA']) if i + j == k - 2 else 0 for i in range(k - 1) for j in range(k - 1) ]) + 1j * params['RHO'] * u * betas[k - 1] * Gamma(1 + (k - 1) * params['ALPHA']) / Gamma(1 + k * params['ALPHA']) ] return betas[n]
def normalgammapdf(mu, Lambda, muprior, kappa, alpha, beta): C = (np.sqrt(kappa) * beta**alpha) / (Gamma(alpha) * np.sqrt(2 * np.pi)) lam = C * np.power(Lambda, (alpha - 0.5)) * np.exp(-beta * Lambda) diff = (mu - muprior)**2 p = lam * np.exp(-kappa / 2 * (np.dot(Lambda, np.transpose(diff)))) return p
def sedov(t, E0, rho0, g, n=1000, nu=3): """ solve the sedov problem t - the time E0 - the initial energy rho0 - the initial density n - number of points (10000) nu - the dimension g - the polytropic gas gamma """ # the similarity variable v_min = 2.0 / ((nu + 2) * g) v_max = 4.0 / ((nu + 2) * (g + 1)) v = v_min + arange(n) * (v_max - v_min) / (n - 1.0) a = calc_a(g, nu) beta = calc_beta(v, g=g, nu=nu) lbeta = log(beta) r = exp(-a[0] * lbeta[0] - a[2] * lbeta[1] - a[1] * lbeta[2]) rho = ( (g + 1.0) / (g - 1.0)) * exp(a[3] * lbeta[1] + a[5] * lbeta[3] + a[4] * lbeta[2]) p = exp(nu * a[0] * lbeta[0] + (a[5] + 1) * lbeta[3] + (a[4] - 2 * a[1]) * lbeta[2]) u = beta[0] * r * 4.0 / ((g + 1) * (nu + 2)) p *= 8.0 / ((g + 1) * (nu + 2) * (nu + 2)) # we have to take extra care at v=v_min, since this can be a special point. # It is not a singularity, however, the gradients of our variables (wrt v) are. # r -> 0, u -> 0, rho -> 0, p-> constant u[0] = 0.0 rho[0] = 0.0 r[0] = 0.0 p[0] = p[1] # volume of an n-sphere vol = (pi**(nu / 2.0) / Gamma(nu / 2.0 + 1)) * power(r, nu) # note we choose to evaluate the integral in this way because the # volumes of the first few elements (i.e near v=vmin) are shrinking # very slowly, so we dramatically improve the error convergence by # finding the volumes exactly. This is most important for the # pressure integral, as this is on the order of the volume. # (dimensionless) energy of the model solution de = rho * u * u * 0.5 + p / (g - 1) # integrate (trapezium rule) q = inner(de[1:] + de[:-1], diff(vol)) * 0.5 # the factor to convert to this particular problem fac = (q * (t**nu) * rho0 / E0)**(-1.0 / (nu + 2)) # shock speed shock_speed = fac * (2.0 / (nu + 2)) rho_s = ((g + 1) / (g - 1)) * rho0 r_s = shock_speed * t * (nu + 2) / 2.0 p_s = (2.0 * rho0 * shock_speed * shock_speed) / (g + 1) u_s = (2.0 * shock_speed) / (g + 1) r *= fac * t u *= fac p *= fac * fac * rho0 rho *= rho0 return r, p, rho, u, r_s, p_s, rho_s, u_s, shock_speed
def factorial(n): return Gamma(n + 1)
from scipy.stats import gennorm #So in our notations form_parameter=beta:=gamma. Also we fix scale_parameter = Gamma(beta). #Generalized normal distribution is truncated into the interval [a,b]. #phi = lambda x, gamma=2: (gamma/(2*Gamma(1/gamma)))*exp(-np.abs(x)**gamma) phi = lambda x, gamma: gennorm.pdf(x, gamma) log_phi = lambda x, gamma: gennorm.logpdf(x, gamma) Phi = lambda x, gamma: gennorm.cdf(x, gamma) #TGN_pdf = lambda x, gamma,alpha,a,b: 1/(Phi((b-alpha)/(Gamma(gamma)),gamma)-Phi((a-alpha)/(Gamma(gamma)),gamma)) * (1/Gamma(gamma)) * phi((x-alpha)/Gamma(gamma),gamma) * int(a<=x<=b) #log_TGN_pdf = lambda x, gamma,alpha,a,b: log(TGN_pdf(x, gamma,alpha,a,b)) #shape=(Gamma(gamma)*abs(b-a)/10) #log_TGN_pdf = lambda x, gamma,alpha,a,b: log_phi((x-alpha)/Gamma(gamma),gamma) - log(Gamma(gamma)*(Phi((b-alpha)/(Gamma(gamma)),gamma)-Phi((a-alpha)/(Gamma(gamma)),gamma))) #numerically more stable! log_TGN_pdf = lambda x, gamma, alpha, a, b: log_phi( (x - alpha) / (Gamma(gamma) * abs(b - a) / 10), gamma) - log( (Gamma(gamma) * abs(b - a) / 10) * (Phi( (b - alpha) / ((Gamma(gamma) * abs(b - a) / 10)), gamma) - Phi( (a - alpha) / ((Gamma(gamma) * abs(b - a) / 10)), gamma) )) #numerically more stable! def TGN_sample(size, gamma, alpha, x_min, x_max): domain = (x_min, x_max) return ars.adaptive_rejection_sampling( logpdf=lambda x: log_TGN_pdf(x, gamma, alpha, x_min, x_max), a=x_min, b=x_max, domain=domain, n_samples=size)
def factorial(n): """Just the factorial function, no frills.""" return Gamma(n + 1)
def levy(self): sigma = (Gamma(1 + self.beta) * sin(pi * self.beta / 2) / (Gamma(1 + self.beta) * self.beta * 2**( (self.beta - 1) / 2)))**(1 / self.beta) return 0.01 * (self.normal(0, 1) * sigma / fabs(self.normal(0, 1))**(1 / self.beta))
def dist_poisson(lam,x): return (lam**x)*(np.exp(-lam))/(Gamma(x))
def eval_Gamma(n, a, b): y = math.pow(a, b) * math.exp(-a * n) * math.pow(n, b - 1) / (Gamma(b)) return y