def test_sympyissue_6208(): assert sqrt(33**(9*I/10)) == -33**(9*I/20) assert root((6*I)**(2*I), 3).as_base_exp()[1] == Rational(1, 3) # != 2*I/3 assert root((6*I)**(I/3), 3).as_base_exp()[1] == I/9 assert sqrt(exp(3*I)) == exp(3*I/2) assert sqrt(-sqrt(3)*(1 + 2*I)) == sqrt(sqrt(3))*sqrt(-1 - 2*I) assert sqrt(exp(5*I)) == -exp(5*I/2) assert root(exp(5*I), 3).exp == Rational(1, 3)
def test_issue_6208(): from diofant import root, Rational I = S.ImaginaryUnit assert sqrt(33**(9 * I / 10)) == -33**(9 * I / 20) assert root((6 * I)**(2 * I), 3).as_base_exp()[1] == Rational(1, 3) # != 2*I/3 assert root((6 * I)**(I / 3), 3).as_base_exp()[1] == I / 9 assert sqrt(exp(3 * I)) == exp(3 * I / 2) assert sqrt(-sqrt(3) * (1 + 2 * I)) == sqrt(sqrt(3)) * sqrt(-1 - 2 * I) assert sqrt(exp(5 * I)) == -exp(5 * I / 2) assert root(exp(5 * I), 3).exp == Rational(1, 3)
def eval(cls, n, m, theta, phi): n, m, theta, phi = [sympify(x) for x in (n, m, theta, phi)] # Handle negative index m and arguments theta, phi if m.could_extract_minus_sign(): m = -m return S.NegativeOne**m * exp(-2*I*m*phi) * Ynm(n, m, theta, phi) if theta.could_extract_minus_sign(): theta = -theta return Ynm(n, m, theta, phi) if phi.could_extract_minus_sign(): phi = -phi return exp(-2*I*m*phi) * Ynm(n, m, theta, phi)
def eval(cls, nu, z): if z.is_zero: if nu.is_zero: return S.One elif (nu.is_integer and nu.is_zero is False) or re(nu).is_positive: return S.Zero elif re(nu).is_negative and not (nu.is_integer is True): return S.ComplexInfinity elif nu.is_imaginary: return S.NaN if im(z) is S.Infinity or im(z) is S.NegativeInfinity: return S.Zero if z.could_extract_minus_sign(): return (z)**nu * (-z)**(-nu) * besseli(nu, -z) if nu.is_integer: if nu.could_extract_minus_sign(): return besseli(-nu, z) newz = z.extract_multiplicatively(I) if newz: # NOTE we don't want to change the function if z==0 return I**(-nu) * besselj(nu, -newz) # branch handling: from diofant import unpolarify, exp if nu.is_integer: newz = unpolarify(z) if newz != z: return besseli(nu, newz) else: newz, n = z.extract_branch_factor() if n != 0: return exp(2 * n * pi * nu * I) * besseli(nu, newz) nnu = unpolarify(nu) if nu != nnu: return besseli(nnu, z)
def eval(cls, a, x): # For lack of a better place, we use this one to extract branching # information. The following can be # found in the literature (c/f references given above), albeit scattered: # 1) For fixed x != 0, lowergamma(s, x) is an entire function of s # 2) For fixed positive integers s, lowergamma(s, x) is an entire # function of x. # 3) For fixed non-positive integers s, # lowergamma(s, exp(I*2*pi*n)*x) = # 2*pi*I*n*(-1)**(-s)/factorial(-s) + lowergamma(s, x) # (this follows from lowergamma(s, x).diff(x) = x**(s-1)*exp(-x)). # 4) For fixed non-integral s, # lowergamma(s, x) = x**s*gamma(s)*lowergamma_unbranched(s, x), # where lowergamma_unbranched(s, x) is an entire function (in fact # of both s and x), i.e. # lowergamma(s, exp(2*I*pi*n)*x) = exp(2*pi*I*n*a)*lowergamma(a, x) from diofant import unpolarify, I nx, n = x.extract_branch_factor() if a.is_integer and a.is_positive: nx = unpolarify(x) if nx != x: return lowergamma(a, nx) elif a.is_integer and a.is_nonpositive: if n != 0: return 2 * pi * I * n * (-1)**( -a) / factorial(-a) + lowergamma(a, nx) elif n != 0: return exp(2 * pi * I * n * a) * lowergamma(a, nx) # Special values. if a.is_Number: # TODO this should be non-recursive if a is S.One: return S.One - exp(-x) elif a is S.Half: return sqrt(pi) * erf(sqrt(x)) elif a.is_Integer or (2 * a).is_Integer: b = a - 1 if b.is_positive: return b * cls(b, x) - x**b * exp(-x) if not a.is_Integer: return (cls(a + 1, x) + x**a * exp(-x)) / a
def fdiff(self, argindex=2): from diofant import meijerg, unpolarify if argindex == 2: a, z = self.args return -exp(-unpolarify(z)) * z**(a - 1) elif argindex == 1: a, z = self.args return uppergamma(a, z) * log(z) + meijerg([], [1, 1], [0, 0, a], [], z) else: raise ArgumentIndexError(self, argindex)
def fdiff(self, argindex=4): if argindex == 3: # Diff wrt theta n, m, theta, phi = self.args return (m * cot(theta) * Ynm(n, m, theta, phi) + sqrt((n - m)*(n + m + 1)) * exp(-I*phi) * Ynm(n, m + 1, theta, phi)) elif argindex == 4: # Diff wrt phi n, m, theta, phi = self.args return I * m * Ynm(n, m, theta, phi) else: # diff wrt n, m, etc raise ArgumentIndexError(self, argindex)
def eval(cls, a, z): from diofant import unpolarify, I, expint if z.is_Number: if z is S.Infinity: return S.Zero elif z is S.Zero: # TODO: Holds only for Re(a) > 0: return gamma(a) # We extract branching information here. C/f lowergamma. nx, n = z.extract_branch_factor() if a.is_integer and (a > 0) is S.true: nx = unpolarify(z) if z != nx: return uppergamma(a, nx) elif a.is_integer and (a <= 0) is S.true: if n != 0: return -2 * pi * I * n * (-1)**( -a) / factorial(-a) + uppergamma(a, nx) elif n != 0: return gamma(a) * (1 - exp(2 * pi * I * n * a)) + exp( 2 * pi * I * n * a) * uppergamma(a, nx) # Special values. if a.is_Number: # TODO this should be non-recursive if a is S.One: return exp(-z) elif a is S.Half: return sqrt(pi) * (1 - erf(sqrt(z))) # TODO could use erfc... elif a.is_Integer or (2 * a).is_Integer: b = a - 1 if b.is_positive: return b * cls(b, z) + z**b * exp(-z) elif b.is_Integer: return expint(-b, z) * unpolarify(z)**(b + 1) if not a.is_Integer: return (cls(a + 1, z) - z**a * exp(-z)) / a
def eval(cls, n, x): if not n.is_Number: # Symbolic result L_n(x) # L_{n}(-x) ---> exp(-x) * L_{-n-1}(x) # L_{-n}(x) ---> exp(x) * L_{n-1}(-x) if n.could_extract_minus_sign(): return exp(x) * laguerre(n - 1, -x) # We can evaluate for some special values of x if x == S.Zero: return S.One elif x == S.NegativeInfinity: return S.Infinity elif x == S.Infinity: return S.NegativeOne**n * S.Infinity else: # n is a given fixed integer, evaluate into polynomial if n.is_negative: raise ValueError( "The index n must be nonnegative integer (got %r)" % n) else: return cls._eval_at_order(n, x)
def _eval_rewrite_as_Sum(self, *args): from diofant.concrete.summations import Sum return exp(Sum(log(self.function), *self.limits))
def _eval_rewrite_as_tractable(self, z): return exp(loggamma(z))
def _eval_expand_func(self, **hints): n, m, theta, phi = self.args rv = (sqrt((2*n + 1)/(4*pi) * factorial(n - m)/factorial(n + m)) * exp(I*m*phi) * assoc_legendre(n, m, cos(theta))) # We can do this because of the range of theta return rv.subs(sqrt(-cos(theta)**2 + 1), sin(theta))
def _eval_rewrite_as_tractable(self, z): return exp(-Rational(2, 3) * z**Rational(3, 2)) * sqrt( pi * sqrt(z)) / 2 * _airyais(z)
def _eval_rewrite_as_besselj(self, nu, z): from diofant import polar_lift, exp return exp(-I * pi * nu / 2) * besselj(nu, polar_lift(I) * z)
def _eval_rewrite_as_intractable(self, x): return airybi(x) * exp(-Rational(2, 3) * x**Rational(3, 2)) / sqrt( S.Pi * sqrt(x))