def taylor_term(n, x, *previous_terms): if n == 0: return S.Pi * S.ImaginaryUnit / 2 elif n < 0 or n % 2 == 0: return S.Zero else: x = sympify(x) if len(previous_terms) >= 2 and n > 2: p = previous_terms[-2] return p * (n - 2)**2 / (n * (n - 1)) * x**2 else: k = (n - 1) // 2 R = RisingFactorial(S.Half, k) F = factorial(k) return -R / F * S.ImaginaryUnit * x**n / n
def expansion_term(n, x, *previous_terms): if n == 0: return log(2 / x) elif n < 0 or n % 2 == 1: return S.Zero else: x = sympify(x) if len(previous_terms) > 2 and n > 2: p = previous_terms[-2] return p * (n - 1)**2 // (n // 2)**2 * x**2 / 4 else: k = n // 2 R = RisingFactorial(S.Half, k) * n F = factorial(k) * n // 2 * n // 2 return -1 * R / F * x**n / 4
def eval(cls, n, a, x): # For negative n the polynomials vanish # See http://functions.wolfram.com/Polynomials/GegenbauerC3/03/01/03/0012/ if n.is_negative: return S.Zero # Some special values for fixed a if a == S.Half: return legendre(n, x) elif a == S.One: return chebyshevu(n, x) elif a == S.NegativeOne: return S.Zero if not n.is_Number: # Handle this before the general sign extraction rule if x == S.NegativeOne: if (re(a) > S.Half) == True: return S.ComplexInfinity else: return ( cos(S.Pi * (a + n)) * sec(S.Pi * a) * gamma(2 * a + n) / (gamma(2 * a) * gamma(n + 1)) ) # Symbolic result C^a_n(x) # C^a_n(-x) ---> (-1)**n * C^a_n(x) if x.could_extract_minus_sign(): return S.NegativeOne ** n * gegenbauer(n, a, -x) # We can evaluate for some special values of x if x.is_zero: return ( 2 ** n * sqrt(S.Pi) * gamma(a + S.Half * n) / (gamma((1 - n) / 2) * gamma(n + 1) * gamma(a)) ) if x == S.One: return gamma(2 * a + n) / (gamma(2 * a) * gamma(n + 1)) elif x is S.Infinity: if n.is_positive: return RisingFactorial(a, n) * S.Infinity else: # n is a given fixed integer, evaluate into polynomial return gegenbauer_poly(n, a, x)
def check(self, f): # Levit, Irreducibility of Polynomials with Low Absolute Values, Theorem 2 n = f.degree() N = (n + 1) // 2 suitable = [] rhs = RisingFactorial((n//2)/2, N) / (2 ** (N-1)) for a in range(-20, 20 + 1): val = abs(f.eval(a)) if val == 0: # clearly this is reducible... return REDUCIBLE, None if val < rhs: suitable.append(a) if len(suitable) >= n: return IRREDUCIBLE, {'a': suitable} return UNKNOWN, None
def eval(cls, n, a, b, x): # Simplify to other polynomials # P^{a, a}_n(x) if a == b: if a == Rational(-1, 2): return RisingFactorial(S.Half, n) / factorial(n) * chebyshevt(n, x) elif a.is_zero: return legendre(n, x) elif a == S.Half: return ( RisingFactorial(3 * S.Half, n) / factorial(n + 1) * chebyshevu(n, x) ) else: return ( RisingFactorial(a + 1, n) / RisingFactorial(2 * a + 1, n) * gegenbauer(n, a + S.Half, x) ) elif b == -a: # P^{a, -a}_n(x) return ( gamma(n + a + 1) / gamma(n + 1) * (1 + x) ** (a / 2) / (1 - x) ** (a / 2) * assoc_legendre(n, -a, x) ) if not n.is_Number: # Symbolic result P^{a,b}_n(x) # P^{a,b}_n(-x) ---> (-1)**n * P^{b,a}_n(-x) if x.could_extract_minus_sign(): return S.NegativeOne ** n * jacobi(n, b, a, -x) # We can evaluate for some special values of x if x.is_zero: return ( 2 ** (-n) * gamma(a + n + 1) / (gamma(a + 1) * factorial(n)) * hyper([-b - n, -n], [a + 1], -1) ) if x == S.One: return RisingFactorial(a + 1, n) / factorial(n) elif x is S.Infinity: if n.is_positive: # Make sure a+b+2*n \notin Z if (a + b + 2 * n).is_integer: raise ValueError("Error. a + b + 2*n should not be an integer.") return RisingFactorial(a + b + n + 1, n) * S.Infinity else: # n is a given fixed integer, evaluate into polynomial return jacobi_poly(n, a, b, x)
def test_assoc_laguerre(): n = Symbol("n") m = Symbol("m") alpha = Symbol("alpha") # generalized Laguerre polynomials: assert assoc_laguerre(0, alpha, x) == 1 assert assoc_laguerre(1, alpha, x) == -x + alpha + 1 assert assoc_laguerre(2, alpha, x).expand() == \ (x**2/2 - (alpha + 2)*x + (alpha + 2)*(alpha + 1)/2).expand() assert assoc_laguerre(3, alpha, x).expand() == \ (-x**3/6 + (alpha + 3)*x**2/2 - (alpha + 2)*(alpha + 3)*x/2 + (alpha + 1)*(alpha + 2)*(alpha + 3)/6).expand() # Test the lowest 10 polynomials with laguerre_poly, to make sure it works: for i in range(10): assert assoc_laguerre(i, 0, x).expand() == laguerre_poly(i, x) X = assoc_laguerre(n, m, x) assert isinstance(X, assoc_laguerre) assert assoc_laguerre(n, 0, x) == laguerre(n, x) assert assoc_laguerre(n, alpha, 0) == binomial(alpha + n, alpha) p = Symbol("p", positive=True) assert assoc_laguerre(p, alpha, oo) == (-1)**p * oo assert assoc_laguerre(p, alpha, -oo) is oo assert diff(assoc_laguerre(n, alpha, x), x) == \ -assoc_laguerre(n - 1, alpha + 1, x) _k = Dummy('k') assert diff(assoc_laguerre(n, alpha, x), alpha).dummy_eq( Sum(assoc_laguerre(_k, alpha, x) / (-alpha + n), (_k, 0, n - 1))) assert conjugate(assoc_laguerre(n, alpha, x)) == \ assoc_laguerre(n, conjugate(alpha), conjugate(x)) assert assoc_laguerre(n, alpha, x).rewrite('polynomial').dummy_eq( gamma(alpha + n + 1) * Sum( x**_k * RisingFactorial(-n, _k) / (factorial(_k) * gamma(_k + alpha + 1)), (_k, 0, n)) / factorial(n)) raises(ValueError, lambda: assoc_laguerre(-2.1, alpha, x)) raises(ArgumentIndexError, lambda: assoc_laguerre(n, alpha, x).fdiff(1)) raises(ArgumentIndexError, lambda: assoc_laguerre(n, alpha, x).fdiff(4))
def _eval_expand_func(self, **hints): arg = self.args[0] if arg.is_Rational: if abs(arg.p) > arg.q: x = Dummy('x') n = arg.p // arg.q p = arg.p - n*arg.q return gamma(x + n)._eval_expand_func().subs(x, Rational(p, arg.q)) if arg.is_Add: coeff, tail = arg.as_coeff_add() if coeff and coeff.q != 1: intpart = floor(coeff) tail = (coeff - intpart,) + tail coeff = intpart tail = arg._new_rawargs(*tail, reeval=False) return gamma(tail)*RisingFactorial(tail, coeff) return self.func(*self.args)
def test_guess(): i0, i1 = symbols('i0 i1') assert guess([1, 2, 6, 24, 120], evaluate=False) == [Product(i1 + 1, (i1, 1, i0 - 1))] assert guess([1, 2, 6, 24, 120]) == [RisingFactorial(2, i0 - 1)] assert guess([1, 2, 7, 42, 429, 7436, 218348, 10850216], niter=4) == [ 2**(i0 - 1) * (Rational(27, 16))**(i0**2 / 2 - 3 * i0 / 2 + 1) * Product( RisingFactorial(Rational(5, 3), i1 - 1) * RisingFactorial(Rational(7, 3), i1 - 1) / (RisingFactorial(Rational(3, 2), i1 - 1) * RisingFactorial(Rational(5, 2), i1 - 1)), (i1, 1, i0 - 1)) ] assert guess([1, 0, 2]) == [] x, y = symbols('x y') assert guess([1, 2, 6, 24, 120], variables=[x, y]) == [RisingFactorial(2, x - 1)]
def _eval_rewrite_as_polynomial(self, n, a, x): from sympy import Sum k = Dummy("k") kern = ((-1)**k * RisingFactorial(a, n - k) * (2 * x)**(n - 2 * k) / (factorial(k) * factorial(n - 2 * k))) return Sum(kern, (k, 0, floor(n / 2)))
def test_sympy__functions__combinatorial__factorials__RisingFactorial(): from sympy.functions.combinatorial.factorials import RisingFactorial assert _test_args(RisingFactorial(2, x))
def test_jacobi(): n = Symbol("n") a = Symbol("a") b = Symbol("b") assert jacobi(0, a, b, x) == 1 assert jacobi(1, a, b, x) == a / 2 - b / 2 + x * (a / 2 + b / 2 + 1) assert jacobi(n, a, a, x) == RisingFactorial(a + 1, n) * gegenbauer( n, a + S.Half, x) / RisingFactorial(2 * a + 1, n) assert jacobi(n, a, -a, x) == ((-1)**a * (-x + 1)**(-a / 2) * (x + 1)**(a / 2) * assoc_legendre(n, a, x) * factorial(-a + n) * gamma(a + n + 1) / (factorial(a + n) * gamma(n + 1))) assert jacobi(n, -b, b, x) == ((-x + 1)**(b / 2) * (x + 1)**(-b / 2) * assoc_legendre(n, b, x) * gamma(-b + n + 1) / gamma(n + 1)) assert jacobi(n, 0, 0, x) == legendre(n, x) assert jacobi(n, S.Half, S.Half, x) == RisingFactorial(Rational( 3, 2), n) * chebyshevu(n, x) / factorial(n + 1) assert jacobi( n, Rational(-1, 2), Rational(-1, 2), x) == RisingFactorial(S.Half, n) * chebyshevt(n, x) / factorial(n) X = jacobi(n, a, b, x) assert isinstance(X, jacobi) assert jacobi(n, a, b, -x) == (-1)**n * jacobi(n, b, a, x) assert jacobi(n, a, b, 0) == 2**(-n) * gamma(a + n + 1) * hyper( (-b - n, -n), (a + 1, ), -1) / (factorial(n) * gamma(a + 1)) assert jacobi(n, a, b, 1) == RisingFactorial(a + 1, n) / factorial(n) m = Symbol("m", positive=True) assert jacobi(m, a, b, oo) == oo * RisingFactorial(a + b + m + 1, m) assert unchanged(jacobi, n, a, b, oo) assert conjugate(jacobi(m, a, b, x)) == \ jacobi(m, conjugate(a), conjugate(b), conjugate(x)) _k = Dummy('k') assert diff(jacobi(n, a, b, x), n) == Derivative(jacobi(n, a, b, x), n) assert diff(jacobi(n, a, b, x), a).dummy_eq( Sum((jacobi(n, a, b, x) + (2 * _k + a + b + 1) * RisingFactorial(_k + b + 1, -_k + n) * jacobi(_k, a, b, x) / ((-_k + n) * RisingFactorial(_k + a + b + 1, -_k + n))) / (_k + a + b + n + 1), (_k, 0, n - 1))) assert diff(jacobi(n, a, b, x), b).dummy_eq( Sum(((-1)**(-_k + n) * (2 * _k + a + b + 1) * RisingFactorial(_k + a + 1, -_k + n) * jacobi(_k, a, b, x) / ((-_k + n) * RisingFactorial(_k + a + b + 1, -_k + n)) + jacobi(n, a, b, x)) / (_k + a + b + n + 1), (_k, 0, n - 1))) assert diff(jacobi(n, a, b, x), x) == \ (a/2 + b/2 + n/2 + S.Half)*jacobi(n - 1, a + 1, b + 1, x) assert jacobi_normalized(n, a, b, x) == \ (jacobi(n, a, b, x)/sqrt(2**(a + b + 1)*gamma(a + n + 1)*gamma(b + n + 1) /((a + b + 2*n + 1)*factorial(n)*gamma(a + b + n + 1)))) raises(ValueError, lambda: jacobi(-2.1, a, b, x)) raises(ValueError, lambda: jacobi(Dummy(positive=True, integer=True), 1, 2, oo)) assert jacobi(n, a, b, x).rewrite("polynomial").dummy_eq( Sum((S.Half - x / 2)**_k * RisingFactorial(-n, _k) * RisingFactorial(_k + a + 1, -_k + n) * RisingFactorial(a + b + n + 1, _k) / factorial(_k), (_k, 0, n)) / factorial(n)) raises(ArgumentIndexError, lambda: jacobi(n, a, b, x).fdiff(5))
def _eval_rewrite_as_polynomial(self, n, a, b, x): # TODO: Make sure n \in N k = Dummy("k") kern = (RisingFactorial(-n, k) * RisingFactorial(a + b + n + 1, k) * RisingFactorial(a + k + 1, n - k) / factorial(k) * ((1 - x)/2)**k) return 1 / factorial(n) * C.Sum(kern, (k, 0, n))
def _eval_rewrite_as_polynomial(self, n, x): # TODO: Should make sure n is in N_0 k = Dummy("k") kern = RisingFactorial( -n, k) / (gamma(k + alpha + 1) * factorial(k)) * x**k return gamma(n + alpha + 1) / factorial(n) * C.Sum(kern, (k, 0, n))
def _eval_rewrite_as_polynomial(self, n, x): # TODO: Should make sure n is in N_0 k = Dummy("k") kern = RisingFactorial(-n, k) / factorial(k)**2 * x**k return C.Sum(kern, (k, 0, n))
def _eval_product(self, term, limits): (k, a, n) = limits if k not in term.free_symbols: if (term - 1).is_zero: return S.One return term**(n - a + 1) if a == n: return term.subs(k, a) from .delta import deltaproduct, _has_simple_delta if term.has(KroneckerDelta) and _has_simple_delta(term, limits[0]): return deltaproduct(term, limits) dif = n - a definite = dif.is_Integer if definite and (dif < 100): return self._eval_product_direct(term, limits) elif term.is_polynomial(k): poly = term.as_poly(k) A = B = Q = S.One all_roots = roots(poly) M = 0 for r, m in all_roots.items(): M += m A *= RisingFactorial(a - r, n - a + 1)**m Q *= (n - r)**m if M < poly.degree(): arg = quo(poly, Q.as_poly(k)) B = self.func(arg, (k, a, n)).doit() return poly.LC()**(n - a + 1) * A * B elif term.is_Add: factored = factor_terms(term, fraction=True) if factored.is_Mul: return self._eval_product(factored, (k, a, n)) elif term.is_Mul: # Factor in part without the summation variable and part with without_k, with_k = term.as_coeff_mul(k) if len(with_k) >= 2: # More than one term including k, so still a multiplication exclude, include = [], [] for t in with_k: p = self._eval_product(t, (k, a, n)) if p is not None: exclude.append(p) else: include.append(t) if not exclude: return None else: arg = term._new_rawargs(*include) A = Mul(*exclude) B = self.func(arg, (k, a, n)).doit() return without_k**(n - a + 1) * A * B else: # Just a single term p = self._eval_product(with_k[0], (k, a, n)) if p is None: p = self.func(with_k[0], (k, a, n)).doit() return without_k**(n - a + 1) * p elif term.is_Pow: if not term.base.has(k): s = summation(term.exp, (k, a, n)) return term.base**s elif not term.exp.has(k): p = self._eval_product(term.base, (k, a, n)) if p is not None: return p**term.exp elif isinstance(term, Product): evaluated = term.doit() f = self._eval_product(evaluated, limits) if f is None: return self.func(evaluated, limits) else: return f if definite: return self._eval_product_direct(term, limits)
def test_issue_6878(): n = symbols('n', integer=True) assert combsimp(RisingFactorial( -10, n)) == 3628800 * (-1)**n / factorial(10 - n)