def my_special_gamma(n): # return gamma(n/2) if n % 2 == 0: # n/2 is an integer return math.factorial(n / 2 - 1) else: root_pi = math.sqrt(math.pi) return root_pi * ss.factorial2(n-2) / math.pow(2.0, (n-1) / 2.0)
def norm_prim_cart(self): r"""Return the normalization constants of the Cartesian Gaussian primitives. For a Cartesian primitive with exponent :math:`\alpha_i`, the normalization constant is: .. math:: N(\alpha_i, \vec{a}) = \sqrt { \left(\frac{2\alpha_i}{\pi}\right)^\frac{3}{2} \frac{(4\alpha_i)^{a_x + a_y + a_z}}{(2a_x - 1)!! (2a_y - 1)!! (2a_z - 1)!!}} Returns ------- norm_prim_cart : np.ndarray(L, K) The normalization constants of the Cartesian Gaussian primitives. `L` is the number of contracted Cartesian Gaussian functions for the given angular momentum, i.e. :math:`(\ell + 1) * (\ell + 2) / 2` `K` is the number of exponents (i.e. primitives). """ exponents = self.exps[np.newaxis, :] angmom_components_cart = self.angmom_components_cart[:, :, np.newaxis] return ((2 * exponents / np.pi)**(3 / 4) * ( (4 * exponents)**(self.angmom / 2)) / np.sqrt( np.prod(factorial2(2 * angmom_components_cart - 1), axis=1)))
def test_rank_one(n): """Test the hafnian of rank one matrices so that it is within 10% of the exact value""" x = np.random.rand(n) A = np.outer(x, x) exact = factorial2(n - 1) * np.prod(x) approx = hafnian(A, approx=True, num_samples=10000) assert np.allclose(approx, exact, rtol=2e-1, atol=0)
def ME_to_inverse_half_life(ME, Jinit, lam, Ediff, EM): """ inputs: ME = (Jfinal || O^lam || Jinit) EM: "E" or "M" output: inverse life time (additive quantity) ln2 / T_1/2 """ if (abs(ME) < 1.e-10): return 0 hc = physical_constants["Planck constant over 2 pi times c in MeV fm"][0] if (EM == "E"): return 5.498e22 * (ediff / hc)**(2 * rank + 1) * (rank + 1) / ( rank * factorial2(2 * lam + 1)**2) * BEM(ME, Jinit) if (EM == "M"): return 6.080e20 * (ediff / hc)**(2 * rank + 1) * (rank + 1) / ( rank * factorial2(2 * lam + 1)**2) * BEM(ME, Jinit)
def normalisation(self): """Calculates normalisation constant for the primitive gaussian and stores in self.normalisation once called. Returns ------- self.normalisation_memo : float """ if self.normalisation_memo is None: l, m, n = self.integral_exponents out1 = factorial2(2 * l - 1) * factorial2(2 * m - 1) * factorial2(2 * n - 1) out2 = (pi / (2 * self.exponent))**(3 / 2) out3 = (4 * self.exponent)**(l + m + n) self.normalisation_memo = 1 / sqrt((out1 * out2) / out3) return self.normalisation_memo
def __init__(self, l, coeffs, zetas): super().__init__() self.ls = torch.tensor(get_cartesian_angulars(l)) anorms = 1.0 / np.sqrt(factorial2(2 * self.ls - 1).prod(-1)) self.register_buffer('anorms', fp_tensor(anorms)) rnorms = (2 * zetas / np.pi)**(3 / 4) * (4 * zetas)**(l / 2) self.register_buffer('coeffs', rnorms * coeffs) self.register_buffer('zetas', zetas)
def __init__(self, epsilon, cutoff, na, q, minSize, maxSize): self.epsilon = epsilon self.cutoff = cutoff self.minSize = minSize self.maxSize = maxSize self.na = na self.q = q self.coeffs = [] for index in range(0, q + 1): first_expr = np.power( -1, index + 1) / (factorial2(2 * q - 2 * index, exact=True) * factorial2(2 * index, exact=True)) second_expr = factorial2(10 + 2 * q, exact=True) / (factorial2(8, exact=True) * (10 + 2 * index)) third_expr = np.power(cutoff, -(10 + 2 * index)) self.coeffs.append(first_expr * second_expr * third_expr)
def normalize(self): a = np.array(self.a) N = (2 / np.pi) ** (3 / 4) * 2 ** np.sum(a) * \ self.alpha ** ((2 * np.sum(a) + 3) / 4) / \ np.sqrt(np.prod(factorial2(2 * a - 1))) self.N = N self.n_primitives = len(self.alpha) return
def FACTDOUBLE(number: func_xltypes.XlNumber) -> func_xltypes.XlNumber: """Returns the double factorial of a number. https://support.office.com/en-us/article/ factdouble-function-e67697ac-d214-48eb-b7b7-cce2589ecac8 """ if number < 0: raise xlerrors.NumExcelError('Negative values are not allowed') return factorial2(int(number), exact=True)
def func_temp(ws): k, kp = ws[0], ws[1] O1 = binom(n_p, kp) * binom(n, k) O2 = H(n_p - kp, 0) * H(n - k, 0) O3 = ((2 * np.sqrt(alphap))**kp) * ((2 * np.sqrt(alpha))**k) if (k + kp) % 2 != 0: return 0. else: return O1*O2*O3*factorial2(int(k+kp-1))\ /np.sqrt((alpha+alphap)**(k+kp))
def __S(e1, e2, R1, R2, ang1, ang2): S = (np.pi/(e1+e2))**(3/2) P = (e1*R1+e2*R2)/(e1+e2) for i in range(3): s = 0 for k in range(0, int((ang1[i]+ang2[i])/2)+1): s += __ck(2*k, ang1[i], ang2[i], P[i]-R1[i], P[i]-R2[i]) * \ special.factorial2(2*k-1, exact=True) / (2*(e1+e2))**k S *= s return S
def KaulaF(n, q, p, j): """ Series coefficient in the Taylor expansion of the Kaula inclination function F_{nqp}(I). See, e.g., Kaula (1962,1966) or Ellis & Murray (2000). The function returns the jth term of the Taylor expansion in the variable s = sin(I/2). I.e. KaulaF(n,q,p,j) = (1/j!) d^j F{nqp}/ ds^j This implementation is based on the Mathematica package by Fabio Zugno available at: https://library.wolfram.com/infocenter/MathSource/4256/ Arguments --------- n : int q : int p : int j : int Returns ------- float """ if q == 0 and 2 * p == n: return (-1)**(j + n) * binom(n, j) * binom( n + j, j) * factorial2(n - 1) / factorial2(n) if n - 2 * p - q < 0: if n - q < 0: return 0 return (-1)**(n - q) * factorial(n + q) * KaulaF(n, -q, n - p, j) / factorial(n - q) numerator = (-1)**j * factorial2(2 * n - 2 * p - 1) numerator *= binom(n / 2 + p + q / 2, j) numerator *= threeFtwo([-j, -2 * p, -n - q], [1 + n - 2 * p - q, -(n / 2) - p - q / 2]) if p < 0: return 0. denom = factorial(n - 2 * p - q) * factorial2(2 * p) return numerator / denom
def compute_Si(lA, lB, PA, PB, gamma): """ Calculate the i-th coordinate contribution to the matrix element S[A,B]. """ Si = 0.0 for k in range( int((lA + lB) / 2) + 1 ): # note range is up to add INCLUDING floor of (lA+lB)/2, hence +1 Si += compute_ck(2*k, lA, lB, PA, PB) * np.sqrt(np.pi / gamma) * \ (special.factorial2(2*k-1,exact=True) / (2*gamma)**k) return Si
def pn_leading_order_amplitude(ell, m, x, mass_ratio=1.0): """Return the leading-order amplitude of r*h/M in PN theory These expressions are from Eqs. (330) of Blanchet's Living Review (2014). Note that `x` is just the orbital angular velocity to the (2/3) power. """ from scipy.special import factorial, factorial2 if m < 0: return (-1)**ell * np.conjugate( pn_leading_order_amplitude(ell, -m, x, mass_ratio=mass_ratio)) if mass_ratio < 1.0: mass_ratio = 1.0 / mass_ratio nu = mass_ratio / (1 + mass_ratio)**2 X1 = mass_ratio / (mass_ratio + 1) X2 = 1 / (mass_ratio + 1) def sigma(ell): return X2**(ell - 1) + (-1)**ell * X1**(ell - 1) if (ell + m) % 2 == 0: amplitude = (((-1)**((ell - m + 2) / 2) / (2**(ell + 1) * factorial( (ell + m) // 2) * factorial( (ell - m) // 2) * factorial2(2 * ell - 1))) * np.sqrt( (5 * (ell + 1) * (ell + 2) * factorial(ell + m) * factorial(ell - m)) / (ell * (ell - 1) * (2 * ell + 1))) * sigma(ell) * (1j * m)**ell * x**(ell / 2 - 1)) else: amplitude = (((-1)**((ell - m - 1) / 2) / (2**(ell - 1) * factorial( (ell + m - 1) // 2) * factorial( (ell - m - 1) // 2) * factorial2(2 * ell + 1))) * np.sqrt( (5 * (ell + 2) * (2 * ell + 1) * factorial(ell + m) * factorial(ell - m)) / (ell * (ell - 1) * (ell + 1))) * sigma(ell + 1) * 1j * (1j * m)**ell * x**((ell - 1) / 2)) return 8 * np.sqrt(np.pi / 5) * nu * x * amplitude
def Nrun(basisset): # Normalize primitive functions for i in range(len(basisset)): for j in range(len(basisset[i][5])): a = basisset[i][5][j][1] l = basisset[i][5][j][3] m = basisset[i][5][j][4] n = basisset[i][5][j][5] part1 = (2.0 / math.pi)**(3.0 / 4.0) part2 = 2.0**(l + m + n) * a**( (2.0 * l + 2.0 * m + 2.0 * n + 3.0) / (4.0)) part3 = math.sqrt( scm.factorial2(int(2 * l - 1)) * scm.factorial2(int(2 * m - 1)) * scm.factorial2(int(2 * n - 1))) basisset[i][5][j][0] = part1 * ((part2) / (part3)) """ # Normalize contractions for k in range(len(basisset)): if len(basisset[k][5]) != 1: l = basisset[k][5][0][3] m = basisset[k][5][0][4] n = basisset[k][5][0][5] L = l+m+n factor = (np.pi**(3.0/2.0)*scm.factorial2(int(2*l-1))*scm.factorial2(int(2*m-1))*scm.factorial2(int(2*n-1)))/(2.0**L) sum = 0 for i in range(len(basisset[k][5])): for j in range(len(basisset[k][5])): alphai = basisset[k][5][i][1] alphaj = basisset[k][5][j][1] ai = basisset[k][5][i][2]*basisset[k][5][i][0] aj = basisset[k][5][j][2]*basisset[k][5][j][0] sum += ai*aj/((alphai+alphaj)**(L+3.0/2.0)) Nc = (factor*sum)**(-1.0/2.0) for i in range(len(basisset[k][5])): basisset[k][5][i][0] *= Nc """ return basisset
def S(self, orb): ''' Overlap integral Page 2315 https://journals.jps.jp/doi/pdf/10.1143/JPSJ.21.2313 ''' assert isinstance(orb, pgto) l1, m1, n1 = self.pow l2, m2, n2 = orb.pow a1 = self.exp a2 = orb.exp A = self.origin B = orb.origin gamma = a1+a2 P = (a1*A+a2*B)/(a1+a2) AB_sq = dot(A-B, A-B) PA = sqrt(dot(P-A, P-A)) PB = sqrt(dot(P-B, P-B)) ## fj(l,m,a,b) f = lambda l,m,a,b,j,i : comb(l,i)*comb(m,j-i)*a**i*b**(j-i) # Sum over 0 <= i <= j for all possible j <=l1+l2 fj = [] for j in range(l1+l2+1): fj_temp = [] for i in range(j+1): fj_temp.append(f(l1, l2, PA, PB)) #end for fj.append(sum(fj_temp)) #end for ## fj complete # start integral pre = (pi/gamma)**3./2*exp(-a1*a2*AB_sq/gamma) int_out = 0 for q in [l1+l2, m1+m2, n1+n2]: int_in = 1 for i in range(int(ceil(0.5*(q)))): int_in *= f[2*i]*factorial2(2*i-1)/(2*gamma)**i #end for int_out += int_in #end for result = pre*int_out return result
def __init__(self, n_max): """Initialize class. Parameters ---------- n_max : int Maximum angular momentum. """ self.binomials = [[binom(n, i) for i in range(n + 1)] for n in range(n_max + 1)] facts = [factorial2(m, 2) for m in range(2 * n_max)] facts.insert(0, 1) self.facts = np.array(facts)
def low_rank_hafnian(G): r"""Returns the hafnian of the low rank matrix :math:`\bm{A} = \bm{G} \bm{G}^T` where :math:`\bm{G}` is rectangular of size :math:`n \times r` with :math:`r \leq n`. Note that the rank of :math:`\bm{A}` is precisely :math:`r`. The hafnian is calculated using the algorithm described in Appendix C of *A faster hafnian formula for complex matrices and its benchmarking on a supercomputer*, :cite:`bjorklund2018faster`. Args: G (array): factorization of the low rank matrix A = G @ G.T. Returns: (complex): hafnian of A. """ n, r = G.shape if n % 2 != 0: return 0 if r == 1: return factorial2(n - 1) * np.prod(G) poly = 1 x = symbols("x0:" + str(r)) for k in range(n): term = 0 for j in range(r): term += G[k, j] * x[j] poly = expand(poly * term) comb = partitions(r, n // 2) haf_val = 0.0 for c in comb: monomial = 1 facts = 1 for i, pi in enumerate(c): monomial *= x[i]**(2 * pi) facts = facts * factorial2(2 * pi - 1) haf_val += complex(poly.coeff(monomial) * facts) return haf_val
def fcint(v1, v2): aa = 0.0 for k1 in range(v1 + 1): for k2 in range(v2 + 1): if (k1 + k2) % 2 == 0: ik = factorial2(k1 + k2 - 1) / (a1 + a2)**((k1 + k2) / 2) else: ik = 0 aa += comb(v1,k1)*comb(v2,k2)*eval_hermite(v1-k1,b1)\ *eval_hermite(v2-k2,b2)*(2*sqrt(a1))**k1*(2*sqrt(a2))**k2*ik bb = aa * A * exp(-S) / 2**(v1 + v2) / factorial(v1) / factorial(v2) * aa #bb = A*exp(-S)/2**(v1+v2) return bb
def F(n, x): #calculate Boys function value by numerical integration if x < 1e-7: return 1 / (2 * n + 1) if n == 20: res1 = 1 / (2 * n + 1) #if x < 1e-7: # return res1 for k in range(1, 11): res1 += (-x)**k / factorial(k) / (2 * n + 2 * k + 1) res2 = factorial2(2 * n - 1) / 2**(n + 1) * np.sqrt( np.pi / x**(2 * n + 1)) res = min(res1, res2) return res return (2 * x * F(n + 1, x) + np.exp(-x)) / (2 * n + 1)
def test_evaluate_construct_array_contraction(): """Test gbasis.evals.eval.Eval.construct_array_contraction.""" test = GeneralizedContractionShell(1, np.array([0.5, 1, 1.5]), np.array([1.0, 2.0]), np.array([0.1, 0.01])) answer = np.array([ _eval_deriv_contractions( np.array([[2, 3, 4]]), np.array([0, 0, 0]), np.array([0.5, 1, 1.5]), np.array([angmom_comp]), np.array([0.1, 0.01]), np.array([1, 2]), np.array([[ (2 * 0.1 / np.pi)**(3 / 4) * (4 * 0.1)**(1 / 2) / np.sqrt(np.prod(factorial2(2 * angmom_comp - 1))), (2 * 0.01 / np.pi)**(3 / 4) * (4 * 0.01)**(1 / 2) / np.sqrt(np.prod(factorial2(2 * angmom_comp - 1))), ]]), ) for angmom_comp in test.angmom_components_cart ]).reshape(3, 1) assert np.allclose( Eval.construct_array_contraction(points=np.array([[2, 3, 4]]), contractions=test), answer) with pytest.raises(TypeError): Eval.construct_array_contraction(points=np.array([[2, 3, 4]]), contractions=None) with pytest.raises(TypeError): Eval.construct_array_contraction(points=np.array([[2, 3, 4]]), contractions={1: 2}) with pytest.raises(TypeError): Eval.construct_array_contraction(points=np.array([2, 3, 4]), contractions=test) with pytest.raises(TypeError): Eval.construct_array_contraction(points=np.array([[3, 4]]), contractions=test)
def gauss_integral(n): r""" Solve the integral \int_0^1 exp(-0.5 * x * x) x^n dx See https://en.wikipedia.org/wiki/List_of_integrals_of_Gaussian_functions Examples -------- >>> ans = gauss_integral(3) >>> np.allclose(ans, 2) True >>> ans = gauss_integral(4) >>> np.allclose(ans, 3.75994) True """ factor = np.sqrt(np.pi * 2) if n % 2 == 0: return factor * factorial2(n - 1) / 2 elif n % 2 == 1: return factor * norm.pdf(0) * factorial2(n - 1) else: raise ValueError("n must be odd or even.")
def lpKernel(N, freq): # # Lowpass filter 1D MAXFLAT kernel generator # # N is the filter half-size, must be odd # freq is the normalised cutoff frequency # # Returns the filter kernel of size (2N+1) # num = 2 * N + 1 result = np.zeros((num, 1)) for n in range(N + 1): i = n + N im = N - n if (n == 0): result[i] = freq else: p = n % 2 val = (ss.factorial2(N)**2 * np.pi**(p - 1) * np.sin(n * np.pi * freq)) / (2**p * n * ss.factorial2(i) * ss.factorial2(im)) result[i] = val result[im] = val return result / np.sum(result)
def gaussian_moment(p): """ Computes the moments of the standard normal distribution. Used when training via the method of moments. Parameters: ----------- p: int Returns: ----------- the pth moment of the standard Gaussian. """ if p % 2 == 0: return factorial2(p - 1) else: return 0
def test_gauss_quadrature(self): degree = 4 alpha = 0. beta = 0. ab = jacobi_recurrence(degree + 1, alpha=alpha, beta=beta, probability=True) x, w = gauss_quadrature(ab, degree + 1) for ii in range(degree + 1): if ii % 2 == 0: assert np.allclose(np.dot(x**ii, w), 1. / (ii + 1.)) else: assert np.allclose(np.dot(x**ii, w), 0.) x_np, w_np = np.polynomial.legendre.leggauss(degree + 1) assert np.allclose(x_np, x) assert np.allclose(w_np / 2, w) degree = 4 alpha = 4. beta = 1. ab = jacobi_recurrence(degree + 1, alpha=alpha, beta=beta, probability=True) x, w = gauss_quadrature(ab, degree + 1) true_moments = [1., -3. / 7., 2. / 7., -4. / 21., 1. / 7.] for ii in range(degree + 1): assert np.allclose(np.dot(x**ii, w), true_moments[ii]) degree = 4 rho = 0. ab = hermite_recurrence(degree + 1, rho, probability=True) x, w = gauss_quadrature(ab, degree + 1) from scipy.special import factorial2 assert np.allclose(np.dot(x**degree, w), factorial2(degree - 1)) x_sp, w_sp = sp.roots_hermitenorm(degree + 1) w_sp /= np.sqrt(2 * np.pi) assert np.allclose(x_sp, x) assert np.allclose(w_sp, w)
def gint(m, center1, exponent1, n, center2, exponent2 ): #calculate one electron integral of two gaussian primitives newcenter = (exponent1 * center1 + exponent2 * center2) / (exponent1 + exponent2) newexponent = exponent1 + exponent2 tempexponent = exponent1 * exponent2 / (exponent1 + exponent2) e12 = np.exp(-tempexponent * (center1 - center2)**2) res = 0 for i in range(m + 1): for j in range(n + 1): if (i + j) % 2 == 0: res += (np.sqrt(np.pi / newexponent) * comb(m, i) * comb(n, j) * factorial2(i + j - 1) / (2 * newexponent)**((i + j) / 2) * (newcenter - center1)**(m - i) * (newcenter - center2)**(n - j)) res = e12 * res return res
def gob_cart_normalization(alpha: np.ndarray, n: np.ndarray) -> np.ndarray: """Compute normalization of exponent. Parameters ---------- alpha Gaussian basis exponents n Cartesian subshell angular momenta Returns ------- np.ndarray The normalization constant for the gaussian cartesian basis. """ return np.sqrt((4 * alpha)**sum(n) * (2 * alpha / np.pi)**1.5 / np.prod(factorial2(2 * n - 1)))
def correction_factor(snrval, Nch): # Calculate the channel-dependent and SNR-dependent correction factor CONSTFACTOR = math.sqrt(0.5 * math.pi) # Constant snrval_squared = snrval * snrval # SNR squared confluent = hyp1f1(-0.5, float(Nch), -0.5 * snrval_squared) # confluent hypergeometric function confluent_squared = confluent * confluent # squared confluent hypergeometric function Nch_minus_one = Nch - 1 # Number of channel reduced by one betaval = float(factorial2(2 * Nch - 1)) / float( (float(factorial(Nch - 1)) * float(2**Nch_minus_one)) ) # Factor beta in equation 18, Koay and Basser, JMR (2006), 179, 317-322 factorval = CONSTFACTOR * float(betaval) # One more scaling required factorval_squared = factorval * factorval # Square the factor corrfact = 2 * float( Nch ) + snrval_squared - factorval_squared * confluent_squared # Final correction factor return corrfact
def muthat_expansion(mu,sig,order): ''' Calculates the expansion for mu_{\hat{T}} based on mu_D and sigma_D. The expansion calculates the average of 1/X where X ~ N(mu_D,sigma_D^2): E[1/X] \approx 1/mu * sum_{k=0}^N (sigma/mu)**2k * (2k-1)!! Because 1/mu is lumped into Teq after the call to this function, it is not necessary to multiply the result of the for loop by 1//mu. Inputs: - mu, sig: expected value and standard deviation of X - order: order of the expansion ''' sigomu = sig/mu sigomu2 = sigomu**2 approx = 0 for k in range(order): approx += sigomu2**k * factorial2(2*k-1) return approx
def G_q2d(n, m): if n == 0: num = factorial2(2 * m - 1) den = 2**(m + 1) * factorial(m - 1) return num / den elif n > 0 and m == 1: t1num = (2 * n**2 - 1) * (n**2 - 1) t1den = 8 * (4 * n**2 - 1) term1 = -t1num / t1den term2 = 1 / 24 * kronecker(n, 1) return term1 + term2 # this is minus in the paper else: # nt1 = numerator term 1, d = denominator... nt1 = 2 * n * (m + n - 1) - m nt2 = (n + 1) * (2 * m + 2 * n - 1) num = nt1 * nt2 dt1 = (m + 2 * n - 2) * (m + 2 * n - 1) dt2 = (m + 2 * n) * (2 * n + 1) den = dt1 * dt2 term1 = num / den # there is a leading negative in the paper return term1 * gamma(n, m)
def _mom(self, k): return .5*special.factorial2(k-1)*(1+(-1)**k)