def test_fourier_transform(): from diofant import simplify, expand, expand_complex, factor, expand_trig FT = fourier_transform IFT = inverse_fourier_transform def simp(x): return simplify(expand_trig(expand_complex(expand(x)))) def sinc(x): return sin(pi * x) / (pi * x) k = symbols('k', extended_real=True) f = Function("f") # TODO for this to work with real a, need to expand abs(a*x) to abs(a)*abs(x) a = symbols('a', positive=True) b = symbols('b', positive=True) posk = symbols('posk', positive=True) # Test unevaluated form assert fourier_transform(f(x), x, k) == FourierTransform(f(x), x, k) assert inverse_fourier_transform(f(k), k, x) == InverseFourierTransform(f(k), k, x) # basic examples from wikipedia assert simp(FT(Heaviside(1 - abs(2 * a * x)), x, k)) == sinc(k / a) / a # TODO IFT is a *mess* assert simp(FT(Heaviside(1 - abs(a * x)) * (1 - abs(a * x)), x, k)) == sinc(k / a)**2 / a # TODO IFT assert factor(FT(exp(-a*x)*Heaviside(x), x, k), extension=I) == \ 1/(a + 2*pi*I*k) # NOTE: the ift comes out in pieces assert IFT(1 / (a + 2 * pi * I * x), x, posk, noconds=False) == (exp(-a * posk), True) assert IFT(1 / (a + 2 * pi * I * x), x, -posk, noconds=False) == (0, True) assert IFT(1 / (a + 2 * pi * I * x), x, symbols('k', negative=True), noconds=False) == (0, True) # TODO IFT without factoring comes out as meijer g assert factor(FT(x*exp(-a*x)*Heaviside(x), x, k), extension=I) == \ 1/(a + 2*pi*I*k)**2 assert FT(exp(-a*x)*sin(b*x)*Heaviside(x), x, k) == \ b/(b**2 + (a + 2*I*pi*k)**2) assert FT(exp(-a * x**2), x, k) == sqrt(pi) * exp(-pi**2 * k**2 / a) / sqrt(a) assert IFT(sqrt(pi / a) * exp(-(pi * k)**2 / a), k, x) == exp(-a * x**2) assert FT(exp(-a * abs(x)), x, k) == 2 * a / (a**2 + 4 * pi**2 * k**2)
def test_fourier_transform(): FT = fourier_transform IFT = inverse_fourier_transform def simp(x): return simplify(expand_trig(expand_complex(expand(x)))) def sinc(x): return sin(pi*x)/(pi*x) k = symbols('k', extended_real=True) f = Function("f") # TODO for this to work with real a, need to expand abs(a*x) to abs(a)*abs(x) a = symbols('a', positive=True) b = symbols('b', positive=True) posk = symbols('posk', positive=True) # Test unevaluated form assert fourier_transform(f(x), x, k) == FourierTransform(f(x), x, k) assert inverse_fourier_transform( f(k), k, x) == InverseFourierTransform(f(k), k, x) # basic examples from wikipedia assert simp(FT(Heaviside(1 - abs(2*a*x)), x, k)) == sinc(k/a)/a # TODO IFT is a *mess* assert simp(FT(Heaviside(1 - abs(a*x))*(1 - abs(a*x)), x, k)) == sinc(k/a)**2/a # TODO IFT assert factor(FT(exp(-a*x)*Heaviside(x), x, k), extension=I) == \ 1/(a + 2*pi*I*k) # NOTE: the ift comes out in pieces assert IFT(1/(a + 2*pi*I*x), x, posk, noconds=False) == (exp(-a*posk), True) assert IFT(1/(a + 2*pi*I*x), x, -posk, noconds=False) == (0, True) assert IFT(1/(a + 2*pi*I*x), x, symbols('k', negative=True), noconds=False) == (0, True) # TODO IFT without factoring comes out as meijer g assert factor(FT(x*exp(-a*x)*Heaviside(x), x, k), extension=I) == \ 1/(a + 2*pi*I*k)**2 assert FT(exp(-a*x)*sin(b*x)*Heaviside(x), x, k) == \ b/(b**2 + (a + 2*I*pi*k)**2) assert FT(exp(-a*x**2), x, k) == sqrt(pi)*exp(-pi**2*k**2/a)/sqrt(a) assert IFT(sqrt(pi/a)*exp(-(pi*k)**2/a), k, x) == exp(-a*x**2) assert FT(exp(-a*abs(x)), x, k) == 2*a/(a**2 + 4*pi**2*k**2)
def deltaproduct(f, limit): """Handle products containing a KroneckerDelta. See Also ======== deltasummation diofant.functions.special.tensor_functions.KroneckerDelta diofant.concrete.products.product """ from diofant.concrete.products import product if ((limit[2] - limit[1]) < 0) is S.true: return S.One if not f.has(KroneckerDelta): return product(f, limit) if f.is_Add: # Identify the term in the Add that has a simple KroneckerDelta delta = None terms = [] for arg in sorted(f.args, key=default_sort_key): if delta is None and _has_simple_delta(arg, limit[0]): delta = arg else: terms.append(arg) newexpr = f.func(*terms) k = Dummy("kprime", integer=True) if isinstance(limit[1], int) and isinstance(limit[2], int): result = deltaproduct(newexpr, limit) + sum( deltaproduct(newexpr, (limit[0], limit[1], ik - 1)) * delta.subs(limit[0], ik) * deltaproduct(newexpr, (limit[0], ik + 1, limit[2])) for ik in range(int(limit[1]), int(limit[2] + 1))) else: result = deltaproduct(newexpr, limit) + deltasummation( deltaproduct(newexpr, (limit[0], limit[1], k - 1)) * delta.subs(limit[0], k) * deltaproduct(newexpr, (limit[0], k + 1, limit[2])), (k, limit[1], limit[2]), no_piecewise=_has_simple_delta(newexpr, limit[0])) return _remove_multiple_delta(result) delta, _ = _extract_delta(f, limit[0]) if not delta: g = _expand_delta(f, limit[0]) if f != g: from diofant import factor try: return factor(deltaproduct(g, limit)) except AssertionError: return deltaproduct(g, limit) return product(f, limit) from diofant import Eq c = Eq(limit[2], limit[1] - 1) return _remove_multiple_delta(f.subs(limit[0], limit[1])*KroneckerDelta(limit[2], limit[1])) + \ S.One*_simplify_delta(KroneckerDelta(limit[2], limit[1] - 1))
def test_nsimplify(): assert nsimplify(0) == 0 assert nsimplify(-1) == -1 assert nsimplify(1) == 1 assert nsimplify(1 + x) == 1 + x assert nsimplify(2.7) == Rational(27, 10) assert nsimplify(1 - GoldenRatio) == (1 - sqrt(5))/2 assert nsimplify((1 + sqrt(5))/4, [GoldenRatio]) == GoldenRatio/2 assert nsimplify(2/GoldenRatio, [GoldenRatio]) == 2*GoldenRatio - 2 assert nsimplify(exp(5*pi*I/3, evaluate=False)) == Rational(1, 2) - sqrt(3)*I/2 assert nsimplify(sin(3*pi/5, evaluate=False)) == sqrt(sqrt(5)/8 + Rational(5, 8)) assert nsimplify(sqrt(atan('1', evaluate=False))*(2 + I), [pi]) == \ sqrt(pi) + sqrt(pi)/2*I assert nsimplify(2 + exp(2*atan('1/4')*I)) == Rational(49, 17) + 8*I/17 assert nsimplify(pi, tolerance=0.01) == Rational(22, 7) assert nsimplify(pi, tolerance=0.001) == Rational(355, 113) assert nsimplify(0.33333, tolerance=1e-4) == Rational(1, 3) assert nsimplify(2.0**(1/3.), tolerance=0.001) == Rational(635, 504) assert nsimplify(2.0**(1/3.), tolerance=0.001, full=True) == cbrt(2) assert nsimplify(x + .5, rational=True) == Rational(1, 2) + x assert nsimplify(1/.3 + x, rational=True) == Rational(10, 3) + x assert nsimplify(log(3).evalf(), rational=True) == Rational(109861228866811, 100000000000000) assert nsimplify(Float(0.272198261287950), [pi, log(2)]) == pi*log(2)/8 assert nsimplify(Float(0.272198261287950).evalf(3), [pi, log(2)]) == \ -pi/4 - log(2) + Rational(7, 4) assert nsimplify(x/7.0) == x/7 assert nsimplify(pi/1e2) == pi/100 assert nsimplify(pi/1e2, rational=False) == pi/100.0 assert nsimplify(pi/1e-7) == 10000000*pi assert not nsimplify( factor(-3.0*z**2*(z**2)**(-2.5) + 3*(z**2)**(-1.5))).atoms(Float) e = x**0.0 assert e.is_Pow and nsimplify(x**0.0) == 1 assert nsimplify(3.333333, tolerance=0.1, rational=True) == Rational(10, 3) assert nsimplify(3.333333, tolerance=0.01, rational=True) == Rational(10, 3) assert nsimplify(3.666666, tolerance=0.1, rational=True) == Rational(11, 3) assert nsimplify(3.666666, tolerance=0.01, rational=True) == Rational(11, 3) assert nsimplify(33, tolerance=10, rational=True) == 33 assert nsimplify(33.33, tolerance=10, rational=True) == 30 assert nsimplify(37.76, tolerance=10, rational=True) == 40 assert nsimplify(-203.1) == -Rational(2031, 10) assert nsimplify(+.2, tolerance=0) == Rational(+1, 5) assert nsimplify(-.2, tolerance=0) == Rational(-1, 5) assert nsimplify(.2222, tolerance=0) == Rational(1111, 5000) assert nsimplify(-.2222, tolerance=0) == -Rational(1111, 5000) # issue sympy/sympy#7211, PR sympy/sympy#4112 assert nsimplify(Float(2e-8)) == Rational(1, 50000000) # issue sympy/sympy#7322 direct test assert nsimplify(1e-42, rational=True) != 0 # issue sympy/sympy#10336 inf = Float('inf') infs = (-oo, oo, inf, -inf) for i in infs: ans = sign(i)*oo assert nsimplify(i) == ans assert nsimplify(i + x) == x + ans assert nsimplify(Sum(1/n**2, (n, 1, oo)), [pi]) == pi**2/6
def test_apart_extension(): f = 2 / (x**2 + 1) g = I / (x + I) - I / (x - I) assert apart(f, extension=I) == g assert apart(f, gaussian=True) == g f = x / ((x - 2) * (x + I)) assert factor(together(apart(f))) == f
def test_apart_extension(): f = 2/(x**2 + 1) g = I/(x + I) - I/(x - I) assert apart(f, extension=I) == g assert apart(f, gaussian=True) == g f = x/((x - 2)*(x + I)) assert factor(together(apart(f))) == f
def _eval_sum_hyper(f, i, a): """ Returns (res, cond). Sums from a to oo. """ from diofant.functions import hyper from diofant.simplify import hyperexpand, hypersimp, fraction, simplify from diofant.polys.polytools import Poly, factor if a != 0: return _eval_sum_hyper(f.subs(i, i + a), i, 0) if f.subs(i, 0) == 0: if simplify(f.subs(i, Dummy('i', integer=True, positive=True))) == 0: return Integer(0), True return _eval_sum_hyper(f.subs(i, i + 1), i, 0) hs = hypersimp(f, i) if hs is None: return numer, denom = fraction(factor(hs)) top, topl = numer.as_coeff_mul(i) bot, botl = denom.as_coeff_mul(i) ab = [top, bot] factors = [topl, botl] params = [[], []] for k in range(2): for fac in factors[k]: mul = 1 if fac.is_Pow: mul = fac.exp fac = fac.base if not mul.is_Integer: return p = Poly(fac, i) if p.degree() != 1: return m, n = p.all_coeffs() ab[k] *= m**mul params[k] += [n / m] * mul # Add "1" to numerator parameters, to account for implicit n! in # hypergeometric series. ap = params[0] + [1] bq = params[1] x = ab[0] / ab[1] h = hyper(ap, bq, x) e = h try: e = hyperexpand(h) except PolynomialError: pass if e is S.NaN and h.convergence_statement: e = h return f.subs(i, 0) * e, h.convergence_statement
def test_sympyissue_4892b(): # Issues relating to issue sympy/sympy#4596 are making the actual result of this hard # to test. The answer should be something like # # (-sin(y) + sqrt(-72 + 48*cos(y) - 8*cos(y)**2)/2)*log(x + sqrt(-72 + # 48*cos(y) - 8*cos(y)**2)/(2*(3 - cos(y)))) + (-sin(y) - sqrt(-72 + # 48*cos(y) - 8*cos(y)**2)/2)*log(x - sqrt(-72 + 48*cos(y) - # 8*cos(y)**2)/(2*(3 - cos(y)))) + x**2*sin(y)/2 + 2*x*cos(y) expr = (sin(y)*x**3 + 2*cos(y)*x**2 + 12)/(x**2 + 2) assert trigsimp(factor(integrate(expr, x).diff(x) - expr)) == 0
def test_sympyissue_4892b(): # Issues relating to issue sympy/sympy#4596 are making the actual result of this hard # to test. The answer should be something like # # (-sin(y) + sqrt(-72 + 48*cos(y) - 8*cos(y)**2)/2)*log(x + sqrt(-72 + # 48*cos(y) - 8*cos(y)**2)/(2*(3 - cos(y)))) + (-sin(y) - sqrt(-72 + # 48*cos(y) - 8*cos(y)**2)/2)*log(x - sqrt(-72 + 48*cos(y) - # 8*cos(y)**2)/(2*(3 - cos(y)))) + x**2*sin(y)/2 + 2*x*cos(y) expr = (sin(y) * x**3 + 2 * cos(y) * x**2 + 12) / (x**2 + 2) assert trigsimp(factor(integrate(expr, x).diff(x) - expr)) == 0
def test_sympyissue_6249(): A = MatrixSymbol('A', 3, 3) B = MatrixSymbol('B', 3, 3) p = A * B - B * A assert cancel(p) == p assert combsimp(p) == p assert factor(p) == p assert separatevars(p) == p assert sqrtdenest(p) == p M = MatrixSymbol('M', 2, 1) assert simplify(M[0] / 2) == M[0] / 2
def test_nsimplify(): assert nsimplify(0) == 0 assert nsimplify(-1) == -1 assert nsimplify(1) == 1 assert nsimplify(1 + x) == 1 + x assert nsimplify(2.7) == Rational(27, 10) assert nsimplify(1 - GoldenRatio) == (1 - sqrt(5))/2 assert nsimplify((1 + sqrt(5))/4, [GoldenRatio]) == GoldenRatio/2 assert nsimplify(2/GoldenRatio, [GoldenRatio]) == 2*GoldenRatio - 2 assert nsimplify(exp(5*pi*I/3, evaluate=False)) == \ sympify('1/2 - sqrt(3)*I/2') assert nsimplify(sin(3*pi/5, evaluate=False)) == \ sympify('sqrt(sqrt(5)/8 + 5/8)') assert nsimplify(sqrt(atan('1', evaluate=False))*(2 + I), [pi]) == \ sqrt(pi) + sqrt(pi)/2*I assert nsimplify(2 + exp(2*atan('1/4')*I)) == sympify('49/17 + 8*I/17') assert nsimplify(pi, tolerance=0.01) == Rational(22, 7) assert nsimplify(pi, tolerance=0.001) == Rational(355, 113) assert nsimplify(0.33333, tolerance=1e-4) == Rational(1, 3) assert nsimplify(2.0**(1/3.), tolerance=0.001) == Rational(635, 504) assert nsimplify(2.0**(1/3.), tolerance=0.001, full=True) == \ 2**Rational(1, 3) assert nsimplify(x + .5, rational=True) == Rational(1, 2) + x assert nsimplify(1/.3 + x, rational=True) == Rational(10, 3) + x assert nsimplify(log(3).n(), rational=True) == \ sympify('109861228866811/100000000000000') assert nsimplify(Float(0.272198261287950), [pi, log(2)]) == pi*log(2)/8 assert nsimplify(Float(0.272198261287950).n(3), [pi, log(2)]) == \ -pi/4 - log(2) + Rational(7, 4) assert nsimplify(x/7.0) == x/7 assert nsimplify(pi/1e2) == pi/100 assert nsimplify(pi/1e2, rational=False) == pi/100.0 assert nsimplify(pi/1e-7) == 10000000*pi assert not nsimplify( factor(-3.0*z**2*(z**2)**(-2.5) + 3*(z**2)**(-1.5))).atoms(Float) e = x**0.0 assert e.is_Pow and nsimplify(x**0.0) == 1 assert nsimplify(3.333333, tolerance=0.1, rational=True) == Rational(10, 3) assert nsimplify(3.333333, tolerance=0.01, rational=True) == Rational(10, 3) assert nsimplify(3.666666, tolerance=0.1, rational=True) == Rational(11, 3) assert nsimplify(3.666666, tolerance=0.01, rational=True) == Rational(11, 3) assert nsimplify(33, tolerance=10, rational=True) == Rational(33) assert nsimplify(33.33, tolerance=10, rational=True) == Rational(30) assert nsimplify(37.76, tolerance=10, rational=True) == Rational(40) assert nsimplify(-203.1) == -Rational(2031, 10) assert nsimplify(.2, tolerance=0) == S.One/5 assert nsimplify(-.2, tolerance=0) == -S.One/5 assert nsimplify(.2222, tolerance=0) == Rational(1111, 5000) assert nsimplify(-.2222, tolerance=0) == -Rational(1111, 5000) # issue 7211, PR 4112 assert nsimplify(Float(2e-8)) == Rational(1, 50000000) # issue 7322 direct test assert nsimplify(1e-42, rational=True) != 0
def test_sympyissue_6387(): assert str(factor(-3.0 * z + 3)) == '-3.0*(1.0*z - 1.0)'
def test_integrate_hyperexponential(): # TODO: Add tests for integrate_hyperexponential() from the book a = Poly( (1 + 2 * t1 + t1**2 + 2 * t1**3) * t**2 + (1 + t1**2) * t + 1 + t1**2, t) d = Poly(1, t) DE = DifferentialExtension( extension={ 'D': [Poly(1, x), Poly(1 + t1**2, t1), Poly(t * (1 + t1**2), t)], 'Tfuncs': [tan, Lambda(i, exp(tan(i)))] }) assert integrate_hyperexponential(a, d, DE) == \ (exp(2*tan(x))*tan(x) + exp(tan(x)), 1 + t1**2, True) a = Poly((t1**3 + (x + 1) * t1**2 + t1 + x + 2) * t, t) assert integrate_hyperexponential(a, d, DE) == \ ((x + tan(x))*exp(tan(x)), 0, True) a = Poly(t, t) d = Poly(1, t) DE = DifferentialExtension(extension={ 'D': [Poly(1, x), Poly(2 * x * t, t)], 'Tfuncs': [Lambda(i, exp(x**2))] }) assert integrate_hyperexponential(a, d, DE) == \ (0, NonElementaryIntegral(exp(x**2), x), False) DE = DifferentialExtension(extension={ 'D': [Poly(1, x), Poly(t, t)], 'Tfuncs': [exp] }) assert integrate_hyperexponential(a, d, DE) == (exp(x), 0, True) a = Poly( 25 * t**6 - 10 * t**5 + 7 * t**4 - 8 * t**3 + 13 * t**2 + 2 * t - 1, t) d = Poly(25 * t**6 + 35 * t**4 + 11 * t**2 + 1, t) assert integrate_hyperexponential(a, d, DE) == \ (-(11 - 10*exp(x))/(5 + 25*exp(2*x)) + log(1 + exp(2*x)), -1, True) DE = DifferentialExtension( extension={ 'D': [Poly(1, x), Poly(t0, t0), Poly(t0 * t, t)], 'Tfuncs': [exp, Lambda(i, exp(exp(i)))] }) assert integrate_hyperexponential(Poly(2 * t0 * t**2, t), Poly(1, t), DE) == (exp(2 * exp(x)), 0, True) DE = DifferentialExtension( extension={ 'D': [Poly(1, x), Poly(t0, t0), Poly(-t0 * t, t)], 'Tfuncs': [exp, Lambda(i, exp(-exp(i)))] }) assert integrate_hyperexponential(Poly(-27*exp(9) - 162*t0*exp(9) + 27*x*t0*exp(9), t), Poly((36*exp(18) + x**2*exp(18) - 12*x*exp(18))*t, t), DE) == \ (27*exp(exp(x))/(-6*exp(9) + x*exp(9)), 0, True) DE = DifferentialExtension(extension={ 'D': [Poly(1, x), Poly(t, t)], 'Tfuncs': [exp] }) assert integrate_hyperexponential(Poly(x**2/2*t, t), Poly(1, t), DE) == \ ((2 - 2*x + x**2)*exp(x)/2, 0, True) assert integrate_hyperexponential(Poly(1 + t, t), Poly(t, t), DE) == \ (-exp(-x), 1, True) # x - exp(-x) assert integrate_hyperexponential(Poly(x, t), Poly(t + 1, t), DE) == \ (0, NonElementaryIntegral(x/(1 + exp(x)), x), False) DE = DifferentialExtension( extension={ 'D': [Poly(1, x), Poly(1 / x, t0), Poly(2 * x * t1, t1)], 'Tfuncs': [log, Lambda(i, exp(i**2))] }) elem, nonelem, b = integrate_hyperexponential( Poly( (8 * x**7 - 12 * x**5 + 6 * x**3 - x) * t1**4 + (8 * t0 * x**7 - 8 * t0 * x**6 - 4 * t0 * x**5 + 2 * t0 * x**3 + 2 * t0 * x**2 - t0 * x + 24 * x**8 - 36 * x**6 - 4 * x**5 + 22 * x**4 + 4 * x**3 - 7 * x**2 - x + 1) * t1**3 + (8 * t0 * x**8 - 4 * t0 * x**6 - 16 * t0 * x**5 - 2 * t0 * x**4 + 12 * t0 * x**3 + t0 * x**2 - 2 * t0 * x + 24 * x**9 - 36 * x**7 - 8 * x**6 + 22 * x**5 + 12 * x**4 - 7 * x**3 - 6 * x**2 + x + 1) * t1**2 + (8 * t0 * x**8 - 8 * t0 * x**6 - 16 * t0 * x**5 + 6 * t0 * x**4 + 10 * t0 * x**3 - 2 * t0 * x**2 - t0 * x + 8 * x**10 - 12 * x**8 - 4 * x**7 + 2 * x**6 + 12 * x**5 + 3 * x**4 - 9 * x**3 - x**2 + 2 * x) * t1 + 8 * t0 * x**7 - 12 * t0 * x**6 - 4 * t0 * x**5 + 8 * t0 * x**4 - t0 * x**2 - 4 * x**7 + 4 * x**6 + 4 * x**5 - 4 * x**4 - x**3 + x**2, t1), Poly((8 * x**7 - 12 * x**5 + 6 * x**3 - x) * t1**4 + (24 * x**8 + 8 * x**7 - 36 * x**6 - 12 * x**5 + 18 * x**4 + 6 * x**3 - 3 * x**2 - x) * t1**3 + (24 * x**9 + 24 * x**8 - 36 * x**7 - 36 * x**6 + 18 * x**5 + 18 * x**4 - 3 * x**3 - 3 * x**2) * t1**2 + (8 * x**10 + 24 * x**9 - 12 * x**8 - 36 * x**7 + 6 * x**6 + 18 * x**5 - x**4 - 3 * x**3) * t1 + 8 * x**10 - 12 * x**8 + 6 * x**6 - x**4, t1), DE) assert factor(elem) == -((x - 1) * log(x) / ((x + exp(x**2)) * (2 * x**2 - 1))) assert (nonelem, b) == (NonElementaryIntegral(exp(x**2) / (exp(x**2) + 1), x), False)
def test_factor(): assert factor(A * B - B * A) == A * B - B * A
def r(a, b, c): return factor(a * x**2 + b * x + c)
def test_factor(): assert factor(A*B - B*A) == A*B - B*A
def r(a, b, c): return factor(a*x**2 + b*x + c)
def test_sympyissue_6387(): assert str(factor(-3.0*z + 3)) == '-3.0*(1.0*z - 1.0)'
def findrecur(self, F=Function('F'), n=None): """Find a recurrence formula for the summand of the sum. Given a sum `f(n) = \sum_k F(n, k)`, where `F(n, k)` is doubly hypergeometric (that's, both `F(n + 1, k)/F(n, k)` and `F(n, k + 1)/F(n, k)` are rational functions of `n` and `k`), we find a recurrence for the summand `F(n, k)` of the form .. math:: \sum_{i=0}^I\sum_{j=0}^J a_{i,j}F(n - j, k - i) = 0 Examples ======== >>> from diofant import symbols, factorial, oo >>> n, k = symbols('n, k', integer=True) >>> s = Sum(factorial(n)/(factorial(k)*factorial(n - k)), (k, 0, oo)) >>> s.findrecur() -F(n, k) + F(n - 1, k) + F(n - 1, k - 1) Notes ===== We use Sister Celine's algorithm, see [1]_. References ========== .. [1] M. Petkovšek, H. S. Wilf, D. Zeilberger, A = B, 1996, Ch. 4. """ from diofant import expand_func, gamma, factor, Mul from diofant.polys import together from diofant.simplify import collect if len(self.variables) > 1: raise ValueError else: if self.limits[0][1:] != (S.Zero, S.Infinity): raise ValueError k = self.variables[0] if not n: try: n = (self.function.free_symbols - {k}).pop() except KeyError: raise ValueError a = Function('a') def f(i, j): return self.function.subs([(n, i), (k, j)]) I, J, step = 0, 1, 1 y, x, sols = S.Zero, [], {} while not any(v for a, v in sols.items()): if step % 2 != 0: dy = sum(a(I, j) * f(n - j, k - I) / f(n, k) for j in range(J)) dx = [a(I, j) for j in range(J)] I += 1 else: dy = sum(a(i, J) * f(n - J, k - i) / f(n, k) for i in range(I)) dx = [a(i, J) for i in range(I)] J += 1 step += 1 y += expand_func(dy.rewrite(gamma)) x += dx t = together(y) numer = t.as_numer_denom()[0] numer = Mul( *[t for t in factor(numer).as_coeff_mul()[1] if t.has(a)]) if not numer.is_rational_function(n, k): raise ValueError() z = collect(numer, k) eq = z.as_poly(k).all_coeffs() sols = dict(solve(eq, *x)) y = sum(a(i, j) * F(n - j, k - i) for i in range(I) for j in range(J)) y = y.subs(sols).subs(map(lambda a: (a, 1), x)) return y if y else None
def test_sympyissue_10161(): x = symbols('x', real=True) h = (2 * x * (-2 * x + abs(x)) * (x**2 - 1) / abs(x**2 - 1) + (x / abs(x) - 2) * abs(x**2 - 1)) assert (h - factor(h)).simplify() == 0
def test_integrate_hyperexponential(): # TODO: Add tests for integrate_hyperexponential() from the book a = Poly((1 + 2*t1 + t1**2 + 2*t1**3)*t**2 + (1 + t1**2)*t + 1 + t1**2, t) d = Poly(1, t) DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t1**2, t1), Poly(t*(1 + t1**2), t)], 'Tfuncs': [tan, Lambda(i, exp(tan(i)))]}) assert integrate_hyperexponential(a, d, DE) == \ (exp(2*tan(x))*tan(x) + exp(tan(x)), 1 + t1**2, True) a = Poly((t1**3 + (x + 1)*t1**2 + t1 + x + 2)*t, t) assert integrate_hyperexponential(a, d, DE) == \ ((x + tan(x))*exp(tan(x)), 0, True) a = Poly(t, t) d = Poly(1, t) DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(2*x*t, t)], 'Tfuncs': [Lambda(i, exp(x**2))]}) assert integrate_hyperexponential(a, d, DE) == \ (0, NonElementaryIntegral(exp(x**2), x), False) DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)], 'Tfuncs': [exp]}) assert integrate_hyperexponential(a, d, DE) == (exp(x), 0, True) a = Poly(25*t**6 - 10*t**5 + 7*t**4 - 8*t**3 + 13*t**2 + 2*t - 1, t) d = Poly(25*t**6 + 35*t**4 + 11*t**2 + 1, t) assert integrate_hyperexponential(a, d, DE) == \ (-(11 - 10*exp(x))/(5 + 25*exp(2*x)) + log(1 + exp(2*x)), -1, True) DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t0, t0), Poly(t0*t, t)], 'Tfuncs': [exp, Lambda(i, exp(exp(i)))]}) assert integrate_hyperexponential(Poly(2*t0*t**2, t), Poly(1, t), DE) == (exp(2*exp(x)), 0, True) DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t0, t0), Poly(-t0*t, t)], 'Tfuncs': [exp, Lambda(i, exp(-exp(i)))]}) assert integrate_hyperexponential(Poly(-27*exp(9) - 162*t0*exp(9) + 27*x*t0*exp(9), t), Poly((36*exp(18) + x**2*exp(18) - 12*x*exp(18))*t, t), DE) == \ (27*exp(exp(x))/(-6*exp(9) + x*exp(9)), 0, True) DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)], 'Tfuncs': [exp]}) assert integrate_hyperexponential(Poly(x**2/2*t, t), Poly(1, t), DE) == \ ((2 - 2*x + x**2)*exp(x)/2, 0, True) assert integrate_hyperexponential(Poly(1 + t, t), Poly(t, t), DE) == \ (-exp(-x), 1, True) # x - exp(-x) assert integrate_hyperexponential(Poly(x, t), Poly(t + 1, t), DE) == \ (0, NonElementaryIntegral(x/(1 + exp(x)), x), False) DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t0), Poly(2*x*t1, t1)], 'Tfuncs': [log, Lambda(i, exp(i**2))]}) elem, nonelem, b = integrate_hyperexponential(Poly((8*x**7 - 12*x**5 + 6*x**3 - x)*t1**4 + (8*t0*x**7 - 8*t0*x**6 - 4*t0*x**5 + 2*t0*x**3 + 2*t0*x**2 - t0*x + 24*x**8 - 36*x**6 - 4*x**5 + 22*x**4 + 4*x**3 - 7*x**2 - x + 1)*t1**3 + (8*t0*x**8 - 4*t0*x**6 - 16*t0*x**5 - 2*t0*x**4 + 12*t0*x**3 + t0*x**2 - 2*t0*x + 24*x**9 - 36*x**7 - 8*x**6 + 22*x**5 + 12*x**4 - 7*x**3 - 6*x**2 + x + 1)*t1**2 + (8*t0*x**8 - 8*t0*x**6 - 16*t0*x**5 + 6*t0*x**4 + 10*t0*x**3 - 2*t0*x**2 - t0*x + 8*x**10 - 12*x**8 - 4*x**7 + 2*x**6 + 12*x**5 + 3*x**4 - 9*x**3 - x**2 + 2*x)*t1 + 8*t0*x**7 - 12*t0*x**6 - 4*t0*x**5 + 8*t0*x**4 - t0*x**2 - 4*x**7 + 4*x**6 + 4*x**5 - 4*x**4 - x**3 + x**2, t1), Poly((8*x**7 - 12*x**5 + 6*x**3 - x)*t1**4 + (24*x**8 + 8*x**7 - 36*x**6 - 12*x**5 + 18*x**4 + 6*x**3 - 3*x**2 - x)*t1**3 + (24*x**9 + 24*x**8 - 36*x**7 - 36*x**6 + 18*x**5 + 18*x**4 - 3*x**3 - 3*x**2)*t1**2 + (8*x**10 + 24*x**9 - 12*x**8 - 36*x**7 + 6*x**6 + 18*x**5 - x**4 - 3*x**3)*t1 + 8*x**10 - 12*x**8 + 6*x**6 - x**4, t1), DE) assert factor(elem) == -((x - 1)*log(x)/((x + exp(x**2))*(2*x**2 - 1))) assert (nonelem, b) == (NonElementaryIntegral(exp(x**2)/(exp(x**2) + 1), x), False)