def fdiff(self, argindex=4): if argindex == 1: # Diff wrt n raise ArgumentIndexError(self, argindex) elif argindex == 2: # Diff wrt a n, a, b, x = self.args k = C.Dummy("k") f1 = 1 / (a + b + n + k + 1) f2 = ((a + b + 2 * k + 1) * C.RisingFactorial(b + k + 1, n - k) / ((n - k) * C.RisingFactorial(a + b + k + 1, n - k))) return C.Sum(f1 * (jacobi(n, a, b, x) + f2 * jacobi(k, a, b, x)), (k, 0, n - 1)) elif argindex == 3: # Diff wrt b n, a, b, x = self.args k = C.Dummy("k") f1 = 1 / (a + b + n + k + 1) f2 = (-1)**(n - k) * ( (a + b + 2 * k + 1) * C.RisingFactorial(a + k + 1, n - k) / ((n - k) * C.RisingFactorial(a + b + k + 1, n - k))) return C.Sum(f1 * (jacobi(n, a, b, x) + f2 * jacobi(k, a, b, x)), (k, 0, n - 1)) elif argindex == 4: # Diff wrt x n, a, b, x = self.args return S.Half * (a + b + n + 1) * jacobi(n - 1, a + 1, b + 1, x) else: raise ArgumentIndexError(self, argindex)
def _eval_rewrite_as_polynomial(self, n, a, b, x): # TODO: Make sure n \in N k = C.Dummy("k") kern = (C.RisingFactorial(-n, k) * C.RisingFactorial(a + b + n + 1, k) * C.RisingFactorial(a + k + 1, n - k) / C.factorial(k) * ((1 - x) / 2)**k) return 1 / C.factorial(n) * C.Sum(kern, (k, 0, n))
def taylor_term(n, x, *previous_terms): if 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 = C.RisingFactorial(S.Half, k) F = C.factorial(k) return R / F * x**n / n
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: p = previous_terms[-2] return p * (n - 2)**2 / (k * (k - 1)) * x**2 else: k = (n - 1) // 2 R = C.RisingFactorial(S.Half, k) F = C.Factorial(k) return -R / F * S.ImaginaryUnit * x**n / n
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 (C.re(a) > S.Half) is True: return S.ComplexInfinity else: # No sec function available yet #return (C.cos(S.Pi*(a+n)) * C.sec(S.Pi*a) * C.gamma(2*a+n) / # (C.gamma(2*a) * C.gamma(n+1))) return None # 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 == S.Zero: return (2**n * sqrt(S.Pi) * C.gamma(a + S.Half * n) / (C.gamma( (1 - n) / 2) * C.gamma(n + 1) * C.gamma(a))) if x == S.One: return C.gamma(2 * a + n) / (C.gamma(2 * a) * C.gamma(n + 1)) elif x == S.Infinity: if n.is_positive: return C.RisingFactorial(a, n) * S.Infinity else: # n is a given fixed integer, evaluate into polynomial return gegenbauer_poly(n, a, x)
def eval(cls, n, a, b, x): # Simplify to other polynomials # P^{a, a}_n(x) if a == b: if a == -S.Half: return C.RisingFactorial( S.Half, n) / C.factorial(n) * chebyshevt(n, x) elif a == S.Zero: return legendre(n, x) elif a == S.Half: return C.RisingFactorial( 3 * S.Half, n) / C.factorial(n + 1) * chebyshevu(n, x) else: return C.RisingFactorial(a + 1, n) / C.RisingFactorial( 2 * a + 1, n) * gegenbauer(n, a + S.Half, x) elif b == -a: # P^{a, -a}_n(x) return C.gamma(n + a + 1) / C.gamma(n + 1) * (1 + x)**(a / 2) / ( 1 - x)**(a / 2) * assoc_legendre(n, -a, x) elif a == -b: # P^{-b, b}_n(x) return C.gamma(n - b + 1) / C.gamma(n + 1) * (1 - x)**(b / 2) / ( 1 + x)**(b / 2) * assoc_legendre(n, b, 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 == S.Zero: return (2**(-n) * C.gamma(a + n + 1) / (C.gamma(a + 1) * C.factorial(n)) * C.hyper([-b - n, -n], [a + 1], -1)) if x == S.One: return C.RisingFactorial(a + 1, n) / C.factorial(n) elif x == S.Infinity: if n.is_positive: # TODO: Make sure a+b+2*n \notin Z return C.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 _eval_rewrite_as_polynomial(self, n, a, x): k = C.Dummy("k") kern = ((-1)**k * C.RisingFactorial(a, n - k) * (2 * x)**(n - 2 * k) / (C.factorial(k) * C.factorial(n - 2 * k))) return C.Sum(kern, (k, 0, C.floor(n / 2)))
def _eval_rewrite_as_polynomial(self, n, x): # TODO: Should make sure n is in N_0 k = C.Dummy("k") kern = C.RisingFactorial( -n, k) / (C.gamma(k + alpha + 1) * C.factorial(k)) * x**k return C.gamma(n + alpha + 1) / C.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 = C.Dummy("k") kern = C.RisingFactorial(-n, k) / C.factorial(k)**2 * x**k return C.Sum(kern, (k, 0, n))