def test_issue_22606(): fx = Function('f')(x) eq = x + gamma(y) # seems like ans should be `eq`, not `(x*y + gamma(y + 1))/y` ans = gammasimp(eq) assert gammasimp(eq.subs(x, fx)).subs(fx, x) == ans assert gammasimp(eq.subs(x, cos(x))).subs(cos(x), x) == ans assert 1 / gammasimp(1 / eq) == ans assert gammasimp(fx.subs(x, eq)).args[0] == ans
def test_lerchphi(): from sympy.functions.special.zeta_functions import (lerchphi, polylog) from sympy.simplify.gammasimp import gammasimp assert hyperexpand(hyper([1, a], [a + 1], z)/a) == lerchphi(z, 1, a) assert hyperexpand( hyper([1, a, a], [a + 1, a + 1], z)/a**2) == lerchphi(z, 2, a) assert hyperexpand(hyper([1, a, a, a], [a + 1, a + 1, a + 1], z)/a**3) == \ lerchphi(z, 3, a) assert hyperexpand(hyper([1] + [a]*10, [a + 1]*10, z)/a**10) == \ lerchphi(z, 10, a) assert gammasimp(hyperexpand(meijerg([0, 1 - a], [], [0], [-a], exp_polar(-I*pi)*z))) == lerchphi(z, 1, a) assert gammasimp(hyperexpand(meijerg([0, 1 - a, 1 - a], [], [0], [-a, -a], exp_polar(-I*pi)*z))) == lerchphi(z, 2, a) assert gammasimp(hyperexpand(meijerg([0, 1 - a, 1 - a, 1 - a], [], [0], [-a, -a, -a], exp_polar(-I*pi)*z))) == lerchphi(z, 3, a) assert hyperexpand(z*hyper([1, 1], [2], z)) == -log(1 + -z) assert hyperexpand(z*hyper([1, 1, 1], [2, 2], z)) == polylog(2, z) assert hyperexpand(z*hyper([1, 1, 1, 1], [2, 2, 2], z)) == polylog(3, z) assert hyperexpand(hyper([1, a, 1 + S.Half], [a + 1, S.Half], z)) == \ -2*a/(z - 1) + (-2*a**2 + a)*lerchphi(z, 1, a) # Now numerical tests. These make sure reductions etc are carried out # correctly # a rational function (polylog at negative integer order) assert can_do([2, 2, 2], [1, 1]) # NOTE these contain log(1-x) etc ... better make sure we have |z| < 1 # reduction of order for polylog assert can_do([1, 1, 1, b + 5], [2, 2, b], div=10) # reduction of order for lerchphi # XXX lerchphi in mpmath is flaky assert can_do( [1, a, a, a, b + 5], [a + 1, a + 1, a + 1, b], numerical=False) # test a bug from sympy.functions.elementary.complexes import Abs assert hyperexpand(hyper([S.Half, S.Half, S.Half, 1], [Rational(3, 2), Rational(3, 2), Rational(3, 2)], Rational(1, 4))) == \ Abs(-polylog(3, exp_polar(I*pi)/2) + polylog(3, S.Half))
def combsimp(expr): r""" Simplify combinatorial expressions. Explanation =========== This function takes as input an expression containing factorials, binomials, Pochhammer symbol and other "combinatorial" functions, and tries to minimize the number of those functions and reduce the size of their arguments. The algorithm works by rewriting all combinatorial functions as gamma functions and applying gammasimp() except simplification steps that may make an integer argument non-integer. See docstring of gammasimp for more information. Then it rewrites expression in terms of factorials and binomials by rewriting gammas as factorials and converting (a+b)!/a!b! into binomials. If expression has gamma functions or combinatorial functions with non-integer argument, it is automatically passed to gammasimp. Examples ======== >>> from sympy.simplify import combsimp >>> from sympy import factorial, binomial, symbols >>> n, k = symbols('n k', integer = True) >>> combsimp(factorial(n)/factorial(n - 3)) n*(n - 2)*(n - 1) >>> combsimp(binomial(n+1, k+1)/binomial(n, k)) (n + 1)/(k + 1) """ expr = expr.rewrite(gamma, piecewise=False) if any( isinstance(node, gamma) and not node.args[0].is_integer for node in preorder_traversal(expr)): return gammasimp(expr) expr = _gammasimp(expr, as_comb=True) expr = _gamma_as_comb(expr) return expr
def combsimp(expr): r""" Simplify combinatorial expressions. This function takes as input an expression containing factorials, binomials, Pochhammer symbol and other "combinatorial" functions, and tries to minimize the number of those functions and reduce the size of their arguments. The algorithm works by rewriting all combinatorial functions as gamma functions and applying gammasimp() except simplification steps that may make an integer argument non-integer. See docstring of gammasimp for more information. Then it rewrites expression in terms of factorials and binomials by rewriting gammas as factorials and converting (a+b)!/a!b! into binomials. If expression has gamma functions or combinatorial functions with non-integer argument, it is automatically passed to gammasimp. Examples ======== >>> from sympy.simplify import combsimp >>> from sympy import factorial, binomial, symbols >>> n, k = symbols('n k', integer = True) >>> combsimp(factorial(n)/factorial(n - 3)) n*(n - 2)*(n - 1) >>> combsimp(binomial(n+1, k+1)/binomial(n, k)) (n + 1)/(k + 1) """ expr = expr.rewrite(gamma) if any(isinstance(node, gamma) and not node.args[0].is_integer for node in preorder_traversal(expr)): return gammasimp(expr); expr = _gammasimp(expr, as_comb = True) expr = _gamma_as_comb(expr) return expr
def test_probability(): # various integrals from probability theory from sympy.core.function import expand_mul from sympy.core.symbol import (Symbol, symbols) from sympy.functions.elementary.complexes import Abs from sympy.simplify.gammasimp import gammasimp from sympy.simplify.powsimp import powsimp mu1, mu2 = symbols('mu1 mu2', nonzero=True) sigma1, sigma2 = symbols('sigma1 sigma2', positive=True) rate = Symbol('lambda', positive=True) def normal(x, mu, sigma): return 1 / sqrt(2 * pi * sigma**2) * exp(-(x - mu)**2 / 2 / sigma**2) def exponential(x, rate): return rate * exp(-rate * x) assert integrate(normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) == 1 assert integrate(x*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) == \ mu1 assert integrate(x**2*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) \ == mu1**2 + sigma1**2 assert integrate(x**3*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) \ == mu1**3 + 3*mu1*sigma1**2 assert integrate(normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == 1 assert integrate(x * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu1 assert integrate(y * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu2 assert integrate(x * y * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu1 * mu2 assert integrate( (x + y + 1) * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == 1 + mu1 + mu2 assert integrate((x + y - 1)*normal(x, mu1, sigma1)*normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == \ -1 + mu1 + mu2 i = integrate(x**2 * normal(x, mu1, sigma1) * normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) assert not i.has(Abs) assert simplify(i) == mu1**2 + sigma1**2 assert integrate(y**2*normal(x, mu1, sigma1)*normal(y, mu2, sigma2), (x, -oo, oo), (y, -oo, oo), meijerg=True) == \ sigma2**2 + mu2**2 assert integrate(exponential(x, rate), (x, 0, oo), meijerg=True) == 1 assert integrate(x*exponential(x, rate), (x, 0, oo), meijerg=True) == \ 1/rate assert integrate(x**2*exponential(x, rate), (x, 0, oo), meijerg=True) == \ 2/rate**2 def E(expr): res1 = integrate(expr * exponential(x, rate) * normal(y, mu1, sigma1), (x, 0, oo), (y, -oo, oo), meijerg=True) res2 = integrate(expr * exponential(x, rate) * normal(y, mu1, sigma1), (y, -oo, oo), (x, 0, oo), meijerg=True) assert expand_mul(res1) == expand_mul(res2) return res1 assert E(1) == 1 assert E(x * y) == mu1 / rate assert E(x * y**2) == mu1**2 / rate + sigma1**2 / rate ans = sigma1**2 + 1 / rate**2 assert simplify(E((x + y + 1)**2) - E(x + y + 1)**2) == ans assert simplify(E((x + y - 1)**2) - E(x + y - 1)**2) == ans assert simplify(E((x + y)**2) - E(x + y)**2) == ans # Beta' distribution alpha, beta = symbols('alpha beta', positive=True) betadist = x**(alpha - 1)*(1 + x)**(-alpha - beta)*gamma(alpha + beta) \ /gamma(alpha)/gamma(beta) assert integrate(betadist, (x, 0, oo), meijerg=True) == 1 i = integrate(x * betadist, (x, 0, oo), meijerg=True, conds='separate') assert (gammasimp(i[0]), i[1]) == (alpha / (beta - 1), 1 < beta) j = integrate(x**2 * betadist, (x, 0, oo), meijerg=True, conds='separate') assert j[1] == (beta > 2) assert gammasimp(j[0] - i[0]**2) == (alpha + beta - 1)*alpha \ /(beta - 2)/(beta - 1)**2 # Beta distribution # NOTE: this is evaluated using antiderivatives. It also tests that # meijerint_indefinite returns the simplest possible answer. a, b = symbols('a b', positive=True) betadist = x**(a - 1) * (-x + 1)**(b - 1) * gamma(a + b) / (gamma(a) * gamma(b)) assert simplify(integrate(betadist, (x, 0, 1), meijerg=True)) == 1 assert simplify(integrate(x*betadist, (x, 0, 1), meijerg=True)) == \ a/(a + b) assert simplify(integrate(x**2*betadist, (x, 0, 1), meijerg=True)) == \ a*(a + 1)/(a + b)/(a + b + 1) assert simplify(integrate(x**y*betadist, (x, 0, 1), meijerg=True)) == \ gamma(a + b)*gamma(a + y)/gamma(a)/gamma(a + b + y) # Chi distribution k = Symbol('k', integer=True, positive=True) chi = 2**(1 - k / 2) * x**(k - 1) * exp(-x**2 / 2) / gamma(k / 2) assert powsimp(integrate(chi, (x, 0, oo), meijerg=True)) == 1 assert simplify(integrate(x*chi, (x, 0, oo), meijerg=True)) == \ sqrt(2)*gamma((k + 1)/2)/gamma(k/2) assert simplify(integrate(x**2 * chi, (x, 0, oo), meijerg=True)) == k # Chi^2 distribution chisquared = 2**(-k / 2) / gamma(k / 2) * x**(k / 2 - 1) * exp(-x / 2) assert powsimp(integrate(chisquared, (x, 0, oo), meijerg=True)) == 1 assert simplify(integrate(x * chisquared, (x, 0, oo), meijerg=True)) == k assert simplify(integrate(x**2*chisquared, (x, 0, oo), meijerg=True)) == \ k*(k + 2) assert gammasimp( integrate(((x - k) / sqrt(2 * k))**3 * chisquared, (x, 0, oo), meijerg=True)) == 2 * sqrt(2) / sqrt(k) # Dagum distribution a, b, p = symbols('a b p', positive=True) # XXX (x/b)**a does not work dagum = a * p / x * (x / b)**(a * p) / (1 + x**a / b**a)**(p + 1) assert simplify(integrate(dagum, (x, 0, oo), meijerg=True)) == 1 # XXX conditions are a mess arg = x * dagum assert simplify(integrate( arg, (x, 0, oo), meijerg=True, conds='none')) == a * b * gamma(1 - 1 / a) * gamma(p + 1 + 1 / a) / ( (a * p + 1) * gamma(p)) assert simplify(integrate( x * arg, (x, 0, oo), meijerg=True, conds='none')) == a * b**2 * gamma(1 - 2 / a) * gamma(p + 1 + 2 / a) / ( (a * p + 2) * gamma(p)) # F-distribution d1, d2 = symbols('d1 d2', positive=True) f = sqrt(((d1*x)**d1 * d2**d2)/(d1*x + d2)**(d1 + d2))/x \ /gamma(d1/2)/gamma(d2/2)*gamma((d1 + d2)/2) assert simplify(integrate(f, (x, 0, oo), meijerg=True)) == 1 # TODO conditions are a mess assert simplify(integrate(x * f, (x, 0, oo), meijerg=True, conds='none')) == d2 / (d2 - 2) assert simplify( integrate(x**2 * f, (x, 0, oo), meijerg=True, conds='none')) == d2**2 * (d1 + 2) / d1 / (d2 - 4) / (d2 - 2) # TODO gamma, rayleigh # inverse gaussian lamda, mu = symbols('lamda mu', positive=True) dist = sqrt(lamda / 2 / pi) * x**(Rational(-3, 2)) * exp( -lamda * (x - mu)**2 / x / 2 / mu**2) mysimp = lambda expr: simplify(expr.rewrite(exp)) assert mysimp(integrate(dist, (x, 0, oo))) == 1 assert mysimp(integrate(x * dist, (x, 0, oo))) == mu assert mysimp(integrate((x - mu)**2 * dist, (x, 0, oo))) == mu**3 / lamda assert mysimp(integrate((x - mu)**3 * dist, (x, 0, oo))) == 3 * mu**5 / lamda**2 # Levi c = Symbol('c', positive=True) assert integrate( sqrt(c / 2 / pi) * exp(-c / 2 / (x - mu)) / (x - mu)**S('3/2'), (x, mu, oo)) == 1 # higher moments oo # log-logistic alpha, beta = symbols('alpha beta', positive=True) distn = (beta/alpha)*x**(beta - 1)/alpha**(beta - 1)/ \ (1 + x**beta/alpha**beta)**2 # FIXME: If alpha, beta are not declared as finite the line below hangs # after the changes in: # https://github.com/sympy/sympy/pull/16603 assert simplify(integrate(distn, (x, 0, oo))) == 1 # NOTE the conditions are a mess, but correctly state beta > 1 assert simplify(integrate(x*distn, (x, 0, oo), conds='none')) == \ pi*alpha/beta/sin(pi/beta) # (similar comment for conditions applies) assert simplify(integrate(x**y*distn, (x, 0, oo), conds='none')) == \ pi*alpha**y*y/beta/sin(pi*y/beta) # weibull k = Symbol('k', positive=True) n = Symbol('n', positive=True) distn = k / lamda * (x / lamda)**(k - 1) * exp(-(x / lamda)**k) assert simplify(integrate(distn, (x, 0, oo))) == 1 assert simplify(integrate(x**n*distn, (x, 0, oo))) == \ lamda**n*gamma(1 + n/k) # rice distribution from sympy.functions.special.bessel import besseli nu, sigma = symbols('nu sigma', positive=True) rice = x / sigma**2 * exp(-(x**2 + nu**2) / 2 / sigma**2) * besseli( 0, x * nu / sigma**2) assert integrate(rice, (x, 0, oo), meijerg=True) == 1 # can someone verify higher moments? # Laplace distribution mu = Symbol('mu', real=True) b = Symbol('b', positive=True) laplace = exp(-abs(x - mu) / b) / 2 / b assert integrate(laplace, (x, -oo, oo), meijerg=True) == 1 assert integrate(x * laplace, (x, -oo, oo), meijerg=True) == mu assert integrate(x**2*laplace, (x, -oo, oo), meijerg=True) == \ 2*b**2 + mu**2 # TODO are there other distributions supported on (-oo, oo) that we can do? # misc tests k = Symbol('k', positive=True) assert gammasimp( expand_mul( integrate(log(x) * x**(k - 1) * exp(-x) / gamma(k), (x, 0, oo)))) == polygamma(0, k)
def test_gammasimp(): R = Rational # was part of test_combsimp_gamma() in test_combsimp.py assert gammasimp(gamma(x)) == gamma(x) assert gammasimp(gamma(x + 1) / x) == gamma(x) assert gammasimp(gamma(x) / (x - 1)) == gamma(x - 1) assert gammasimp(x * gamma(x)) == gamma(x + 1) assert gammasimp((x + 1) * gamma(x + 1)) == gamma(x + 2) assert gammasimp(gamma(x + y) * (x + y)) == gamma(x + y + 1) assert gammasimp(x / gamma(x + 1)) == 1 / gamma(x) assert gammasimp((x + 1)**2 / gamma(x + 2)) == (x + 1) / gamma(x + 1) assert gammasimp(x*gamma(x) + gamma(x + 3)/(x + 2)) == \ (x + 2)*gamma(x + 1) assert gammasimp(gamma(2 * x) * x) == gamma(2 * x + 1) / 2 assert gammasimp(gamma(2 * x) / (x - S.Half)) == 2 * gamma(2 * x - 1) assert gammasimp(gamma(x) * gamma(1 - x)) == pi / sin(pi * x) assert gammasimp(gamma(x) * gamma(-x)) == -pi / (x * sin(pi * x)) assert gammasimp(1/gamma(x + 3)/gamma(1 - x)) == \ sin(pi*x)/(pi*x*(x + 1)*(x + 2)) assert gammasimp(factorial(n + 2)) == gamma(n + 3) assert gammasimp(binomial(n, k)) == \ gamma(n + 1)/(gamma(k + 1)*gamma(-k + n + 1)) assert powsimp(gammasimp( gamma(x)*gamma(x + S.Half)*gamma(y)/gamma(x + y))) == \ 2**(-2*x + 1)*sqrt(pi)*gamma(2*x)*gamma(y)/gamma(x + y) assert gammasimp(1/gamma(x)/gamma(x - Rational(1, 3))/gamma(x + Rational(1, 3))) == \ 3**(3*x - Rational(3, 2))/(2*pi*gamma(3*x - 1)) assert simplify( gamma(S.Half + x / 2) * gamma(1 + x / 2) / gamma(1 + x) / sqrt(pi) * 2**x) == 1 assert gammasimp(gamma(Rational(-1, 4)) * gamma(Rational(-3, 4))) == 16 * sqrt(2) * pi / 3 assert powsimp(gammasimp(gamma(2*x)/gamma(x))) == \ 2**(2*x - 1)*gamma(x + S.Half)/sqrt(pi) # issue 6792 e = (-gamma(k) * gamma(k + 2) + gamma(k + 1)**2) / gamma(k)**2 assert gammasimp(e) == -k assert gammasimp(1 / e) == -1 / k e = (gamma(x) + gamma(x + 1)) / gamma(x) assert gammasimp(e) == x + 1 assert gammasimp(1 / e) == 1 / (x + 1) e = (gamma(x) + gamma(x + 2)) * (gamma(x - 1) + gamma(x)) / gamma(x) assert gammasimp(e) == (x**2 + x + 1) * gamma(x + 1) / (x - 1) e = (-gamma(k) * gamma(k + 2) + gamma(k + 1)**2) / gamma(k)**2 assert gammasimp(e**2) == k**2 assert gammasimp(e**2 / gamma(k + 1)) == k / gamma(k) a = R(1, 2) + R(1, 3) b = a + R(1, 3) assert gammasimp(gamma(2 * k) / gamma(k) * gamma(k + a) * gamma(k + b)) == 3 * 2**(2 * k + 1) * 3**( -3 * k - 2) * sqrt(pi) * gamma(3 * k + R(3, 2)) / 2 # issue 9699 assert gammasimp( (x + 1) * factorial(x) / gamma(y)) == gamma(x + 2) / gamma(y) assert gammasimp(rf(x + n, k) * binomial(n, k)).simplify() == Piecewise( (gamma(n + 1) * gamma(k + n + x) / (gamma(k + 1) * gamma(n + x) * gamma(-k + n + 1)), n > -x), ((-1)**k * gamma(n + 1) * gamma(-n - x + 1) / (gamma(k + 1) * gamma(-k + n + 1) * gamma(-k - n - x + 1)), True)) A, B = symbols('A B', commutative=False) assert gammasimp(e * B * A) == gammasimp(e) * B * A # check iteration assert gammasimp(gamma(2 * k) / gamma(k) * gamma(-k - R(1, 2))) == (-2**(2 * k + 1) * sqrt(pi) / (2 * ((2 * k + 1) * cos(pi * k)))) assert gammasimp( gamma(k) * gamma(k + R(1, 3)) * gamma(k + R(2, 3)) / gamma(k * R(3, 2))) == (3 * 2**(3 * k + 1) * 3**(-3 * k - S.Half) * sqrt(pi) * gamma(k * R(3, 2) + S.Half) / 2) # issue 6153 assert gammasimp(gamma(Rational(1, 4)) / gamma(Rational(5, 4))) == 4 # was part of test_combsimp() in test_combsimp.py assert gammasimp(binomial(n + 2, k + S.Half)) == gamma(n + 3)/ \ (gamma(k + R(3, 2))*gamma(-k + n + R(5, 2))) assert gammasimp(binomial(n + 2, k + 2.0)) == \ gamma(n + 3)/(gamma(k + 3.0)*gamma(-k + n + 1)) # issue 11548 assert gammasimp(binomial(0, x)) == sin(pi * x) / (pi * x) e = gamma(n + Rational(1, 3)) * gamma(n + R(2, 3)) assert gammasimp(e) == e assert gammasimp(gamma(4*n + S.Half)/gamma(2*n - R(3, 4))) == \ 2**(4*n - R(5, 2))*(8*n - 3)*gamma(2*n + R(3, 4))/sqrt(pi) i, m = symbols('i m', integer=True) e = gamma(exp(i)) assert gammasimp(e) == e e = gamma(m + 3) assert gammasimp(e) == e e = gamma(m + 1) / (gamma(i + 1) * gamma(-i + m + 1)) assert gammasimp(e) == e p = symbols("p", integer=True, positive=True) assert gammasimp(gamma(-p + 4)) == gamma(-p + 4)
def test_meijerg_expand(): from sympy.simplify.gammasimp import gammasimp from sympy.simplify.simplify import simplify # from mpmath docs assert hyperexpand(meijerg([[], []], [[0], []], -z)) == exp(z) assert hyperexpand(meijerg([[1, 1], []], [[1], [0]], z)) == \ log(z + 1) assert hyperexpand(meijerg([[1, 1], []], [[1], [1]], z)) == \ z/(z + 1) assert hyperexpand(meijerg([[], []], [[S.Half], [0]], (z/2)**2)) \ == sin(z)/sqrt(pi) assert hyperexpand(meijerg([[], []], [[0], [S.Half]], (z/2)**2)) \ == cos(z)/sqrt(pi) assert can_do_meijer([], [a], [a - 1, a - S.Half], []) assert can_do_meijer([], [], [a/2], [-a/2], False) # branches... assert can_do_meijer([a], [b], [a], [b, a - 1]) # wikipedia assert hyperexpand(meijerg([1], [], [], [0], z)) == \ Piecewise((0, abs(z) < 1), (1, abs(1/z) < 1), (meijerg([1], [], [], [0], z), True)) assert hyperexpand(meijerg([], [1], [0], [], z)) == \ Piecewise((1, abs(z) < 1), (0, abs(1/z) < 1), (meijerg([], [1], [0], [], z), True)) # The Special Functions and their Approximations assert can_do_meijer([], [], [a + b/2], [a, a - b/2, a + S.Half]) assert can_do_meijer( [], [], [a], [b], False) # branches only agree for small z assert can_do_meijer([], [S.Half], [a], [-a]) assert can_do_meijer([], [], [a, b], []) assert can_do_meijer([], [], [a, b], []) assert can_do_meijer([], [], [a, a + S.Half], [b, b + S.Half]) assert can_do_meijer([], [], [a, -a], [0, S.Half], False) # dito assert can_do_meijer([], [], [a, a + S.Half, b, b + S.Half], []) assert can_do_meijer([S.Half], [], [0], [a, -a]) assert can_do_meijer([S.Half], [], [a], [0, -a], False) # dito assert can_do_meijer([], [a - S.Half], [a, b], [a - S.Half], False) assert can_do_meijer([], [a + S.Half], [a + b, a - b, a], [], False) assert can_do_meijer([a + S.Half], [], [b, 2*a - b, a], [], False) # This for example is actually zero. assert can_do_meijer([], [], [], [a, b]) # Testing a bug: assert hyperexpand(meijerg([0, 2], [], [], [-1, 1], z)) == \ Piecewise((0, abs(z) < 1), (z*(1 - 1/z**2)/2, abs(1/z) < 1), (meijerg([0, 2], [], [], [-1, 1], z), True)) # Test that the simplest possible answer is returned: assert gammasimp(simplify(hyperexpand( meijerg([1], [1 - a], [-a/2, -a/2 + S.Half], [], 1/z)))) == \ -2*sqrt(pi)*(sqrt(z + 1) + 1)**a/a # Test that hyper is returned assert hyperexpand(meijerg([1], [], [a], [0, 0], z)) == hyper( (a,), (a + 1, a + 1), z*exp_polar(I*pi))*z**a*gamma(a)/gamma(a + 1)**2 # Test place option f = meijerg(((0, 1), ()), ((S.Half,), (0,)), z**2) assert hyperexpand(f) == sqrt(pi)/sqrt(1 + z**(-2)) assert hyperexpand(f, place=0) == sqrt(pi)*z/sqrt(z**2 + 1)
def test_mellin_transform_bessel(): from sympy.functions.elementary.miscellaneous import Max MT = mellin_transform # 8.4.19 assert MT(besselj(a, 2*sqrt(x)), x, s) == \ (gamma(a/2 + s)/gamma(a/2 - s + 1), (-re(a)/2, Rational(3, 4)), True) assert MT(sin(sqrt(x))*besselj(a, sqrt(x)), x, s) == \ (2**a*gamma(-2*s + S.Half)*gamma(a/2 + s + S.Half)/( gamma(-a/2 - s + 1)*gamma(a - 2*s + 1)), ( -re(a)/2 - S.Half, Rational(1, 4)), True) assert MT(cos(sqrt(x))*besselj(a, sqrt(x)), x, s) == \ (2**a*gamma(a/2 + s)*gamma(-2*s + S.Half)/( gamma(-a/2 - s + S.Half)*gamma(a - 2*s + 1)), ( -re(a)/2, Rational(1, 4)), True) assert MT(besselj(a, sqrt(x))**2, x, s) == \ (gamma(a + s)*gamma(S.Half - s) / (sqrt(pi)*gamma(1 - s)*gamma(1 + a - s)), (-re(a), S.Half), True) assert MT(besselj(a, sqrt(x))*besselj(-a, sqrt(x)), x, s) == \ (gamma(s)*gamma(S.Half - s) / (sqrt(pi)*gamma(1 - a - s)*gamma(1 + a - s)), (0, S.Half), True) # NOTE: prudnikov gives the strip below as (1/2 - re(a), 1). As far as # I can see this is wrong (since besselj(z) ~ 1/sqrt(z) for z large) assert MT(besselj(a - 1, sqrt(x))*besselj(a, sqrt(x)), x, s) == \ (gamma(1 - s)*gamma(a + s - S.Half) / (sqrt(pi)*gamma(Rational(3, 2) - s)*gamma(a - s + S.Half)), (S.Half - re(a), S.Half), True) assert MT(besselj(a, sqrt(x))*besselj(b, sqrt(x)), x, s) == \ (4**s*gamma(1 - 2*s)*gamma((a + b)/2 + s) / (gamma(1 - s + (b - a)/2)*gamma(1 - s + (a - b)/2) *gamma( 1 - s + (a + b)/2)), (-(re(a) + re(b))/2, S.Half), True) assert MT(besselj(a, sqrt(x))**2 + besselj(-a, sqrt(x))**2, x, s)[1:] == \ ((Max(re(a), -re(a)), S.Half), True) # Section 8.4.20 assert MT(bessely(a, 2*sqrt(x)), x, s) == \ (-cos(pi*(a/2 - s))*gamma(s - a/2)*gamma(s + a/2)/pi, (Max(-re(a)/2, re(a)/2), Rational(3, 4)), True) assert MT(sin(sqrt(x))*bessely(a, sqrt(x)), x, s) == \ (-4**s*sin(pi*(a/2 - s))*gamma(S.Half - 2*s) * gamma((1 - a)/2 + s)*gamma((1 + a)/2 + s) / (sqrt(pi)*gamma(1 - s - a/2)*gamma(1 - s + a/2)), (Max(-(re(a) + 1)/2, (re(a) - 1)/2), Rational(1, 4)), True) assert MT(cos(sqrt(x))*bessely(a, sqrt(x)), x, s) == \ (-4**s*cos(pi*(a/2 - s))*gamma(s - a/2)*gamma(s + a/2)*gamma(S.Half - 2*s) / (sqrt(pi)*gamma(S.Half - s - a/2)*gamma(S.Half - s + a/2)), (Max(-re(a)/2, re(a)/2), Rational(1, 4)), True) assert MT(besselj(a, sqrt(x))*bessely(a, sqrt(x)), x, s) == \ (-cos(pi*s)*gamma(s)*gamma(a + s)*gamma(S.Half - s) / (pi**S('3/2')*gamma(1 + a - s)), (Max(-re(a), 0), S.Half), True) assert MT(besselj(a, sqrt(x))*bessely(b, sqrt(x)), x, s) == \ (-4**s*cos(pi*(a/2 - b/2 + s))*gamma(1 - 2*s) * gamma(a/2 - b/2 + s)*gamma(a/2 + b/2 + s) / (pi*gamma(a/2 - b/2 - s + 1)*gamma(a/2 + b/2 - s + 1)), (Max((-re(a) + re(b))/2, (-re(a) - re(b))/2), S.Half), True) # NOTE bessely(a, sqrt(x))**2 and bessely(a, sqrt(x))*bessely(b, sqrt(x)) # are a mess (no matter what way you look at it ...) assert MT(bessely(a, sqrt(x))**2, x, s)[1:] == \ ((Max(-re(a), 0, re(a)), S.Half), True) # Section 8.4.22 # TODO we can't do any of these (delicate cancellation) # Section 8.4.23 assert MT(besselk(a, 2*sqrt(x)), x, s) == \ (gamma( s - a/2)*gamma(s + a/2)/2, (Max(-re(a)/2, re(a)/2), oo), True) assert MT(besselj(a, 2*sqrt(2*sqrt(x)))*besselk( a, 2*sqrt(2*sqrt(x))), x, s) == (4**(-s)*gamma(2*s)* gamma(a/2 + s)/(2*gamma(a/2 - s + 1)), (Max(0, -re(a)/2), oo), True) # TODO bessely(a, x)*besselk(a, x) is a mess assert MT(besseli(a, sqrt(x))*besselk(a, sqrt(x)), x, s) == \ (gamma(s)*gamma( a + s)*gamma(-s + S.Half)/(2*sqrt(pi)*gamma(a - s + 1)), (Max(-re(a), 0), S.Half), True) assert MT(besseli(b, sqrt(x))*besselk(a, sqrt(x)), x, s) == \ (2**(2*s - 1)*gamma(-2*s + 1)*gamma(-a/2 + b/2 + s)* \ gamma(a/2 + b/2 + s)/(gamma(-a/2 + b/2 - s + 1)* \ gamma(a/2 + b/2 - s + 1)), (Max(-re(a)/2 - re(b)/2, \ re(a)/2 - re(b)/2), S.Half), True) # TODO products of besselk are a mess mt = MT(exp(-x/2)*besselk(a, x/2), x, s) mt0 = gammasimp(trigsimp(gammasimp(mt[0].expand(func=True)))) assert mt0 == 2*pi**Rational(3, 2)*cos(pi*s)*gamma(S.Half - s)/( (cos(2*pi*a) - cos(2*pi*s))*gamma(-a - s + 1)*gamma(a - s + 1)) assert mt[1:] == ((Max(-re(a), re(a)), oo), True)
def test_gammasimp(): assert gammasimp(A*B - B*A) == A*B - B*A