chore: 添加虚拟环境到仓库
- 添加 backend_service/venv 虚拟环境 - 包含所有Python依赖包 - 注意:虚拟环境约393MB,包含12655个文件
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
from sympy.core.function import Function
|
||||
from sympy.core.numbers import (Rational, pi)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.functions.special.delta_functions import (DiracDelta, Heaviside)
|
||||
from sympy.integrals.deltafunctions import change_mul, deltaintegrate
|
||||
|
||||
f = Function("f")
|
||||
x_1, x_2, x, y, z = symbols("x_1 x_2 x y z")
|
||||
|
||||
|
||||
def test_change_mul():
|
||||
assert change_mul(x, x) == (None, None)
|
||||
assert change_mul(x*y, x) == (None, None)
|
||||
assert change_mul(x*y*DiracDelta(x), x) == (DiracDelta(x), x*y)
|
||||
assert change_mul(x*y*DiracDelta(x)*DiracDelta(y), x) == \
|
||||
(DiracDelta(x), x*y*DiracDelta(y))
|
||||
assert change_mul(DiracDelta(x)**2, x) == \
|
||||
(DiracDelta(x), DiracDelta(x))
|
||||
assert change_mul(y*DiracDelta(x)**2, x) == \
|
||||
(DiracDelta(x), y*DiracDelta(x))
|
||||
|
||||
|
||||
def test_deltaintegrate():
|
||||
assert deltaintegrate(x, x) is None
|
||||
assert deltaintegrate(x + DiracDelta(x), x) is None
|
||||
assert deltaintegrate(DiracDelta(x, 0), x) == Heaviside(x)
|
||||
for n in range(10):
|
||||
assert deltaintegrate(DiracDelta(x, n + 1), x) == DiracDelta(x, n)
|
||||
assert deltaintegrate(DiracDelta(x), x) == Heaviside(x)
|
||||
assert deltaintegrate(DiracDelta(-x), x) == Heaviside(x)
|
||||
assert deltaintegrate(DiracDelta(x - y), x) == Heaviside(x - y)
|
||||
assert deltaintegrate(DiracDelta(y - x), x) == Heaviside(x - y)
|
||||
|
||||
assert deltaintegrate(x*DiracDelta(x), x) == 0
|
||||
assert deltaintegrate((x - y)*DiracDelta(x - y), x) == 0
|
||||
|
||||
assert deltaintegrate(DiracDelta(x)**2, x) == DiracDelta(0)*Heaviside(x)
|
||||
assert deltaintegrate(y*DiracDelta(x)**2, x) == \
|
||||
y*DiracDelta(0)*Heaviside(x)
|
||||
assert deltaintegrate(DiracDelta(x, 1), x) == DiracDelta(x, 0)
|
||||
assert deltaintegrate(y*DiracDelta(x, 1), x) == y*DiracDelta(x, 0)
|
||||
assert deltaintegrate(DiracDelta(x, 1)**2, x) == -DiracDelta(0, 2)*Heaviside(x)
|
||||
assert deltaintegrate(y*DiracDelta(x, 1)**2, x) == -y*DiracDelta(0, 2)*Heaviside(x)
|
||||
|
||||
|
||||
assert deltaintegrate(DiracDelta(x) * f(x), x) == f(0) * Heaviside(x)
|
||||
assert deltaintegrate(DiracDelta(-x) * f(x), x) == f(0) * Heaviside(x)
|
||||
assert deltaintegrate(DiracDelta(x - 1) * f(x), x) == f(1) * Heaviside(x - 1)
|
||||
assert deltaintegrate(DiracDelta(1 - x) * f(x), x) == f(1) * Heaviside(x - 1)
|
||||
assert deltaintegrate(DiracDelta(x**2 + x - 2), x) == \
|
||||
Heaviside(x - 1)/3 + Heaviside(x + 2)/3
|
||||
|
||||
p = cos(x)*(DiracDelta(x) + DiracDelta(x**2 - 1))*sin(x)*(x - pi)
|
||||
assert deltaintegrate(p, x) - (-pi*(cos(1)*Heaviside(-1 + x)*sin(1)/2 - \
|
||||
cos(1)*Heaviside(1 + x)*sin(1)/2) + \
|
||||
cos(1)*Heaviside(1 + x)*sin(1)/2 + \
|
||||
cos(1)*Heaviside(-1 + x)*sin(1)/2) == 0
|
||||
|
||||
p = x_2*DiracDelta(x - x_2)*DiracDelta(x_2 - x_1)
|
||||
assert deltaintegrate(p, x_2) == x*DiracDelta(x - x_1)*Heaviside(x_2 - x)
|
||||
|
||||
p = x*y**2*z*DiracDelta(y - x)*DiracDelta(y - z)*DiracDelta(x - z)
|
||||
assert deltaintegrate(p, y) == x**3*z*DiracDelta(x - z)**2*Heaviside(y - x)
|
||||
assert deltaintegrate((x + 1)*DiracDelta(2*x), x) == S.Half * Heaviside(x)
|
||||
assert deltaintegrate((x + 1)*DiracDelta(x*Rational(2, 3) + Rational(4, 9)), x) == \
|
||||
S.Half * Heaviside(x + Rational(2, 3))
|
||||
|
||||
a, b, c = symbols('a b c', commutative=False)
|
||||
assert deltaintegrate(DiracDelta(x - y)*f(x - b)*f(x - a), x) == \
|
||||
f(y - b)*f(y - a)*Heaviside(x - y)
|
||||
|
||||
p = f(x - a)*DiracDelta(x - y)*f(x - c)*f(x - b)
|
||||
assert deltaintegrate(p, x) == f(y - a)*f(y - c)*f(y - b)*Heaviside(x - y)
|
||||
|
||||
p = DiracDelta(x - z)*f(x - b)*f(x - a)*DiracDelta(x - y)
|
||||
assert deltaintegrate(p, x) == DiracDelta(y - z)*f(y - b)*f(y - a) * \
|
||||
Heaviside(x - y)
|
||||
@@ -0,0 +1,277 @@
|
||||
# A collection of failing integrals from the issues.
|
||||
|
||||
from sympy.core.numbers import (I, Rational, oo, pi)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.complexes import sign
|
||||
from sympy.functions.elementary.exponential import (exp, log)
|
||||
from sympy.functions.elementary.hyperbolic import (sech, sinh)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.piecewise import Piecewise
|
||||
from sympy.functions.elementary.trigonometric import (acos, atan, cos, sin, tan)
|
||||
from sympy.functions.special.delta_functions import DiracDelta
|
||||
from sympy.functions.special.gamma_functions import gamma
|
||||
from sympy.integrals.integrals import (Integral, integrate)
|
||||
from sympy.simplify.fu import fu
|
||||
|
||||
|
||||
from sympy.testing.pytest import XFAIL, slow, tooslow
|
||||
|
||||
from sympy.abc import x, k, c, y, b, h, a, m, z, n, t
|
||||
|
||||
|
||||
@tooslow
|
||||
@XFAIL
|
||||
def test_issue_3880():
|
||||
# integrate_hyperexponential(Poly(t*2*(1 - t0**2)*t0*(x**3 + x**2), t), Poly((1 + t0**2)**2*2*(x**2 + x + 1), t), [Poly(1, x), Poly(1 + t0**2, t0), Poly(t, t)], [x, t0, t], [exp, tan])
|
||||
assert not integrate(exp(x)*cos(2*x)*sin(2*x) * (x**3 + x**2)/(2*(x**2 + x + 1)), x).has(Integral)
|
||||
|
||||
|
||||
def test_issue_4212_real():
|
||||
xr = symbols('xr', real=True)
|
||||
negabsx = Piecewise((-xr, xr < 0), (xr, True))
|
||||
assert integrate(sign(xr), xr) == negabsx
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_4212():
|
||||
# XXX: Maybe this should be expected to fail without real assumptions on x.
|
||||
# As a complex function sign(x) is not analytic and so there is no complex
|
||||
# function whose complex derivative is sign(x). With real assumptions this
|
||||
# works (see test_issue_4212_real above).
|
||||
assert not integrate(sign(x), x).has(Integral)
|
||||
|
||||
|
||||
def test_issue_4511():
|
||||
# This works, but gives a slightly over-complicated answer.
|
||||
f = integrate(cos(x)**2 / (1 - sin(x)), x)
|
||||
assert fu(f) == x - cos(x) - 1
|
||||
assert f == ((x*tan(x/2)**2 + x - 2)/(tan(x/2)**2 + 1)).expand()
|
||||
|
||||
|
||||
def test_integrate_DiracDelta_no_meijerg():
|
||||
assert integrate(integrate(integrate(
|
||||
DiracDelta(x - y - z), (z, 0, oo)), (y, 0, 1), meijerg=False), (x, 0, 1)) == S.Half
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_integrate_DiracDelta_fails():
|
||||
# issue 6427
|
||||
# works without meijerg. See test_integrate_DiracDelta_no_meijerg above.
|
||||
assert integrate(integrate(integrate(
|
||||
DiracDelta(x - y - z), (z, 0, oo)), (y, 0, 1)), (x, 0, 1)) == S.Half
|
||||
|
||||
|
||||
@XFAIL
|
||||
@slow
|
||||
def test_issue_4525():
|
||||
# Warning: takes a long time
|
||||
assert not integrate((x**m * (1 - x)**n * (a + b*x + c*x**2))/(1 + x**2), (x, 0, 1)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
@tooslow
|
||||
def test_issue_4540():
|
||||
# Note, this integral is probably nonelementary
|
||||
assert not integrate(
|
||||
(sin(1/x) - x*exp(x)) /
|
||||
((-sin(1/x) + x*exp(x))*x + x*sin(1/x)), x).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
@slow
|
||||
def test_issue_4891():
|
||||
# Requires the hypergeometric function.
|
||||
assert not integrate(cos(x)**y, x).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
@slow
|
||||
def test_issue_1796a():
|
||||
assert not integrate(exp(2*b*x)*exp(-a*x**2), x).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_4895b():
|
||||
assert not integrate(exp(2*b*x)*exp(-a*x**2), (x, -oo, 0)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_4895c():
|
||||
assert not integrate(exp(2*b*x)*exp(-a*x**2), (x, -oo, oo)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_4895d():
|
||||
assert not integrate(exp(2*b*x)*exp(-a*x**2), (x, 0, oo)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
@slow
|
||||
def test_issue_4941():
|
||||
assert not integrate(sqrt(1 + sinh(x/20)**2), (x, -25, 25)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_4992():
|
||||
# Nonelementary integral. Requires hypergeometric/Meijer-G handling.
|
||||
assert not integrate(log(x) * x**(k - 1) * exp(-x) / gamma(k), (x, 0, oo)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_16396a():
|
||||
i = integrate(1/(1+sqrt(tan(x))), (x, pi/3, pi/6))
|
||||
assert not i.has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_16396b():
|
||||
i = integrate(x*sin(x)/(1+cos(x)**2), (x, 0, pi))
|
||||
assert not i.has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_16046():
|
||||
assert integrate(exp(exp(I*x)), [x, 0, 2*pi]) == 2*pi
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_15925a():
|
||||
assert not integrate(sqrt((1+sin(x))**2+(cos(x))**2), (x, -pi/2, pi/2)).has(Integral)
|
||||
|
||||
|
||||
def test_issue_15925b():
|
||||
f = sqrt((-12*cos(x)**2*sin(x))**2+(12*cos(x)*sin(x)**2)**2)
|
||||
assert integrate(f, (x, 0, pi/6)) == Rational(3, 2)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_15925b_manual():
|
||||
assert not integrate(sqrt((-12*cos(x)**2*sin(x))**2+(12*cos(x)*sin(x)**2)**2),
|
||||
(x, 0, pi/6), manual=True).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
@tooslow
|
||||
def test_issue_15227():
|
||||
i = integrate(log(1-x)*log((1+x)**2)/x, (x, 0, 1))
|
||||
assert not i.has(Integral)
|
||||
# assert i == -5*zeta(3)/4
|
||||
|
||||
|
||||
@XFAIL
|
||||
@slow
|
||||
def test_issue_14716():
|
||||
i = integrate(log(x + 5)*cos(pi*x),(x, S.Half, 1))
|
||||
assert not i.has(Integral)
|
||||
# Mathematica can not solve it either, but
|
||||
# integrate(log(x + 5)*cos(pi*x),(x, S.Half, 1)).transform(x, y - 5).doit()
|
||||
# works
|
||||
# assert i == -log(Rational(11, 2))/pi - Si(pi*Rational(11, 2))/pi + Si(6*pi)/pi
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_14709a():
|
||||
i = integrate(x*acos(1 - 2*x/h), (x, 0, h))
|
||||
assert not i.has(Integral)
|
||||
# assert i == 5*h**2*pi/16
|
||||
|
||||
|
||||
@slow
|
||||
@XFAIL
|
||||
def test_issue_14398():
|
||||
assert not integrate(exp(x**2)*cos(x), x).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_14074():
|
||||
i = integrate(log(sin(x)), (x, 0, pi/2))
|
||||
assert not i.has(Integral)
|
||||
# assert i == -pi*log(2)/2
|
||||
|
||||
|
||||
@XFAIL
|
||||
@slow
|
||||
def test_issue_14078b():
|
||||
i = integrate((atan(4*x)-atan(2*x))/x, (x, 0, oo))
|
||||
assert not i.has(Integral)
|
||||
# assert i == pi*log(2)/2
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_13792():
|
||||
i = integrate(log(1/x) / (1 - x), (x, 0, 1))
|
||||
assert not i.has(Integral)
|
||||
# assert i in [polylog(2, -exp_polar(I*pi)), pi**2/6]
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_11845a():
|
||||
assert not integrate(exp(y - x**3), (x, 0, 1)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_11845b():
|
||||
assert not integrate(exp(-y - x**3), (x, 0, 1)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_11813():
|
||||
assert not integrate((a - x)**Rational(-1, 2)*x, (x, 0, a)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_11254c():
|
||||
assert not integrate(sech(x)**2, (x, 0, 1)).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_10584():
|
||||
assert not integrate(sqrt(x**2 + 1/x**2), x).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_9101():
|
||||
assert not integrate(log(x + sqrt(x**2 + y**2 + z**2)), z).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_7147():
|
||||
assert not integrate(x/sqrt(a*x**2 + b*x + c)**3, x).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_7109():
|
||||
assert not integrate(sqrt(a**2/(a**2 - x**2)), x).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_integrate_Piecewise_rational_over_reals():
|
||||
f = Piecewise(
|
||||
(0, t - 478.515625*pi < 0),
|
||||
(13.2075145209219*pi/(0.000871222*t + 0.995)**2, t - 478.515625*pi >= 0))
|
||||
|
||||
assert abs((integrate(f, (t, 0, oo)) - 15235.9375*pi).evalf()) <= 1e-7
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_issue_4311_slow():
|
||||
# Not slow when bypassing heurish
|
||||
assert not integrate(x*abs(9-x**2), x).has(Integral)
|
||||
|
||||
@XFAIL
|
||||
def test_issue_20370():
|
||||
a = symbols('a', positive=True)
|
||||
assert integrate((1 + a * cos(x))**-1, (x, 0, 2 * pi)) == (2 * pi / sqrt(1 - a**2))
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_polylog():
|
||||
# log(1/x)*log(x+1)-polylog(2, -x)
|
||||
assert not integrate(log(1/x)/(x + 1), x).has(Integral)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_polylog_manual():
|
||||
# Make sure _parts_rule does not go into an infinite loop here
|
||||
assert not integrate(log(1/x)/(x + 1), x, manual=True).has(Integral)
|
||||
@@ -0,0 +1,417 @@
|
||||
from sympy.concrete.summations import Sum
|
||||
from sympy.core.add import Add
|
||||
from sympy.core.function import (Derivative, Function, diff)
|
||||
from sympy.core.numbers import (I, Rational, pi)
|
||||
from sympy.core.relational import Eq, Ne
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.elementary.exponential import (LambertW, exp, log)
|
||||
from sympy.functions.elementary.hyperbolic import (asinh, cosh, sinh, tanh)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.piecewise import Piecewise
|
||||
from sympy.functions.elementary.trigonometric import (acos, asin, atan, cos, sin, tan)
|
||||
from sympy.functions.special.bessel import (besselj, besselk, bessely, jn)
|
||||
from sympy.functions.special.error_functions import erf
|
||||
from sympy.integrals.integrals import Integral
|
||||
from sympy.logic.boolalg import And
|
||||
from sympy.matrices import Matrix
|
||||
from sympy.simplify.ratsimp import ratsimp
|
||||
from sympy.simplify.simplify import simplify
|
||||
from sympy.integrals.heurisch import components, heurisch, heurisch_wrapper
|
||||
from sympy.testing.pytest import XFAIL, slow
|
||||
from sympy.integrals.integrals import integrate
|
||||
from sympy import S
|
||||
|
||||
x, y, z, nu = symbols('x,y,z,nu')
|
||||
f = Function('f')
|
||||
|
||||
|
||||
def test_components():
|
||||
assert components(x*y, x) == {x}
|
||||
assert components(1/(x + y), x) == {x}
|
||||
assert components(sin(x), x) == {sin(x), x}
|
||||
assert components(sin(x)*sqrt(log(x)), x) == \
|
||||
{log(x), sin(x), sqrt(log(x)), x}
|
||||
assert components(x*sin(exp(x)*y), x) == \
|
||||
{sin(y*exp(x)), x, exp(x)}
|
||||
assert components(x**Rational(17, 54)/sqrt(sin(x)), x) == \
|
||||
{sin(x), x**Rational(1, 54), sqrt(sin(x)), x}
|
||||
|
||||
assert components(f(x), x) == \
|
||||
{x, f(x)}
|
||||
assert components(Derivative(f(x), x), x) == \
|
||||
{x, f(x), Derivative(f(x), x)}
|
||||
assert components(f(x)*diff(f(x), x), x) == \
|
||||
{x, f(x), Derivative(f(x), x), Derivative(f(x), x)}
|
||||
|
||||
|
||||
def test_issue_10680():
|
||||
assert isinstance(integrate(x**log(x**log(x**log(x))),x), Integral)
|
||||
|
||||
|
||||
def test_issue_21166():
|
||||
assert integrate(sin(x/sqrt(abs(x))), (x, -1, 1)) == 0
|
||||
|
||||
|
||||
def test_heurisch_polynomials():
|
||||
assert heurisch(1, x) == x
|
||||
assert heurisch(x, x) == x**2/2
|
||||
assert heurisch(x**17, x) == x**18/18
|
||||
# For coverage
|
||||
assert heurisch_wrapper(y, x) == y*x
|
||||
|
||||
|
||||
def test_heurisch_fractions():
|
||||
assert heurisch(1/x, x) == log(x)
|
||||
assert heurisch(1/(2 + x), x) == log(x + 2)
|
||||
assert heurisch(1/(x + sin(y)), x) == log(x + sin(y))
|
||||
|
||||
# Up to a constant, where C = pi*I*Rational(5, 12), Mathematica gives identical
|
||||
# result in the first case. The difference is because SymPy changes
|
||||
# signs of expressions without any care.
|
||||
# XXX ^ ^ ^ is this still correct?
|
||||
assert heurisch(5*x**5/(
|
||||
2*x**6 - 5), x) in [5*log(2*x**6 - 5) / 12, 5*log(-2*x**6 + 5) / 12]
|
||||
assert heurisch(5*x**5/(2*x**6 + 5), x) == 5*log(2*x**6 + 5) / 12
|
||||
|
||||
assert heurisch(1/x**2, x) == -1/x
|
||||
assert heurisch(-1/x**5, x) == 1/(4*x**4)
|
||||
|
||||
|
||||
def test_heurisch_log():
|
||||
assert heurisch(log(x), x) == x*log(x) - x
|
||||
assert heurisch(log(3*x), x) == -x + x*log(3) + x*log(x)
|
||||
assert heurisch(log(x**2), x) in [x*log(x**2) - 2*x, 2*x*log(x) - 2*x]
|
||||
|
||||
|
||||
def test_heurisch_exp():
|
||||
assert heurisch(exp(x), x) == exp(x)
|
||||
assert heurisch(exp(-x), x) == -exp(-x)
|
||||
assert heurisch(exp(17*x), x) == exp(17*x) / 17
|
||||
assert heurisch(x*exp(x), x) == x*exp(x) - exp(x)
|
||||
assert heurisch(x*exp(x**2), x) == exp(x**2) / 2
|
||||
|
||||
assert heurisch(exp(-x**2), x) is None
|
||||
|
||||
assert heurisch(2**x, x) == 2**x/log(2)
|
||||
assert heurisch(x*2**x, x) == x*2**x/log(2) - 2**x*log(2)**(-2)
|
||||
|
||||
assert heurisch(Integral(x**z*y, (y, 1, 2), (z, 2, 3)).function, x) == (x*x**z*y)/(z+1)
|
||||
assert heurisch(Sum(x**z, (z, 1, 2)).function, z) == x**z/log(x)
|
||||
|
||||
# https://github.com/sympy/sympy/issues/23707
|
||||
anti = -exp(z)/(sqrt(x - y)*exp(z*sqrt(x - y)) - exp(z*sqrt(x - y)))
|
||||
assert heurisch(exp(z)*exp(-z*sqrt(x - y)), z) == anti
|
||||
|
||||
|
||||
def test_heurisch_trigonometric():
|
||||
assert heurisch(sin(x), x) == -cos(x)
|
||||
assert heurisch(pi*sin(x) + 1, x) == x - pi*cos(x)
|
||||
|
||||
assert heurisch(cos(x), x) == sin(x)
|
||||
assert heurisch(tan(x), x) in [
|
||||
log(1 + tan(x)**2)/2,
|
||||
log(tan(x) + I) + I*x,
|
||||
log(tan(x) - I) - I*x,
|
||||
]
|
||||
|
||||
assert heurisch(sin(x)*sin(y), x) == -cos(x)*sin(y)
|
||||
assert heurisch(sin(x)*sin(y), y) == -cos(y)*sin(x)
|
||||
|
||||
# gives sin(x) in answer when run via setup.py and cos(x) when run via py.test
|
||||
assert heurisch(sin(x)*cos(x), x) in [sin(x)**2 / 2, -cos(x)**2 / 2]
|
||||
assert heurisch(cos(x)/sin(x), x) == log(sin(x))
|
||||
|
||||
assert heurisch(x*sin(7*x), x) == sin(7*x) / 49 - x*cos(7*x) / 7
|
||||
assert heurisch(1/pi/4 * x**2*cos(x), x) == 1/pi/4*(x**2*sin(x) -
|
||||
2*sin(x) + 2*x*cos(x))
|
||||
|
||||
assert heurisch(acos(x/4) * asin(x/4), x) == 2*x - (sqrt(16 - x**2))*asin(x/4) \
|
||||
+ (sqrt(16 - x**2))*acos(x/4) + x*asin(x/4)*acos(x/4)
|
||||
|
||||
assert heurisch(sin(x)/(cos(x)**2+1), x) == -atan(cos(x)) #fixes issue 13723
|
||||
assert heurisch(1/(cos(x)+2), x) == 2*sqrt(3)*atan(sqrt(3)*tan(x/2)/3)/3
|
||||
assert heurisch(2*sin(x)*cos(x)/(sin(x)**4 + 1), x) == atan(sqrt(2)*sin(x)
|
||||
- 1) - atan(sqrt(2)*sin(x) + 1)
|
||||
|
||||
assert heurisch(1/cosh(x), x) == 2*atan(tanh(x/2))
|
||||
|
||||
|
||||
def test_heurisch_hyperbolic():
|
||||
assert heurisch(sinh(x), x) == cosh(x)
|
||||
assert heurisch(cosh(x), x) == sinh(x)
|
||||
|
||||
assert heurisch(x*sinh(x), x) == x*cosh(x) - sinh(x)
|
||||
assert heurisch(x*cosh(x), x) == x*sinh(x) - cosh(x)
|
||||
|
||||
assert heurisch(
|
||||
x*asinh(x/2), x) == x**2*asinh(x/2)/2 + asinh(x/2) - x*sqrt(4 + x**2)/4
|
||||
|
||||
|
||||
def test_heurisch_mixed():
|
||||
assert heurisch(sin(x)*exp(x), x) == exp(x)*sin(x)/2 - exp(x)*cos(x)/2
|
||||
assert heurisch(sin(x/sqrt(-x)), x) == 2*x*cos(x/sqrt(-x))/sqrt(-x) - 2*sin(x/sqrt(-x))
|
||||
|
||||
|
||||
def test_heurisch_radicals():
|
||||
assert heurisch(1/sqrt(x), x) == 2*sqrt(x)
|
||||
assert heurisch(1/sqrt(x)**3, x) == -2/sqrt(x)
|
||||
assert heurisch(sqrt(x)**3, x) == 2*sqrt(x)**5/5
|
||||
|
||||
assert heurisch(sin(x)*sqrt(cos(x)), x) == -2*sqrt(cos(x))**3/3
|
||||
y = Symbol('y')
|
||||
assert heurisch(sin(y*sqrt(x)), x) == 2/y**2*sin(y*sqrt(x)) - \
|
||||
2*sqrt(x)*cos(y*sqrt(x))/y
|
||||
assert heurisch_wrapper(sin(y*sqrt(x)), x) == Piecewise(
|
||||
(-2*sqrt(x)*cos(sqrt(x)*y)/y + 2*sin(sqrt(x)*y)/y**2, Ne(y, 0)),
|
||||
(0, True))
|
||||
y = Symbol('y', positive=True)
|
||||
assert heurisch_wrapper(sin(y*sqrt(x)), x) == 2/y**2*sin(y*sqrt(x)) - \
|
||||
2*sqrt(x)*cos(y*sqrt(x))/y
|
||||
|
||||
|
||||
def test_heurisch_special():
|
||||
assert heurisch(erf(x), x) == x*erf(x) + exp(-x**2)/sqrt(pi)
|
||||
assert heurisch(exp(-x**2)*erf(x), x) == sqrt(pi)*erf(x)**2 / 4
|
||||
|
||||
|
||||
def test_heurisch_symbolic_coeffs():
|
||||
assert heurisch(1/(x + y), x) == log(x + y)
|
||||
assert heurisch(1/(x + sqrt(2)), x) == log(x + sqrt(2))
|
||||
assert simplify(diff(heurisch(log(x + y + z), y), y)) == log(x + y + z)
|
||||
|
||||
|
||||
def test_heurisch_symbolic_coeffs_1130():
|
||||
y = Symbol('y')
|
||||
assert heurisch_wrapper(1/(x**2 + y), x) == Piecewise(
|
||||
(log(x - sqrt(-y))/(2*sqrt(-y)) - log(x + sqrt(-y))/(2*sqrt(-y)),
|
||||
Ne(y, 0)), (-1/x, True))
|
||||
y = Symbol('y', positive=True)
|
||||
assert heurisch_wrapper(1/(x**2 + y), x) == (atan(x/sqrt(y))/sqrt(y))
|
||||
|
||||
|
||||
def test_heurisch_hacking():
|
||||
assert heurisch(sqrt(1 + 7*x**2), x, hints=[]) == \
|
||||
x*sqrt(1 + 7*x**2)/2 + sqrt(7)*asinh(sqrt(7)*x)/14
|
||||
assert heurisch(sqrt(1 - 7*x**2), x, hints=[]) == \
|
||||
x*sqrt(1 - 7*x**2)/2 + sqrt(7)*asin(sqrt(7)*x)/14
|
||||
|
||||
assert heurisch(1/sqrt(1 + 7*x**2), x, hints=[]) == \
|
||||
sqrt(7)*asinh(sqrt(7)*x)/7
|
||||
assert heurisch(1/sqrt(1 - 7*x**2), x, hints=[]) == \
|
||||
sqrt(7)*asin(sqrt(7)*x)/7
|
||||
|
||||
assert heurisch(exp(-7*x**2), x, hints=[]) == \
|
||||
sqrt(7*pi)*erf(sqrt(7)*x)/14
|
||||
|
||||
assert heurisch(1/sqrt(9 - 4*x**2), x, hints=[]) == \
|
||||
asin(x*Rational(2, 3))/2
|
||||
|
||||
assert heurisch(1/sqrt(9 + 4*x**2), x, hints=[]) == \
|
||||
asinh(x*Rational(2, 3))/2
|
||||
|
||||
assert heurisch(1/sqrt(3*x**2-4), x, hints=[]) == \
|
||||
sqrt(3)*log(3*x + sqrt(3)*sqrt(3*x**2 - 4))/3
|
||||
|
||||
|
||||
def test_heurisch_function():
|
||||
assert heurisch(f(x), x) is None
|
||||
|
||||
@XFAIL
|
||||
def test_heurisch_function_derivative():
|
||||
# TODO: it looks like this used to work just by coincindence and
|
||||
# thanks to sloppy implementation. Investigate why this used to
|
||||
# work at all and if support for this can be restored.
|
||||
|
||||
df = diff(f(x), x)
|
||||
|
||||
assert heurisch(f(x)*df, x) == f(x)**2/2
|
||||
assert heurisch(f(x)**2*df, x) == f(x)**3/3
|
||||
assert heurisch(df/f(x), x) == log(f(x))
|
||||
|
||||
|
||||
def test_heurisch_wrapper():
|
||||
f = 1/(y + x)
|
||||
assert heurisch_wrapper(f, x) == log(x + y)
|
||||
f = 1/(y - x)
|
||||
assert heurisch_wrapper(f, x) == -log(x - y)
|
||||
f = 1/((y - x)*(y + x))
|
||||
assert heurisch_wrapper(f, x) == Piecewise(
|
||||
(-log(x - y)/(2*y) + log(x + y)/(2*y), Ne(y, 0)), (1/x, True))
|
||||
# issue 6926
|
||||
f = sqrt(x**2/((y - x)*(y + x)))
|
||||
assert heurisch_wrapper(f, x) == x*sqrt(-x**2/(x**2 - y**2)) \
|
||||
- y**2*sqrt(-x**2/(x**2 - y**2))/x
|
||||
|
||||
|
||||
def test_issue_3609():
|
||||
assert heurisch(1/(x * (1 + log(x)**2)), x) == atan(log(x))
|
||||
|
||||
### These are examples from the Poor Man's Integrator
|
||||
### http://www-sop.inria.fr/cafe/Manuel.Bronstein/pmint/examples/
|
||||
|
||||
|
||||
def test_pmint_rat():
|
||||
# TODO: heurisch() is off by a constant: -3/4. Possibly different permutation
|
||||
# would give the optimal result?
|
||||
|
||||
def drop_const(expr, x):
|
||||
if expr.is_Add:
|
||||
return Add(*[ arg for arg in expr.args if arg.has(x) ])
|
||||
else:
|
||||
return expr
|
||||
|
||||
f = (x**7 - 24*x**4 - 4*x**2 + 8*x - 8)/(x**8 + 6*x**6 + 12*x**4 + 8*x**2)
|
||||
g = (4 + 8*x**2 + 6*x + 3*x**3)/(x**5 + 4*x**3 + 4*x) + log(x)
|
||||
|
||||
assert drop_const(ratsimp(heurisch(f, x)), x) == g
|
||||
|
||||
|
||||
def test_pmint_trig():
|
||||
f = (x - tan(x)) / tan(x)**2 + tan(x)
|
||||
g = -x**2/2 - x/tan(x) + log(tan(x)**2 + 1)/2
|
||||
|
||||
assert heurisch(f, x) == g
|
||||
|
||||
|
||||
def test_pmint_logexp():
|
||||
f = (1 + x + x*exp(x))*(x + log(x) + exp(x) - 1)/(x + log(x) + exp(x))**2/x
|
||||
g = log(x + exp(x) + log(x)) + 1/(x + exp(x) + log(x))
|
||||
|
||||
assert ratsimp(heurisch(f, x)) == g
|
||||
|
||||
|
||||
def test_pmint_erf():
|
||||
f = exp(-x**2)*erf(x)/(erf(x)**3 - erf(x)**2 - erf(x) + 1)
|
||||
g = sqrt(pi)*log(erf(x) - 1)/8 - sqrt(pi)*log(erf(x) + 1)/8 - sqrt(pi)/(4*erf(x) - 4)
|
||||
|
||||
assert ratsimp(heurisch(f, x)) == g
|
||||
|
||||
|
||||
def test_pmint_LambertW():
|
||||
f = LambertW(x)
|
||||
g = x*LambertW(x) - x + x/LambertW(x)
|
||||
|
||||
assert heurisch(f, x) == g
|
||||
|
||||
|
||||
def test_pmint_besselj():
|
||||
f = besselj(nu + 1, x)/besselj(nu, x)
|
||||
g = nu*log(x) - log(besselj(nu, x))
|
||||
|
||||
assert heurisch(f, x) == g
|
||||
|
||||
f = (nu*besselj(nu, x) - x*besselj(nu + 1, x))/x
|
||||
g = besselj(nu, x)
|
||||
|
||||
assert heurisch(f, x) == g
|
||||
|
||||
f = jn(nu + 1, x)/jn(nu, x)
|
||||
g = nu*log(x) - log(jn(nu, x))
|
||||
|
||||
assert heurisch(f, x) == g
|
||||
|
||||
|
||||
@slow
|
||||
def test_pmint_bessel_products():
|
||||
f = x*besselj(nu, x)*bessely(nu, 2*x)
|
||||
g = -2*x*besselj(nu, x)*bessely(nu - 1, 2*x)/3 + x*besselj(nu - 1, x)*bessely(nu, 2*x)/3
|
||||
|
||||
assert heurisch(f, x) == g
|
||||
|
||||
f = x*besselj(nu, x)*besselk(nu, 2*x)
|
||||
g = -2*x*besselj(nu, x)*besselk(nu - 1, 2*x)/5 - x*besselj(nu - 1, x)*besselk(nu, 2*x)/5
|
||||
|
||||
assert heurisch(f, x) == g
|
||||
|
||||
|
||||
def test_pmint_WrightOmega():
|
||||
def omega(x):
|
||||
return LambertW(exp(x))
|
||||
|
||||
f = (1 + omega(x) * (2 + cos(omega(x)) * (x + omega(x))))/(1 + omega(x))/(x + omega(x))
|
||||
g = log(x + LambertW(exp(x))) + sin(LambertW(exp(x)))
|
||||
|
||||
assert heurisch(f, x) == g
|
||||
|
||||
|
||||
def test_RR():
|
||||
# Make sure the algorithm does the right thing if the ring is RR. See
|
||||
# issue 8685.
|
||||
assert heurisch(sqrt(1 + 0.25*x**2), x, hints=[]) == \
|
||||
0.5*x*sqrt(0.25*x**2 + 1) + 1.0*asinh(0.5*x)
|
||||
|
||||
# TODO: convert the rest of PMINT tests:
|
||||
# Airy functions
|
||||
# f = (x - AiryAi(x)*AiryAi(1, x)) / (x**2 - AiryAi(x)**2)
|
||||
# g = Rational(1,2)*ln(x + AiryAi(x)) + Rational(1,2)*ln(x - AiryAi(x))
|
||||
# f = x**2 * AiryAi(x)
|
||||
# g = -AiryAi(x) + AiryAi(1, x)*x
|
||||
# Whittaker functions
|
||||
# f = WhittakerW(mu + 1, nu, x) / (WhittakerW(mu, nu, x) * x)
|
||||
# g = x/2 - mu*ln(x) - ln(WhittakerW(mu, nu, x))
|
||||
|
||||
|
||||
def test_issue_22527():
|
||||
t, R = symbols(r't R')
|
||||
z = Function('z')(t)
|
||||
def f(x):
|
||||
return x/sqrt(R**2 - x**2)
|
||||
Uz = integrate(f(z), z)
|
||||
Ut = integrate(f(t), t)
|
||||
assert Ut == Uz.subs(z, t)
|
||||
|
||||
|
||||
def test_heurisch_complex_erf_issue_26338():
|
||||
r = symbols('r', real=True)
|
||||
a = sqrt(pi)*erf((1 + I)/2)/2
|
||||
assert integrate(exp(-I*r**2/2), (r, 0, 1)) == a - I*a
|
||||
|
||||
a = exp(-x**2/(2*(2 - I)**2))
|
||||
assert heurisch(a, x, hints=[]) is None # None, not a wrong soln
|
||||
a = exp(-r**2/(2*(2 - I)**2))
|
||||
assert heurisch(a, r, hints=[]) is None
|
||||
a = sqrt(pi)*erf((1 + I)/2)/2
|
||||
assert integrate(exp(-I*x**2/2), (x, 0, 1)) == a - I*a
|
||||
|
||||
|
||||
def test_issue_15498():
|
||||
Z0 = Function('Z0')
|
||||
k01, k10, t, s= symbols('k01 k10 t s', real=True, positive=True)
|
||||
m = Matrix([[exp(-k10*t)]])
|
||||
_83 = Rational(83, 100) # 0.83 works, too
|
||||
[a, b, c, d, e, f, g] = [100, 0.5, _83, 50, 0.6, 2, 120]
|
||||
AIF_btf = a*(d*e*(1 - exp(-(t - b)/e)) + f*g*(1 - exp(-(t - b)/g)))
|
||||
AIF_atf = a*(d*e*exp(-(t - b)/e)*(exp((c - b)/e) - 1
|
||||
) + f*g*exp(-(t - b)/g)*(exp((c - b)/g) - 1))
|
||||
AIF_sym = Piecewise((0, t < b), (AIF_btf, And(b <= t, t < c)), (AIF_atf, c <= t))
|
||||
aif_eq = Eq(Z0(t), AIF_sym)
|
||||
f_vec = Matrix([[k01*Z0(t)]])
|
||||
integrand = m*m.subs(t, s)**-1*f_vec.subs(aif_eq.lhs, aif_eq.rhs).subs(t, s)
|
||||
solution = integrate(integrand[0], (s, 0, t))
|
||||
assert solution is not None # does not hang and takes less than 10 s
|
||||
|
||||
|
||||
@slow
|
||||
def test_heurisch_issue_26930():
|
||||
integrand = x**Rational(4, 3)*log(x)
|
||||
anti = 3*x**(S(7)/3)*log(x)/7 - 9*x**(S(7)/3)/49
|
||||
assert heurisch(integrand, x) == anti
|
||||
assert integrate(integrand, x) == anti
|
||||
assert integrate(integrand, (x, 0, 1)) == -S(9)/49
|
||||
|
||||
|
||||
def test_heurisch_issue_26922():
|
||||
|
||||
a, b, x = symbols("a, b, x", real=True, positive=True)
|
||||
C = symbols("C", real=True)
|
||||
i1 = -C*x*exp(-a*x**2 - sqrt(b)*x)
|
||||
i2 = C*x*exp(-a*x**2 + sqrt(b)*x)
|
||||
i = Integral(i1, x) + Integral(i2, x)
|
||||
res = (
|
||||
-C*exp(-a*x**2)*exp(sqrt(b)*x)/(2*a)
|
||||
+ C*exp(-a*x**2)*exp(-sqrt(b)*x)/(2*a)
|
||||
+ sqrt(pi)*C*sqrt(b)*exp(b/(4*a))*erf(sqrt(a)*x - sqrt(b)/(2*sqrt(a)))/(4*a**(S(3)/2))
|
||||
+ sqrt(pi)*C*sqrt(b)*exp(b/(4*a))*erf(sqrt(a)*x + sqrt(b)/(2*sqrt(a)))/(4*a**(S(3)/2))
|
||||
)
|
||||
|
||||
assert i.doit(heurisch=False).expand() == res
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,627 @@
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
|
||||
from sympy.core import S, Rational
|
||||
|
||||
from sympy.integrals.intpoly import (decompose, best_origin, distance_to_side,
|
||||
polytope_integrate, point_sort,
|
||||
hyperplane_parameters, main_integrate3d,
|
||||
main_integrate, polygon_integrate,
|
||||
lineseg_integrate, integration_reduction,
|
||||
integration_reduction_dynamic, is_vertex)
|
||||
|
||||
from sympy.geometry.line import Segment2D
|
||||
from sympy.geometry.polygon import Polygon
|
||||
from sympy.geometry.point import Point, Point2D
|
||||
from sympy.abc import x, y, z
|
||||
|
||||
from sympy.testing.pytest import slow
|
||||
|
||||
|
||||
def test_decompose():
|
||||
assert decompose(x) == {1: x}
|
||||
assert decompose(x**2) == {2: x**2}
|
||||
assert decompose(x*y) == {2: x*y}
|
||||
assert decompose(x + y) == {1: x + y}
|
||||
assert decompose(x**2 + y) == {1: y, 2: x**2}
|
||||
assert decompose(8*x**2 + 4*y + 7) == {0: 7, 1: 4*y, 2: 8*x**2}
|
||||
assert decompose(x**2 + 3*y*x) == {2: x**2 + 3*x*y}
|
||||
assert decompose(9*x**2 + y + 4*x + x**3 + y**2*x + 3) ==\
|
||||
{0: 3, 1: 4*x + y, 2: 9*x**2, 3: x**3 + x*y**2}
|
||||
|
||||
assert decompose(x, True) == {x}
|
||||
assert decompose(x ** 2, True) == {x**2}
|
||||
assert decompose(x * y, True) == {x * y}
|
||||
assert decompose(x + y, True) == {x, y}
|
||||
assert decompose(x ** 2 + y, True) == {y, x ** 2}
|
||||
assert decompose(8 * x ** 2 + 4 * y + 7, True) == {7, 4*y, 8*x**2}
|
||||
assert decompose(x ** 2 + 3 * y * x, True) == {x ** 2, 3 * x * y}
|
||||
assert decompose(9 * x ** 2 + y + 4 * x + x ** 3 + y ** 2 * x + 3, True) == \
|
||||
{3, y, 4*x, 9*x**2, x*y**2, x**3}
|
||||
|
||||
|
||||
def test_best_origin():
|
||||
expr1 = y ** 2 * x ** 5 + y ** 5 * x ** 7 + 7 * x + x ** 12 + y ** 7 * x
|
||||
|
||||
l1 = Segment2D(Point(0, 3), Point(1, 1))
|
||||
l2 = Segment2D(Point(S(3) / 2, 0), Point(S(3) / 2, 3))
|
||||
l3 = Segment2D(Point(0, S(3) / 2), Point(3, S(3) / 2))
|
||||
l4 = Segment2D(Point(0, 2), Point(2, 0))
|
||||
l5 = Segment2D(Point(0, 2), Point(1, 1))
|
||||
l6 = Segment2D(Point(2, 0), Point(1, 1))
|
||||
|
||||
assert best_origin((2, 1), 3, l1, expr1) == (0, 3)
|
||||
# XXX: Should these return exact Rational output? Maybe best_origin should
|
||||
# sympify its arguments...
|
||||
assert best_origin((2, 0), 3, l2, x ** 7) == (1.5, 0)
|
||||
assert best_origin((0, 2), 3, l3, x ** 7) == (0, 1.5)
|
||||
assert best_origin((1, 1), 2, l4, x ** 7 * y ** 3) == (0, 2)
|
||||
assert best_origin((1, 1), 2, l4, x ** 3 * y ** 7) == (2, 0)
|
||||
assert best_origin((1, 1), 2, l5, x ** 2 * y ** 9) == (0, 2)
|
||||
assert best_origin((1, 1), 2, l6, x ** 9 * y ** 2) == (2, 0)
|
||||
|
||||
|
||||
@slow
|
||||
def test_polytope_integrate():
|
||||
# Convex 2-Polytopes
|
||||
# Vertex representation
|
||||
assert polytope_integrate(Polygon(Point(0, 0), Point(0, 2),
|
||||
Point(4, 0)), 1) == 4
|
||||
assert polytope_integrate(Polygon(Point(0, 0), Point(0, 1),
|
||||
Point(1, 1), Point(1, 0)), x * y) ==\
|
||||
Rational(1, 4)
|
||||
assert polytope_integrate(Polygon(Point(0, 3), Point(5, 3), Point(1, 1)),
|
||||
6*x**2 - 40*y) == Rational(-935, 3)
|
||||
|
||||
assert polytope_integrate(Polygon(Point(0, 0), Point(0, sqrt(3)),
|
||||
Point(sqrt(3), sqrt(3)),
|
||||
Point(sqrt(3), 0)), 1) == 3
|
||||
|
||||
hexagon = Polygon(Point(0, 0), Point(-sqrt(3) / 2, S.Half),
|
||||
Point(-sqrt(3) / 2, S(3) / 2), Point(0, 2),
|
||||
Point(sqrt(3) / 2, S(3) / 2), Point(sqrt(3) / 2, S.Half))
|
||||
|
||||
assert polytope_integrate(hexagon, 1) == S(3*sqrt(3)) / 2
|
||||
|
||||
# Hyperplane representation
|
||||
assert polytope_integrate([((-1, 0), 0), ((1, 2), 4),
|
||||
((0, -1), 0)], 1) == 4
|
||||
assert polytope_integrate([((-1, 0), 0), ((0, 1), 1),
|
||||
((1, 0), 1), ((0, -1), 0)], x * y) == Rational(1, 4)
|
||||
assert polytope_integrate([((0, 1), 3), ((1, -2), -1),
|
||||
((-2, -1), -3)], 6*x**2 - 40*y) == Rational(-935, 3)
|
||||
assert polytope_integrate([((-1, 0), 0), ((0, sqrt(3)), 3),
|
||||
((sqrt(3), 0), 3), ((0, -1), 0)], 1) == 3
|
||||
|
||||
hexagon = [((Rational(-1, 2), -sqrt(3) / 2), 0),
|
||||
((-1, 0), sqrt(3) / 2),
|
||||
((Rational(-1, 2), sqrt(3) / 2), sqrt(3)),
|
||||
((S.Half, sqrt(3) / 2), sqrt(3)),
|
||||
((1, 0), sqrt(3) / 2),
|
||||
((S.Half, -sqrt(3) / 2), 0)]
|
||||
assert polytope_integrate(hexagon, 1) == S(3*sqrt(3)) / 2
|
||||
|
||||
# Non-convex polytopes
|
||||
# Vertex representation
|
||||
assert polytope_integrate(Polygon(Point(-1, -1), Point(-1, 1),
|
||||
Point(1, 1), Point(0, 0),
|
||||
Point(1, -1)), 1) == 3
|
||||
assert polytope_integrate(Polygon(Point(-1, -1), Point(-1, 1),
|
||||
Point(0, 0), Point(1, 1),
|
||||
Point(1, -1), Point(0, 0)), 1) == 2
|
||||
# Hyperplane representation
|
||||
assert polytope_integrate([((-1, 0), 1), ((0, 1), 1), ((1, -1), 0),
|
||||
((1, 1), 0), ((0, -1), 1)], 1) == 3
|
||||
assert polytope_integrate([((-1, 0), 1), ((1, 1), 0), ((-1, 1), 0),
|
||||
((1, 0), 1), ((-1, -1), 0),
|
||||
((1, -1), 0)], 1) == 2
|
||||
|
||||
# Tests for 2D polytopes mentioned in Chin et al(Page 10):
|
||||
# http://dilbert.engr.ucdavis.edu/~suku/quadrature/cls-integration.pdf
|
||||
fig1 = Polygon(Point(1.220, -0.827), Point(-1.490, -4.503),
|
||||
Point(-3.766, -1.622), Point(-4.240, -0.091),
|
||||
Point(-3.160, 4), Point(-0.981, 4.447),
|
||||
Point(0.132, 4.027))
|
||||
assert polytope_integrate(fig1, x**2 + x*y + y**2) ==\
|
||||
S(2031627344735367)/(8*10**12)
|
||||
|
||||
fig2 = Polygon(Point(4.561, 2.317), Point(1.491, -1.315),
|
||||
Point(-3.310, -3.164), Point(-4.845, -3.110),
|
||||
Point(-4.569, 1.867))
|
||||
assert polytope_integrate(fig2, x**2 + x*y + y**2) ==\
|
||||
S(517091313866043)/(16*10**11)
|
||||
|
||||
fig3 = Polygon(Point(-2.740, -1.888), Point(-3.292, 4.233),
|
||||
Point(-2.723, -0.697), Point(-0.643, -3.151))
|
||||
assert polytope_integrate(fig3, x**2 + x*y + y**2) ==\
|
||||
S(147449361647041)/(8*10**12)
|
||||
|
||||
fig4 = Polygon(Point(0.211, -4.622), Point(-2.684, 3.851),
|
||||
Point(0.468, 4.879), Point(4.630, -1.325),
|
||||
Point(-0.411, -1.044))
|
||||
assert polytope_integrate(fig4, x**2 + x*y + y**2) ==\
|
||||
S(180742845225803)/(10**12)
|
||||
|
||||
# Tests for many polynomials with maximum degree given(2D case).
|
||||
tri = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))
|
||||
polys = []
|
||||
expr1 = x**9*y + x**7*y**3 + 2*x**2*y**8
|
||||
expr2 = x**6*y**4 + x**5*y**5 + 2*y**10
|
||||
expr3 = x**10 + x**9*y + x**8*y**2 + x**5*y**5
|
||||
polys.extend((expr1, expr2, expr3))
|
||||
result_dict = polytope_integrate(tri, polys, max_degree=10)
|
||||
assert result_dict[expr1] == Rational(615780107, 594)
|
||||
assert result_dict[expr2] == Rational(13062161, 27)
|
||||
assert result_dict[expr3] == Rational(1946257153, 924)
|
||||
|
||||
tri = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))
|
||||
expr1 = x**7*y**1 + 2*x**2*y**6
|
||||
expr2 = x**6*y**4 + x**5*y**5 + 2*y**10
|
||||
expr3 = x**10 + x**9*y + x**8*y**2 + x**5*y**5
|
||||
polys.extend((expr1, expr2, expr3))
|
||||
assert polytope_integrate(tri, polys, max_degree=9) == \
|
||||
{x**7*y + 2*x**2*y**6: Rational(489262, 9)}
|
||||
|
||||
# Tests when all integral of all monomials up to a max_degree is to be
|
||||
# calculated.
|
||||
assert polytope_integrate(Polygon(Point(0, 0), Point(0, 1),
|
||||
Point(1, 1), Point(1, 0)),
|
||||
max_degree=4) == {0: 0, 1: 1, x: S.Half,
|
||||
x ** 2 * y ** 2: S.One / 9,
|
||||
x ** 4: S.One / 5,
|
||||
y ** 4: S.One / 5,
|
||||
y: S.Half,
|
||||
x * y ** 2: S.One / 6,
|
||||
y ** 2: S.One / 3,
|
||||
x ** 3: S.One / 4,
|
||||
x ** 2 * y: S.One / 6,
|
||||
x ** 3 * y: S.One / 8,
|
||||
x * y: S.One / 4,
|
||||
y ** 3: S.One / 4,
|
||||
x ** 2: S.One / 3,
|
||||
x * y ** 3: S.One / 8}
|
||||
|
||||
# Tests for 3D polytopes
|
||||
cube1 = [[(0, 0, 0), (0, 6, 6), (6, 6, 6), (3, 6, 0),
|
||||
(0, 6, 0), (6, 0, 6), (3, 0, 0), (0, 0, 6)],
|
||||
[1, 2, 3, 4], [3, 2, 5, 6], [1, 7, 5, 2], [0, 6, 5, 7],
|
||||
[1, 4, 0, 7], [0, 4, 3, 6]]
|
||||
assert polytope_integrate(cube1, 1) == S(162)
|
||||
|
||||
# 3D Test cases in Chin et al(2015)
|
||||
cube2 = [[(0, 0, 0), (0, 0, 5), (0, 5, 0), (0, 5, 5), (5, 0, 0),
|
||||
(5, 0, 5), (5, 5, 0), (5, 5, 5)],
|
||||
[3, 7, 6, 2], [1, 5, 7, 3], [5, 4, 6, 7], [0, 4, 5, 1],
|
||||
[2, 0, 1, 3], [2, 6, 4, 0]]
|
||||
|
||||
cube3 = [[(0, 0, 0), (5, 0, 0), (5, 4, 0), (3, 2, 0), (3, 5, 0),
|
||||
(0, 5, 0), (0, 0, 5), (5, 0, 5), (5, 4, 5), (3, 2, 5),
|
||||
(3, 5, 5), (0, 5, 5)],
|
||||
[6, 11, 5, 0], [1, 7, 6, 0], [5, 4, 3, 2, 1, 0], [11, 10, 4, 5],
|
||||
[10, 9, 3, 4], [9, 8, 2, 3], [8, 7, 1, 2], [7, 8, 9, 10, 11, 6]]
|
||||
|
||||
cube4 = [[(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1),
|
||||
(S.One / 4, S.One / 4, S.One / 4)],
|
||||
[0, 2, 1], [1, 3, 0], [4, 2, 3], [4, 3, 1],
|
||||
[0, 1, 2], [2, 4, 1], [0, 3, 2]]
|
||||
|
||||
assert polytope_integrate(cube2, x ** 2 + y ** 2 + x * y + z ** 2) ==\
|
||||
Rational(15625, 4)
|
||||
assert polytope_integrate(cube3, x ** 2 + y ** 2 + x * y + z ** 2) ==\
|
||||
S(33835) / 12
|
||||
assert polytope_integrate(cube4, x ** 2 + y ** 2 + x * y + z ** 2) ==\
|
||||
S(37) / 960
|
||||
|
||||
# Test cases from Mathematica's PolyhedronData library
|
||||
octahedron = [[(S.NegativeOne / sqrt(2), 0, 0), (0, S.One / sqrt(2), 0),
|
||||
(0, 0, S.NegativeOne / sqrt(2)), (0, 0, S.One / sqrt(2)),
|
||||
(0, S.NegativeOne / sqrt(2), 0), (S.One / sqrt(2), 0, 0)],
|
||||
[3, 4, 5], [3, 5, 1], [3, 1, 0], [3, 0, 4], [4, 0, 2],
|
||||
[4, 2, 5], [2, 0, 1], [5, 2, 1]]
|
||||
|
||||
assert polytope_integrate(octahedron, 1) == sqrt(2) / 3
|
||||
|
||||
great_stellated_dodecahedron =\
|
||||
[[(-0.32491969623290634095, 0, 0.42532540417601993887),
|
||||
(0.32491969623290634095, 0, -0.42532540417601993887),
|
||||
(-0.52573111211913359231, 0, 0.10040570794311363956),
|
||||
(0.52573111211913359231, 0, -0.10040570794311363956),
|
||||
(-0.10040570794311363956, -0.3090169943749474241, 0.42532540417601993887),
|
||||
(-0.10040570794311363956, 0.30901699437494742410, 0.42532540417601993887),
|
||||
(0.10040570794311363956, -0.3090169943749474241, -0.42532540417601993887),
|
||||
(0.10040570794311363956, 0.30901699437494742410, -0.42532540417601993887),
|
||||
(-0.16245984811645317047, -0.5, 0.10040570794311363956),
|
||||
(-0.16245984811645317047, 0.5, 0.10040570794311363956),
|
||||
(0.16245984811645317047, -0.5, -0.10040570794311363956),
|
||||
(0.16245984811645317047, 0.5, -0.10040570794311363956),
|
||||
(-0.42532540417601993887, -0.3090169943749474241, -0.10040570794311363956),
|
||||
(-0.42532540417601993887, 0.30901699437494742410, -0.10040570794311363956),
|
||||
(-0.26286555605956679615, 0.1909830056250525759, -0.42532540417601993887),
|
||||
(-0.26286555605956679615, -0.1909830056250525759, -0.42532540417601993887),
|
||||
(0.26286555605956679615, 0.1909830056250525759, 0.42532540417601993887),
|
||||
(0.26286555605956679615, -0.1909830056250525759, 0.42532540417601993887),
|
||||
(0.42532540417601993887, -0.3090169943749474241, 0.10040570794311363956),
|
||||
(0.42532540417601993887, 0.30901699437494742410, 0.10040570794311363956)],
|
||||
[12, 3, 0, 6, 16], [17, 7, 0, 3, 13],
|
||||
[9, 6, 0, 7, 8], [18, 2, 1, 4, 14],
|
||||
[15, 5, 1, 2, 19], [11, 4, 1, 5, 10],
|
||||
[8, 19, 2, 18, 9], [10, 13, 3, 12, 11],
|
||||
[16, 14, 4, 11, 12], [13, 10, 5, 15, 17],
|
||||
[14, 16, 6, 9, 18], [19, 8, 7, 17, 15]]
|
||||
# Actual volume is : 0.163118960624632
|
||||
assert Abs(polytope_integrate(great_stellated_dodecahedron, 1) -\
|
||||
0.163118960624632) < 1e-12
|
||||
|
||||
expr = x **2 + y ** 2 + z ** 2
|
||||
octahedron_five_compound = [[(0, -0.7071067811865475244, 0),
|
||||
(0, 0.70710678118654752440, 0),
|
||||
(0.1148764602736805918,
|
||||
-0.35355339059327376220, -0.60150095500754567366),
|
||||
(0.1148764602736805918, 0.35355339059327376220,
|
||||
-0.60150095500754567366),
|
||||
(0.18587401723009224507,
|
||||
-0.57206140281768429760, 0.37174803446018449013),
|
||||
(0.18587401723009224507, 0.57206140281768429760,
|
||||
0.37174803446018449013),
|
||||
(0.30075047750377283683, -0.21850801222441053540,
|
||||
0.60150095500754567366),
|
||||
(0.30075047750377283683, 0.21850801222441053540,
|
||||
0.60150095500754567366),
|
||||
(0.48662449473386508189, -0.35355339059327376220,
|
||||
-0.37174803446018449013),
|
||||
(0.48662449473386508189, 0.35355339059327376220,
|
||||
-0.37174803446018449013),
|
||||
(-0.60150095500754567366, 0, -0.37174803446018449013),
|
||||
(-0.30075047750377283683, -0.21850801222441053540,
|
||||
-0.60150095500754567366),
|
||||
(-0.30075047750377283683, 0.21850801222441053540,
|
||||
-0.60150095500754567366),
|
||||
(0.60150095500754567366, 0, 0.37174803446018449013),
|
||||
(0.4156269377774534286, -0.57206140281768429760, 0),
|
||||
(0.4156269377774534286, 0.57206140281768429760, 0),
|
||||
(0.37174803446018449013, 0, -0.60150095500754567366),
|
||||
(-0.4156269377774534286, -0.57206140281768429760, 0),
|
||||
(-0.4156269377774534286, 0.57206140281768429760, 0),
|
||||
(-0.67249851196395732696, -0.21850801222441053540, 0),
|
||||
(-0.67249851196395732696, 0.21850801222441053540, 0),
|
||||
(0.67249851196395732696, -0.21850801222441053540, 0),
|
||||
(0.67249851196395732696, 0.21850801222441053540, 0),
|
||||
(-0.37174803446018449013, 0, 0.60150095500754567366),
|
||||
(-0.48662449473386508189, -0.35355339059327376220,
|
||||
0.37174803446018449013),
|
||||
(-0.48662449473386508189, 0.35355339059327376220,
|
||||
0.37174803446018449013),
|
||||
(-0.18587401723009224507, -0.57206140281768429760,
|
||||
-0.37174803446018449013),
|
||||
(-0.18587401723009224507, 0.57206140281768429760,
|
||||
-0.37174803446018449013),
|
||||
(-0.11487646027368059176, -0.35355339059327376220,
|
||||
0.60150095500754567366),
|
||||
(-0.11487646027368059176, 0.35355339059327376220,
|
||||
0.60150095500754567366)],
|
||||
[0, 10, 16], [23, 10, 0], [16, 13, 0],
|
||||
[0, 13, 23], [16, 10, 1], [1, 10, 23],
|
||||
[1, 13, 16], [23, 13, 1], [2, 4, 19],
|
||||
[22, 4, 2], [2, 19, 27], [27, 22, 2],
|
||||
[20, 5, 3], [3, 5, 21], [26, 20, 3],
|
||||
[3, 21, 26], [29, 19, 4], [4, 22, 29],
|
||||
[5, 20, 28], [28, 21, 5], [6, 8, 15],
|
||||
[17, 8, 6], [6, 15, 25], [25, 17, 6],
|
||||
[14, 9, 7], [7, 9, 18], [24, 14, 7],
|
||||
[7, 18, 24], [8, 12, 15], [17, 12, 8],
|
||||
[14, 11, 9], [9, 11, 18], [11, 14, 24],
|
||||
[24, 18, 11], [25, 15, 12], [12, 17, 25],
|
||||
[29, 27, 19], [20, 26, 28], [28, 26, 21],
|
||||
[22, 27, 29]]
|
||||
assert Abs(polytope_integrate(octahedron_five_compound, expr)) - 0.353553\
|
||||
< 1e-6
|
||||
|
||||
cube_five_compound = [[(-0.1624598481164531631, -0.5, -0.6881909602355867691),
|
||||
(-0.1624598481164531631, 0.5, -0.6881909602355867691),
|
||||
(0.1624598481164531631, -0.5, 0.68819096023558676910),
|
||||
(0.1624598481164531631, 0.5, 0.68819096023558676910),
|
||||
(-0.52573111211913359231, 0, -0.6881909602355867691),
|
||||
(0.52573111211913359231, 0, 0.68819096023558676910),
|
||||
(-0.26286555605956679615, -0.8090169943749474241,
|
||||
-0.1624598481164531631),
|
||||
(-0.26286555605956679615, 0.8090169943749474241,
|
||||
-0.1624598481164531631),
|
||||
(0.26286555605956680301, -0.8090169943749474241,
|
||||
0.1624598481164531631),
|
||||
(0.26286555605956680301, 0.8090169943749474241,
|
||||
0.1624598481164531631),
|
||||
(-0.42532540417601993887, -0.3090169943749474241,
|
||||
0.68819096023558676910),
|
||||
(-0.42532540417601993887, 0.30901699437494742410,
|
||||
0.68819096023558676910),
|
||||
(0.42532540417601996609, -0.3090169943749474241,
|
||||
-0.6881909602355867691),
|
||||
(0.42532540417601996609, 0.30901699437494742410,
|
||||
-0.6881909602355867691),
|
||||
(-0.6881909602355867691, -0.5, 0.1624598481164531631),
|
||||
(-0.6881909602355867691, 0.5, 0.1624598481164531631),
|
||||
(0.68819096023558676910, -0.5, -0.1624598481164531631),
|
||||
(0.68819096023558676910, 0.5, -0.1624598481164531631),
|
||||
(-0.85065080835203998877, 0, -0.1624598481164531631),
|
||||
(0.85065080835203993218, 0, 0.1624598481164531631)],
|
||||
[18, 10, 3, 7], [13, 19, 8, 0], [18, 0, 8, 10],
|
||||
[3, 19, 13, 7], [18, 7, 13, 0], [8, 19, 3, 10],
|
||||
[6, 2, 11, 18], [1, 9, 19, 12], [11, 9, 1, 18],
|
||||
[6, 12, 19, 2], [1, 12, 6, 18], [11, 2, 19, 9],
|
||||
[4, 14, 11, 7], [17, 5, 8, 12], [4, 12, 8, 14],
|
||||
[11, 5, 17, 7], [4, 7, 17, 12], [8, 5, 11, 14],
|
||||
[6, 10, 15, 4], [13, 9, 5, 16], [15, 9, 13, 4],
|
||||
[6, 16, 5, 10], [13, 16, 6, 4], [15, 10, 5, 9],
|
||||
[14, 15, 1, 0], [16, 17, 3, 2], [14, 2, 3, 15],
|
||||
[1, 17, 16, 0], [14, 0, 16, 2], [3, 17, 1, 15]]
|
||||
assert Abs(polytope_integrate(cube_five_compound, expr) - 1.25) < 1e-12
|
||||
|
||||
echidnahedron = [[(0, 0, -2.4898982848827801995),
|
||||
(0, 0, 2.4898982848827802734),
|
||||
(0, -4.2360679774997896964, -2.4898982848827801995),
|
||||
(0, -4.2360679774997896964, 2.4898982848827802734),
|
||||
(0, 4.2360679774997896964, -2.4898982848827801995),
|
||||
(0, 4.2360679774997896964, 2.4898982848827802734),
|
||||
(-4.0287400534704067567, -1.3090169943749474241, -2.4898982848827801995),
|
||||
(-4.0287400534704067567, -1.3090169943749474241, 2.4898982848827802734),
|
||||
(-4.0287400534704067567, 1.3090169943749474241, -2.4898982848827801995),
|
||||
(-4.0287400534704067567, 1.3090169943749474241, 2.4898982848827802734),
|
||||
(4.0287400534704069747, -1.3090169943749474241, -2.4898982848827801995),
|
||||
(4.0287400534704069747, -1.3090169943749474241, 2.4898982848827802734),
|
||||
(4.0287400534704069747, 1.3090169943749474241, -2.4898982848827801995),
|
||||
(4.0287400534704069747, 1.3090169943749474241, 2.4898982848827802734),
|
||||
(-2.4898982848827801995, -3.4270509831248422723, -2.4898982848827801995),
|
||||
(-2.4898982848827801995, -3.4270509831248422723, 2.4898982848827802734),
|
||||
(-2.4898982848827801995, 3.4270509831248422723, -2.4898982848827801995),
|
||||
(-2.4898982848827801995, 3.4270509831248422723, 2.4898982848827802734),
|
||||
(2.4898982848827802734, -3.4270509831248422723, -2.4898982848827801995),
|
||||
(2.4898982848827802734, -3.4270509831248422723, 2.4898982848827802734),
|
||||
(2.4898982848827802734, 3.4270509831248422723, -2.4898982848827801995),
|
||||
(2.4898982848827802734, 3.4270509831248422723, 2.4898982848827802734),
|
||||
(-4.7169310137059934362, -0.8090169943749474241, -1.1135163644116066184),
|
||||
(-4.7169310137059934362, 0.8090169943749474241, -1.1135163644116066184),
|
||||
(4.7169310137059937438, -0.8090169943749474241, 1.11351636441160673519),
|
||||
(4.7169310137059937438, 0.8090169943749474241, 1.11351636441160673519),
|
||||
(-4.2916056095299737777, -2.1180339887498948482, 1.11351636441160673519),
|
||||
(-4.2916056095299737777, 2.1180339887498948482, 1.11351636441160673519),
|
||||
(4.2916056095299737777, -2.1180339887498948482, -1.1135163644116066184),
|
||||
(4.2916056095299737777, 2.1180339887498948482, -1.1135163644116066184),
|
||||
(-3.6034146492943870399, 0, -3.3405490932348205213),
|
||||
(3.6034146492943870399, 0, 3.3405490932348202056),
|
||||
(-3.3405490932348205213, -3.4270509831248422723, 1.11351636441160673519),
|
||||
(-3.3405490932348205213, 3.4270509831248422723, 1.11351636441160673519),
|
||||
(3.3405490932348202056, -3.4270509831248422723, -1.1135163644116066184),
|
||||
(3.3405490932348202056, 3.4270509831248422723, -1.1135163644116066184),
|
||||
(-2.9152236890588002395, -2.1180339887498948482, 3.3405490932348202056),
|
||||
(-2.9152236890588002395, 2.1180339887498948482, 3.3405490932348202056),
|
||||
(2.9152236890588002395, -2.1180339887498948482, -3.3405490932348205213),
|
||||
(2.9152236890588002395, 2.1180339887498948482, -3.3405490932348205213),
|
||||
(-2.2270327288232132368, 0, -1.1135163644116066184),
|
||||
(-2.2270327288232132368, -4.2360679774997896964, -1.1135163644116066184),
|
||||
(-2.2270327288232132368, 4.2360679774997896964, -1.1135163644116066184),
|
||||
(2.2270327288232134704, 0, 1.11351636441160673519),
|
||||
(2.2270327288232134704, -4.2360679774997896964, 1.11351636441160673519),
|
||||
(2.2270327288232134704, 4.2360679774997896964, 1.11351636441160673519),
|
||||
(-1.8017073246471935200, -1.3090169943749474241, 1.11351636441160673519),
|
||||
(-1.8017073246471935200, 1.3090169943749474241, 1.11351636441160673519),
|
||||
(1.8017073246471935043, -1.3090169943749474241, -1.1135163644116066184),
|
||||
(1.8017073246471935043, 1.3090169943749474241, -1.1135163644116066184),
|
||||
(-1.3763819204711735382, 0, -4.7169310137059934362),
|
||||
(-1.3763819204711735382, 0, 0.26286555605956679615),
|
||||
(1.37638192047117353821, 0, 4.7169310137059937438),
|
||||
(1.37638192047117353821, 0, -0.26286555605956679615),
|
||||
(-1.1135163644116066184, -3.4270509831248422723, -3.3405490932348205213),
|
||||
(-1.1135163644116066184, -0.8090169943749474241, 4.7169310137059937438),
|
||||
(-1.1135163644116066184, -0.8090169943749474241, -0.26286555605956679615),
|
||||
(-1.1135163644116066184, 0.8090169943749474241, 4.7169310137059937438),
|
||||
(-1.1135163644116066184, 0.8090169943749474241, -0.26286555605956679615),
|
||||
(-1.1135163644116066184, 3.4270509831248422723, -3.3405490932348205213),
|
||||
(1.11351636441160673519, -3.4270509831248422723, 3.3405490932348202056),
|
||||
(1.11351636441160673519, -0.8090169943749474241, -4.7169310137059934362),
|
||||
(1.11351636441160673519, -0.8090169943749474241, 0.26286555605956679615),
|
||||
(1.11351636441160673519, 0.8090169943749474241, -4.7169310137059934362),
|
||||
(1.11351636441160673519, 0.8090169943749474241, 0.26286555605956679615),
|
||||
(1.11351636441160673519, 3.4270509831248422723, 3.3405490932348202056),
|
||||
(-0.85065080835203998877, 0, 1.11351636441160673519),
|
||||
(0.85065080835203993218, 0, -1.1135163644116066184),
|
||||
(-0.6881909602355867691, -0.5, -1.1135163644116066184),
|
||||
(-0.6881909602355867691, 0.5, -1.1135163644116066184),
|
||||
(-0.6881909602355867691, -4.7360679774997896964, -1.1135163644116066184),
|
||||
(-0.6881909602355867691, -2.1180339887498948482, -1.1135163644116066184),
|
||||
(-0.6881909602355867691, 2.1180339887498948482, -1.1135163644116066184),
|
||||
(-0.6881909602355867691, 4.7360679774997896964, -1.1135163644116066184),
|
||||
(0.68819096023558676910, -0.5, 1.11351636441160673519),
|
||||
(0.68819096023558676910, 0.5, 1.11351636441160673519),
|
||||
(0.68819096023558676910, -4.7360679774997896964, 1.11351636441160673519),
|
||||
(0.68819096023558676910, -2.1180339887498948482, 1.11351636441160673519),
|
||||
(0.68819096023558676910, 2.1180339887498948482, 1.11351636441160673519),
|
||||
(0.68819096023558676910, 4.7360679774997896964, 1.11351636441160673519),
|
||||
(-0.42532540417601993887, -1.3090169943749474241, -4.7169310137059934362),
|
||||
(-0.42532540417601993887, -1.3090169943749474241, 0.26286555605956679615),
|
||||
(-0.42532540417601993887, 1.3090169943749474241, -4.7169310137059934362),
|
||||
(-0.42532540417601993887, 1.3090169943749474241, 0.26286555605956679615),
|
||||
(-0.26286555605956679615, -0.8090169943749474241, 1.11351636441160673519),
|
||||
(-0.26286555605956679615, 0.8090169943749474241, 1.11351636441160673519),
|
||||
(0.26286555605956679615, -0.8090169943749474241, -1.1135163644116066184),
|
||||
(0.26286555605956679615, 0.8090169943749474241, -1.1135163644116066184),
|
||||
(0.42532540417601996609, -1.3090169943749474241, 4.7169310137059937438),
|
||||
(0.42532540417601996609, -1.3090169943749474241, -0.26286555605956679615),
|
||||
(0.42532540417601996609, 1.3090169943749474241, 4.7169310137059937438),
|
||||
(0.42532540417601996609, 1.3090169943749474241, -0.26286555605956679615)],
|
||||
[9, 66, 47], [44, 62, 77], [20, 91, 49], [33, 47, 83],
|
||||
[3, 77, 84], [12, 49, 53], [36, 84, 66], [28, 53, 62],
|
||||
[73, 83, 91], [15, 84, 46], [25, 64, 43], [16, 58, 72],
|
||||
[26, 46, 51], [11, 43, 74], [4, 72, 91], [60, 74, 84],
|
||||
[35, 91, 64], [23, 51, 58], [19, 74, 77], [79, 83, 78],
|
||||
[6, 56, 40], [76, 77, 81], [21, 78, 75], [8, 40, 58],
|
||||
[31, 75, 74], [42, 58, 83], [41, 81, 56], [13, 75, 43],
|
||||
[27, 51, 47], [2, 89, 71], [24, 43, 62], [17, 47, 85],
|
||||
[14, 71, 56], [65, 85, 75], [22, 56, 51], [34, 62, 89],
|
||||
[5, 85, 78], [32, 81, 46], [10, 53, 48], [45, 78, 64],
|
||||
[7, 46, 66], [18, 48, 89], [37, 66, 85], [70, 89, 81],
|
||||
[29, 64, 53], [88, 74, 1], [38, 67, 48], [42, 83, 72],
|
||||
[57, 1, 85], [34, 48, 62], [59, 72, 87], [19, 62, 74],
|
||||
[63, 87, 67], [17, 85, 83], [52, 75, 1], [39, 87, 49],
|
||||
[22, 51, 40], [55, 1, 66], [29, 49, 64], [30, 40, 69],
|
||||
[13, 64, 75], [82, 69, 87], [7, 66, 51], [90, 85, 1],
|
||||
[59, 69, 72], [70, 81, 71], [88, 1, 84], [73, 72, 83],
|
||||
[54, 71, 68], [5, 83, 85], [50, 68, 69], [3, 84, 81],
|
||||
[57, 66, 1], [30, 68, 40], [28, 62, 48], [52, 1, 74],
|
||||
[23, 40, 51], [38, 48, 86], [9, 51, 66], [80, 86, 68],
|
||||
[11, 74, 62], [55, 84, 1], [54, 86, 71], [35, 64, 49],
|
||||
[90, 1, 75], [41, 71, 81], [39, 49, 67], [15, 81, 84],
|
||||
[61, 67, 86], [21, 75, 64], [24, 53, 43], [50, 69, 0],
|
||||
[37, 85, 47], [31, 43, 75], [61, 0, 67], [27, 47, 58],
|
||||
[10, 67, 53], [8, 58, 69], [90, 75, 85], [45, 91, 78],
|
||||
[80, 68, 0], [36, 66, 46], [65, 78, 85], [63, 0, 87],
|
||||
[32, 46, 56], [20, 87, 91], [14, 56, 68], [57, 85, 66],
|
||||
[33, 58, 47], [61, 86, 0], [60, 84, 77], [37, 47, 66],
|
||||
[82, 0, 69], [44, 77, 89], [16, 69, 58], [18, 89, 86],
|
||||
[55, 66, 84], [26, 56, 46], [63, 67, 0], [31, 74, 43],
|
||||
[36, 46, 84], [50, 0, 68], [25, 43, 53], [6, 68, 56],
|
||||
[12, 53, 67], [88, 84, 74], [76, 89, 77], [82, 87, 0],
|
||||
[65, 75, 78], [60, 77, 74], [80, 0, 86], [79, 78, 91],
|
||||
[2, 86, 89], [4, 91, 87], [52, 74, 75], [21, 64, 78],
|
||||
[18, 86, 48], [23, 58, 40], [5, 78, 83], [28, 48, 53],
|
||||
[6, 40, 68], [25, 53, 64], [54, 68, 86], [33, 83, 58],
|
||||
[17, 83, 47], [12, 67, 49], [41, 56, 71], [9, 47, 51],
|
||||
[35, 49, 91], [2, 71, 86], [79, 91, 83], [38, 86, 67],
|
||||
[26, 51, 56], [7, 51, 46], [4, 87, 72], [34, 89, 48],
|
||||
[15, 46, 81], [42, 72, 58], [10, 48, 67], [27, 58, 51],
|
||||
[39, 67, 87], [76, 81, 89], [3, 81, 77], [8, 69, 40],
|
||||
[29, 53, 49], [19, 77, 62], [22, 40, 56], [20, 49, 87],
|
||||
[32, 56, 81], [59, 87, 69], [24, 62, 53], [11, 62, 43],
|
||||
[14, 68, 71], [73, 91, 72], [13, 43, 64], [70, 71, 89],
|
||||
[16, 72, 69], [44, 89, 62], [30, 69, 68], [45, 64, 91]]
|
||||
# Actual volume is : 51.405764746872634
|
||||
assert Abs(polytope_integrate(echidnahedron, 1) - 51.4057647468726) < 1e-12
|
||||
assert Abs(polytope_integrate(echidnahedron, expr) - 253.569603474519) <\
|
||||
1e-12
|
||||
|
||||
# Tests for many polynomials with maximum degree given(2D case).
|
||||
assert polytope_integrate(cube2, [x**2, y*z], max_degree=2) == \
|
||||
{y * z: 3125 / S(4), x ** 2: 3125 / S(3)}
|
||||
|
||||
assert polytope_integrate(cube2, max_degree=2) == \
|
||||
{1: 125, x: 625 / S(2), x * z: 3125 / S(4), y: 625 / S(2),
|
||||
y * z: 3125 / S(4), z ** 2: 3125 / S(3), y ** 2: 3125 / S(3),
|
||||
z: 625 / S(2), x * y: 3125 / S(4), x ** 2: 3125 / S(3)}
|
||||
|
||||
def test_point_sort():
|
||||
assert point_sort([Point(0, 0), Point(1, 0), Point(1, 1)]) == \
|
||||
[Point2D(1, 1), Point2D(1, 0), Point2D(0, 0)]
|
||||
|
||||
fig6 = Polygon((0, 0), (1, 0), (1, 1))
|
||||
assert polytope_integrate(fig6, x*y) == Rational(-1, 8)
|
||||
assert polytope_integrate(fig6, x*y, clockwise = True) == Rational(1, 8)
|
||||
|
||||
|
||||
def test_polytopes_intersecting_sides():
|
||||
fig5 = Polygon(Point(-4.165, -0.832), Point(-3.668, 1.568),
|
||||
Point(-3.266, 1.279), Point(-1.090, -2.080),
|
||||
Point(3.313, -0.683), Point(3.033, -4.845),
|
||||
Point(-4.395, 4.840), Point(-1.007, -3.328))
|
||||
assert polytope_integrate(fig5, x**2 + x*y + y**2) ==\
|
||||
S(1633405224899363)/(24*10**12)
|
||||
|
||||
fig6 = Polygon(Point(-3.018, -4.473), Point(-0.103, 2.378),
|
||||
Point(-1.605, -2.308), Point(4.516, -0.771),
|
||||
Point(4.203, 0.478))
|
||||
assert polytope_integrate(fig6, x**2 + x*y + y**2) ==\
|
||||
S(88161333955921)/(3*10**12)
|
||||
|
||||
|
||||
def test_max_degree():
|
||||
polygon = Polygon((0, 0), (0, 1), (1, 1), (1, 0))
|
||||
polys = [1, x, y, x*y, x**2*y, x*y**2]
|
||||
assert polytope_integrate(polygon, polys, max_degree=3) == \
|
||||
{1: 1, x: S.Half, y: S.Half, x*y: Rational(1, 4), x**2*y: Rational(1, 6), x*y**2: Rational(1, 6)}
|
||||
assert polytope_integrate(polygon, polys, max_degree=2) == \
|
||||
{1: 1, x: S.Half, y: S.Half, x*y: Rational(1, 4)}
|
||||
assert polytope_integrate(polygon, polys, max_degree=1) == \
|
||||
{1: 1, x: S.Half, y: S.Half}
|
||||
|
||||
|
||||
def test_main_integrate3d():
|
||||
cube = [[(0, 0, 0), (0, 0, 5), (0, 5, 0), (0, 5, 5), (5, 0, 0),\
|
||||
(5, 0, 5), (5, 5, 0), (5, 5, 5)],\
|
||||
[2, 6, 7, 3], [3, 7, 5, 1], [7, 6, 4, 5], [1, 5, 4, 0],\
|
||||
[3, 1, 0, 2], [0, 4, 6, 2]]
|
||||
vertices = cube[0]
|
||||
faces = cube[1:]
|
||||
hp_params = hyperplane_parameters(faces, vertices)
|
||||
assert main_integrate3d(1, faces, vertices, hp_params) == -125
|
||||
assert main_integrate3d(1, faces, vertices, hp_params, max_degree=1) == \
|
||||
{1: -125, y: Rational(-625, 2), z: Rational(-625, 2), x: Rational(-625, 2)}
|
||||
|
||||
|
||||
def test_main_integrate():
|
||||
triangle = Polygon((0, 3), (5, 3), (1, 1))
|
||||
facets = triangle.sides
|
||||
hp_params = hyperplane_parameters(triangle)
|
||||
assert main_integrate(x**2 + y**2, facets, hp_params) == Rational(325, 6)
|
||||
assert main_integrate(x**2 + y**2, facets, hp_params, max_degree=1) == \
|
||||
{0: 0, 1: 5, y: Rational(35, 3), x: 10}
|
||||
|
||||
|
||||
def test_polygon_integrate():
|
||||
cube = [[(0, 0, 0), (0, 0, 5), (0, 5, 0), (0, 5, 5), (5, 0, 0),\
|
||||
(5, 0, 5), (5, 5, 0), (5, 5, 5)],\
|
||||
[2, 6, 7, 3], [3, 7, 5, 1], [7, 6, 4, 5], [1, 5, 4, 0],\
|
||||
[3, 1, 0, 2], [0, 4, 6, 2]]
|
||||
facet = cube[1]
|
||||
facets = cube[1:]
|
||||
vertices = cube[0]
|
||||
assert polygon_integrate(facet, [(0, 1, 0), 5], 0, facets, vertices, 1, 0) == -25
|
||||
|
||||
|
||||
def test_distance_to_side():
|
||||
point = (0, 0, 0)
|
||||
assert distance_to_side(point, [(0, 0, 1), (0, 1, 0)], (1, 0, 0)) == -sqrt(2)/2
|
||||
|
||||
|
||||
def test_lineseg_integrate():
|
||||
polygon = [(0, 5, 0), (5, 5, 0), (5, 5, 5), (0, 5, 5)]
|
||||
line_seg = [(0, 5, 0), (5, 5, 0)]
|
||||
assert lineseg_integrate(polygon, 0, line_seg, 1, 0) == 5
|
||||
assert lineseg_integrate(polygon, 0, line_seg, 0, 0) == 0
|
||||
|
||||
|
||||
def test_integration_reduction():
|
||||
triangle = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))
|
||||
facets = triangle.sides
|
||||
a, b = hyperplane_parameters(triangle)[0]
|
||||
assert integration_reduction(facets, 0, a, b, 1, (x, y), 0) == 5
|
||||
assert integration_reduction(facets, 0, a, b, 0, (x, y), 0) == 0
|
||||
|
||||
|
||||
def test_integration_reduction_dynamic():
|
||||
triangle = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))
|
||||
facets = triangle.sides
|
||||
a, b = hyperplane_parameters(triangle)[0]
|
||||
x0 = facets[0].points[0]
|
||||
monomial_values = [[0, 0, 0, 0], [1, 0, 0, 5],\
|
||||
[y, 0, 1, 15], [x, 1, 0, None]]
|
||||
|
||||
assert integration_reduction_dynamic(facets, 0, a, b, x, 1, (x, y), 1,\
|
||||
0, 1, x0, monomial_values, 3) == Rational(25, 2)
|
||||
assert integration_reduction_dynamic(facets, 0, a, b, 0, 1, (x, y), 1,\
|
||||
0, 1, x0, monomial_values, 3) == 0
|
||||
|
||||
|
||||
def test_is_vertex():
|
||||
assert is_vertex(2) is False
|
||||
assert is_vertex((2, 3)) is True
|
||||
assert is_vertex(Point(2, 3)) is True
|
||||
assert is_vertex((2, 3, 4)) is True
|
||||
assert is_vertex((2, 3, 4, 5)) is False
|
||||
|
||||
|
||||
def test_issue_19234():
|
||||
polygon = Polygon(Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0))
|
||||
polys = [ 1, x, y, x*y, x**2*y, x*y**2]
|
||||
assert polytope_integrate(polygon, polys) == \
|
||||
{1: 1, x: S.Half, y: S.Half, x*y: Rational(1, 4), x**2*y: Rational(1, 6), x*y**2: Rational(1, 6)}
|
||||
polys = [ 1, x, y, x*y, 3 + x**2*y, x + x*y**2]
|
||||
assert polytope_integrate(polygon, polys) == \
|
||||
{1: 1, x: S.Half, y: S.Half, x*y: Rational(1, 4), x**2*y + 3: Rational(19, 6), x*y**2 + x: Rational(2, 3)}
|
||||
@@ -0,0 +1,774 @@
|
||||
from sympy.integrals.laplace import (
|
||||
laplace_transform, inverse_laplace_transform,
|
||||
LaplaceTransform, InverseLaplaceTransform,
|
||||
_laplace_deep_collect, laplace_correspondence,
|
||||
laplace_initial_conds)
|
||||
from sympy.core.function import Function, expand_mul
|
||||
from sympy.core import EulerGamma, Subs, Derivative, diff
|
||||
from sympy.core.exprtools import factor_terms
|
||||
from sympy.core.numbers import I, oo, pi
|
||||
from sympy.core.relational import Eq
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import Symbol, symbols
|
||||
from sympy.simplify.simplify import simplify
|
||||
from sympy.functions.elementary.complexes import Abs, re
|
||||
from sympy.functions.elementary.exponential import exp, log, exp_polar
|
||||
from sympy.functions.elementary.hyperbolic import cosh, sinh, coth, asinh
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.piecewise import Piecewise
|
||||
from sympy.functions.elementary.trigonometric import atan, cos, sin
|
||||
from sympy.logic.boolalg import And
|
||||
from sympy.functions.special.gamma_functions import (
|
||||
lowergamma, gamma, uppergamma)
|
||||
from sympy.functions.special.delta_functions import DiracDelta, Heaviside
|
||||
from sympy.functions.special.singularity_functions import SingularityFunction
|
||||
from sympy.functions.special.zeta_functions import lerchphi
|
||||
from sympy.functions.special.error_functions import (
|
||||
fresnelc, fresnels, erf, erfc, Ei, Ci, expint, E1)
|
||||
from sympy.functions.special.bessel import besseli, besselj, besselk, bessely
|
||||
from sympy.testing.pytest import slow, warns_deprecated_sympy
|
||||
from sympy.matrices import Matrix, eye
|
||||
from sympy.abc import s
|
||||
|
||||
|
||||
@slow
|
||||
def test_laplace_transform():
|
||||
LT = laplace_transform
|
||||
ILT = inverse_laplace_transform
|
||||
a, b, c = symbols('a, b, c', positive=True)
|
||||
np = symbols('np', integer=True, positive=True)
|
||||
t, w, x = symbols('t, w, x')
|
||||
f = Function('f')
|
||||
F = Function('F')
|
||||
g = Function('g')
|
||||
y = Function('y')
|
||||
Y = Function('Y')
|
||||
|
||||
# Test helper functions
|
||||
assert (
|
||||
_laplace_deep_collect(exp((t+a)*(t+b)) +
|
||||
besselj(2, exp((t+a)*(t+b)-t**2)), t) ==
|
||||
exp(a*b + t**2 + t*(a + b)) + besselj(2, exp(a*b + t*(a + b))))
|
||||
L = laplace_transform(diff(y(t), t, 3), t, s, noconds=True)
|
||||
L = laplace_correspondence(L, {y: Y})
|
||||
L = laplace_initial_conds(L, t, {y: [2, 4, 8, 16, 32]})
|
||||
assert L == s**3*Y(s) - 2*s**2 - 4*s - 8
|
||||
# Test whether `noconds=True` in `doit`:
|
||||
assert (2*LaplaceTransform(exp(t), t, s) - 1).doit() == -1 + 2/(s - 1)
|
||||
assert (LT(a*t+t**2+t**(S(5)/2), t, s) ==
|
||||
(a/s**2 + 2/s**3 + 15*sqrt(pi)/(8*s**(S(7)/2)), 0, True))
|
||||
assert LT(b/(t+a), t, s) == (-b*exp(-a*s)*Ei(-a*s), 0, True)
|
||||
assert (LT(1/sqrt(t+a), t, s) ==
|
||||
(sqrt(pi)*sqrt(1/s)*exp(a*s)*erfc(sqrt(a)*sqrt(s)), 0, True))
|
||||
assert (LT(sqrt(t)/(t+a), t, s) ==
|
||||
(-pi*sqrt(a)*exp(a*s)*erfc(sqrt(a)*sqrt(s)) + sqrt(pi)*sqrt(1/s),
|
||||
0, True))
|
||||
assert (LT((t+a)**(-S(3)/2), t, s) ==
|
||||
(-2*sqrt(pi)*sqrt(s)*exp(a*s)*erfc(sqrt(a)*sqrt(s)) + 2/sqrt(a),
|
||||
0, True))
|
||||
assert (LT(t**(S(1)/2)*(t+a)**(-1), t, s) ==
|
||||
(-pi*sqrt(a)*exp(a*s)*erfc(sqrt(a)*sqrt(s)) + sqrt(pi)*sqrt(1/s),
|
||||
0, True))
|
||||
assert (LT(1/(a*sqrt(t) + t**(3/2)), t, s) ==
|
||||
(pi*sqrt(a)*exp(a*s)*erfc(sqrt(a)*sqrt(s)), 0, True))
|
||||
assert (LT((t+a)**b, t, s) ==
|
||||
(s**(-b - 1)*exp(-a*s)*uppergamma(b + 1, a*s), 0, True))
|
||||
assert LT(t**5/(t+a), t, s) == (120*a**5*uppergamma(-5, a*s), 0, True)
|
||||
assert LT(exp(t), t, s) == (1/(s - 1), 1, True)
|
||||
assert LT(exp(2*t), t, s) == (1/(s - 2), 2, True)
|
||||
assert LT(exp(a*t), t, s) == (1/(s - a), a, True)
|
||||
assert LT(exp(a*(t-b)), t, s) == (exp(-a*b)/(-a + s), a, True)
|
||||
assert LT(t*exp(-a*(t)), t, s) == ((a + s)**(-2), -a, True)
|
||||
assert LT(t*exp(-a*(t-b)), t, s) == (exp(a*b)/(a + s)**2, -a, True)
|
||||
assert LT(b*t*exp(-a*t), t, s) == (b/(a + s)**2, -a, True)
|
||||
assert LT(exp(-a*exp(-t)), t, s) == (lowergamma(s, a)/a**s, 0, True)
|
||||
assert LT(exp(-a*exp(t)), t, s) == (a**s*uppergamma(-s, a), 0, True)
|
||||
assert (LT(t**(S(7)/4)*exp(-8*t)/gamma(S(11)/4), t, s) ==
|
||||
((s + 8)**(-S(11)/4), -8, True))
|
||||
assert (LT(t**(S(3)/2)*exp(-8*t), t, s) ==
|
||||
(3*sqrt(pi)/(4*(s + 8)**(S(5)/2)), -8, True))
|
||||
assert LT(t**a*exp(-a*t), t, s) == ((a+s)**(-a-1)*gamma(a+1), -a, True)
|
||||
assert (LT(b*exp(-a*t**2), t, s) ==
|
||||
(sqrt(pi)*b*exp(s**2/(4*a))*erfc(s/(2*sqrt(a)))/(2*sqrt(a)),
|
||||
0, True))
|
||||
assert (LT(exp(-2*t**2), t, s) ==
|
||||
(sqrt(2)*sqrt(pi)*exp(s**2/8)*erfc(sqrt(2)*s/4)/4, 0, True))
|
||||
assert (LT(b*exp(2*t**2), t, s) ==
|
||||
(b*LaplaceTransform(exp(2*t**2), t, s), -oo, True))
|
||||
assert (LT(t*exp(-a*t**2), t, s) ==
|
||||
(1/(2*a) - s*erfc(s/(2*sqrt(a)))/(4*sqrt(pi)*a**(S(3)/2)),
|
||||
0, True))
|
||||
assert (LT(exp(-a/t), t, s) ==
|
||||
(2*sqrt(a)*sqrt(1/s)*besselk(1, 2*sqrt(a)*sqrt(s)), 0, True))
|
||||
assert LT(sqrt(t)*exp(-a/t), t, s, simplify=True) == (
|
||||
sqrt(pi)*(sqrt(a)*sqrt(s) + 1/S(2))*sqrt(s**(-3)) *
|
||||
exp(-2*sqrt(a)*sqrt(s)), 0, True)
|
||||
assert (LT(exp(-a/t)/sqrt(t), t, s) ==
|
||||
(sqrt(pi)*sqrt(1/s)*exp(-2*sqrt(a)*sqrt(s)), 0, True))
|
||||
assert (LT(exp(-a/t)/(t*sqrt(t)), t, s) ==
|
||||
(sqrt(pi)*sqrt(1/a)*exp(-2*sqrt(a)*sqrt(s)), 0, True))
|
||||
# TODO: rules with sqrt(a*t) and sqrt(a/t) have stopped working after
|
||||
# changes to as_base_exp
|
||||
# assert (
|
||||
# LT(exp(-2*sqrt(a*t)), t, s) ==
|
||||
# (1/s - sqrt(pi)*sqrt(a) * exp(a/s)*erfc(sqrt(a)*sqrt(1/s)) /
|
||||
# s**(S(3)/2), 0, True))
|
||||
# assert LT(exp(-2*sqrt(a*t))/sqrt(t), t, s) == (
|
||||
# exp(a/s)*erfc(sqrt(a) * sqrt(1/s))*(sqrt(pi)*sqrt(1/s)), 0, True)
|
||||
assert (LT(t**4*exp(-2/t), t, s) ==
|
||||
(8*sqrt(2)*(1/s)**(S(5)/2)*besselk(5, 2*sqrt(2)*sqrt(s)),
|
||||
0, True))
|
||||
assert LT(sinh(a*t), t, s) == (a/(-a**2 + s**2), a, True)
|
||||
assert (LT(b*sinh(a*t)**2, t, s) ==
|
||||
(2*a**2*b/(-4*a**2*s + s**3), 2*a, True))
|
||||
assert (LT(b*sinh(a*t)**2, t, s, simplify=True) ==
|
||||
(2*a**2*b/(s*(-4*a**2 + s**2)), 2*a, True))
|
||||
# The following line confirms that issue #21202 is solved
|
||||
assert LT(cosh(2*t), t, s) == (s/(-4 + s**2), 2, True)
|
||||
assert LT(cosh(a*t), t, s) == (s/(-a**2 + s**2), a, True)
|
||||
assert (LT(cosh(a*t)**2, t, s, simplify=True) ==
|
||||
((2*a**2 - s**2)/(s*(4*a**2 - s**2)), 2*a, True))
|
||||
assert (LT(sinh(x+3), x, s, simplify=True) ==
|
||||
((s*sinh(3) + cosh(3))/(s**2 - 1), 1, True))
|
||||
L, _, _ = LT(42*sin(w*t+x)**2, t, s)
|
||||
assert (
|
||||
L -
|
||||
21*(s**2 + s*(-s*cos(2*x) + 2*w*sin(2*x)) +
|
||||
4*w**2)/(s*(s**2 + 4*w**2))).simplify() == 0
|
||||
# The following line replaces the old test test_issue_7173()
|
||||
assert LT(sinh(a*t)*cosh(a*t), t, s, simplify=True) == (a/(-4*a**2 + s**2),
|
||||
2*a, True)
|
||||
assert LT(sinh(a*t)/t, t, s) == (log((a + s)/(-a + s))/2, a, True)
|
||||
assert (LT(t**(-S(3)/2)*sinh(a*t), t, s) ==
|
||||
(-sqrt(pi)*(sqrt(-a + s) - sqrt(a + s)), a, True))
|
||||
# assert (LT(sinh(2*sqrt(a*t)), t, s) ==
|
||||
# (sqrt(pi)*sqrt(a)*exp(a/s)/s**(S(3)/2), 0, True))
|
||||
# assert (LT(sqrt(t)*sinh(2*sqrt(a*t)), t, s, simplify=True) ==
|
||||
# ((-sqrt(a)*s**(S(5)/2) + sqrt(pi)*s**2*(2*a + s)*exp(a/s) *
|
||||
# erf(sqrt(a)*sqrt(1/s))/2)/s**(S(9)/2), 0, True))
|
||||
# assert (LT(sinh(2*sqrt(a*t))/sqrt(t), t, s) ==
|
||||
# (sqrt(pi)*exp(a/s)*erf(sqrt(a)*sqrt(1/s))/sqrt(s), 0, True))
|
||||
# assert (LT(sinh(sqrt(a*t))**2/sqrt(t), t, s) ==
|
||||
# (sqrt(pi)*(exp(a/s) - 1)/(2*sqrt(s)), 0, True))
|
||||
assert (LT(t**(S(3)/7)*cosh(a*t), t, s) ==
|
||||
(((a + s)**(-S(10)/7) + (-a+s)**(-S(10)/7))*gamma(S(10)/7)/2,
|
||||
a, True))
|
||||
# assert (LT(cosh(2*sqrt(a*t)), t, s) ==
|
||||
# (sqrt(pi)*sqrt(a)*exp(a/s)*erf(sqrt(a)*sqrt(1/s))/s**(S(3)/2) +
|
||||
# 1/s, 0, True))
|
||||
# assert (LT(sqrt(t)*cosh(2*sqrt(a*t)), t, s) ==
|
||||
# (sqrt(pi)*(a + s/2)*exp(a/s)/s**(S(5)/2), 0, True))
|
||||
# assert (LT(cosh(2*sqrt(a*t))/sqrt(t), t, s) ==
|
||||
# (sqrt(pi)*exp(a/s)/sqrt(s), 0, True))
|
||||
# assert (LT(cosh(sqrt(a*t))**2/sqrt(t), t, s) ==
|
||||
# (sqrt(pi)*(exp(a/s) + 1)/(2*sqrt(s)), 0, True))
|
||||
assert LT(log(t), t, s, simplify=True) == (
|
||||
(-log(s) - EulerGamma)/s, 0, True)
|
||||
assert (LT(-log(t/a), t, s, simplify=True) ==
|
||||
((log(a) + log(s) + EulerGamma)/s, 0, True))
|
||||
assert LT(log(1+a*t), t, s) == (-exp(s/a)*Ei(-s/a)/s, 0, True)
|
||||
assert (LT(log(t+a), t, s, simplify=True) ==
|
||||
((s*log(a) - exp(s/a)*Ei(-s/a))/s**2, 0, True))
|
||||
assert (LT(log(t)/sqrt(t), t, s, simplify=True) ==
|
||||
(sqrt(pi)*(-log(s) - log(4) - EulerGamma)/sqrt(s), 0, True))
|
||||
assert (LT(t**(S(5)/2)*log(t), t, s, simplify=True) ==
|
||||
(sqrt(pi)*(-15*log(s) - log(1073741824) - 15*EulerGamma + 46) /
|
||||
(8*s**(S(7)/2)), 0, True))
|
||||
assert (LT(t**3*log(t), t, s, noconds=True, simplify=True) -
|
||||
6*(-log(s) - S.EulerGamma + S(11)/6)/s**4).simplify() == S.Zero
|
||||
assert (LT(log(t)**2, t, s, simplify=True) ==
|
||||
(((log(s) + EulerGamma)**2 + pi**2/6)/s, 0, True))
|
||||
assert (LT(exp(-a*t)*log(t), t, s, simplify=True) ==
|
||||
((-log(a + s) - EulerGamma)/(a + s), -a, True))
|
||||
assert LT(sin(a*t), t, s) == (a/(a**2 + s**2), 0, True)
|
||||
assert (LT(Abs(sin(a*t)), t, s) ==
|
||||
(a*coth(pi*s/(2*a))/(a**2 + s**2), 0, True))
|
||||
assert LT(sin(a*t)/t, t, s) == (atan(a/s), 0, True)
|
||||
assert LT(sin(a*t)**2/t, t, s) == (log(4*a**2/s**2 + 1)/4, 0, True)
|
||||
assert (LT(sin(a*t)**2/t**2, t, s) ==
|
||||
(a*atan(2*a/s) - s*log(4*a**2/s**2 + 1)/4, 0, True))
|
||||
# assert (LT(sin(2*sqrt(a*t)), t, s) ==
|
||||
# (sqrt(pi)*sqrt(a)*exp(-a/s)/s**(S(3)/2), 0, True))
|
||||
# assert LT(sin(2*sqrt(a*t))/t, t, s) == (pi*erf(sqrt(a)*sqrt(1/s)), 0, True)
|
||||
assert LT(cos(a*t), t, s) == (s/(a**2 + s**2), 0, True)
|
||||
assert (LT(cos(a*t)**2, t, s) ==
|
||||
((2*a**2 + s**2)/(s*(4*a**2 + s**2)), 0, True))
|
||||
# assert (LT(sqrt(t)*cos(2*sqrt(a*t)), t, s, simplify=True) ==
|
||||
# (sqrt(pi)*(-a + s/2)*exp(-a/s)/s**(S(5)/2), 0, True))
|
||||
# assert (LT(cos(2*sqrt(a*t))/sqrt(t), t, s) ==
|
||||
# (sqrt(pi)*sqrt(1/s)*exp(-a/s), 0, True))
|
||||
assert (LT(sin(a*t)*sin(b*t), t, s) ==
|
||||
(2*a*b*s/((s**2 + (a - b)**2)*(s**2 + (a + b)**2)), 0, True))
|
||||
assert (LT(cos(a*t)*sin(b*t), t, s) ==
|
||||
(b*(-a**2 + b**2 + s**2)/((s**2 + (a - b)**2)*(s**2 + (a + b)**2)),
|
||||
0, True))
|
||||
assert (LT(cos(a*t)*cos(b*t), t, s) ==
|
||||
(s*(a**2 + b**2 + s**2)/((s**2 + (a - b)**2)*(s**2 + (a + b)**2)),
|
||||
0, True))
|
||||
assert (LT(-a*t*cos(a*t) + sin(a*t), t, s, simplify=True) ==
|
||||
(2*a**3/(a**4 + 2*a**2*s**2 + s**4), 0, True))
|
||||
assert LT(c*exp(-b*t)*sin(a*t), t, s) == (a *
|
||||
c/(a**2 + (b + s)**2), -b, True)
|
||||
assert LT(c*exp(-b*t)*cos(a*t), t, s) == (c*(b + s)/(a**2 + (b + s)**2),
|
||||
-b, True)
|
||||
L, plane, cond = LT(cos(x + 3), x, s, simplify=True)
|
||||
assert plane == 0
|
||||
assert L - (s*cos(3) - sin(3))/(s**2 + 1) == 0
|
||||
# Error functions (laplace7.pdf)
|
||||
assert LT(erf(a*t), t, s) == (exp(s**2/(4*a**2))*erfc(s/(2*a))/s, 0, True)
|
||||
# assert LT(erf(sqrt(a*t)), t, s) == (sqrt(a)/(s*sqrt(a + s)), 0, True)
|
||||
# assert (LT(exp(a*t)*erf(sqrt(a*t)), t, s, simplify=True) ==
|
||||
# (-sqrt(a)/(sqrt(s)*(a - s)), a, True))
|
||||
# assert (LT(erf(sqrt(a/t)/2), t, s, simplify=True) ==
|
||||
# (1/s - exp(-sqrt(a)*sqrt(s))/s, 0, True))
|
||||
# assert (LT(erfc(sqrt(a*t)), t, s, simplify=True) ==
|
||||
# (-sqrt(a)/(s*sqrt(a + s)) + 1/s, -a, True))
|
||||
# assert (LT(exp(a*t)*erfc(sqrt(a*t)), t, s) ==
|
||||
# (1/(sqrt(a)*sqrt(s) + s), 0, True))
|
||||
# assert LT(erfc(sqrt(a/t)/2), t, s) == (exp(-sqrt(a)*sqrt(s))/s, 0, True)
|
||||
# Bessel functions (laplace8.pdf)
|
||||
assert LT(besselj(0, a*t), t, s) == (1/sqrt(a**2 + s**2), 0, True)
|
||||
assert (LT(besselj(1, a*t), t, s, simplify=True) ==
|
||||
(a/(a**2 + s**2 + s*sqrt(a**2 + s**2)), 0, True))
|
||||
assert (LT(besselj(2, a*t), t, s, simplify=True) ==
|
||||
(a**2/(sqrt(a**2 + s**2)*(s + sqrt(a**2 + s**2))**2), 0, True))
|
||||
assert (LT(t*besselj(0, a*t), t, s) ==
|
||||
(s/(a**2 + s**2)**(S(3)/2), 0, True))
|
||||
assert (LT(t*besselj(1, a*t), t, s) ==
|
||||
(a/(a**2 + s**2)**(S(3)/2), 0, True))
|
||||
assert (LT(t**2*besselj(2, a*t), t, s) ==
|
||||
(3*a**2/(a**2 + s**2)**(S(5)/2), 0, True))
|
||||
# assert LT(besselj(0, 2*sqrt(a*t)), t, s) == (exp(-a/s)/s, 0, True)
|
||||
# assert (LT(t**(S(3)/2)*besselj(3, 2*sqrt(a*t)), t, s) ==
|
||||
# (a**(S(3)/2)*exp(-a/s)/s**4, 0, True))
|
||||
assert (LT(besselj(0, a*sqrt(t**2+b*t)), t, s, simplify=True) ==
|
||||
(exp(b*(s - sqrt(a**2 + s**2)))/sqrt(a**2 + s**2), 0, True))
|
||||
assert LT(besseli(0, a*t), t, s) == (1/sqrt(-a**2 + s**2), a, True)
|
||||
assert (LT(besseli(1, a*t), t, s, simplify=True) ==
|
||||
(a/(-a**2 + s**2 + s*sqrt(-a**2 + s**2)), a, True))
|
||||
assert (LT(besseli(2, a*t), t, s, simplify=True) ==
|
||||
(a**2/(sqrt(-a**2 + s**2)*(s + sqrt(-a**2 + s**2))**2), a, True))
|
||||
assert LT(t*besseli(0, a*t), t, s) == (s/(-a**2 + s**2)**(S(3)/2), a, True)
|
||||
assert LT(t*besseli(1, a*t), t, s) == (a/(-a**2 + s**2)**(S(3)/2), a, True)
|
||||
assert (LT(t**2*besseli(2, a*t), t, s) ==
|
||||
(3*a**2/(-a**2 + s**2)**(S(5)/2), a, True))
|
||||
# assert (LT(t**(S(3)/2)*besseli(3, 2*sqrt(a*t)), t, s) ==
|
||||
# (a**(S(3)/2)*exp(a/s)/s**4, 0, True))
|
||||
assert (LT(bessely(0, a*t), t, s) ==
|
||||
(-2*asinh(s/a)/(pi*sqrt(a**2 + s**2)), 0, True))
|
||||
assert (LT(besselk(0, a*t), t, s) ==
|
||||
(log((s + sqrt(-a**2 + s**2))/a)/sqrt(-a**2 + s**2), -a, True))
|
||||
assert (LT(sin(a*t)**4, t, s, simplify=True) ==
|
||||
(24*a**4/(s*(64*a**4 + 20*a**2*s**2 + s**4)), 0, True))
|
||||
# Test general rules and unevaluated forms
|
||||
# These all also test whether issue #7219 is solved.
|
||||
assert LT(Heaviside(t-1)*cos(t-1), t, s) == (s*exp(-s)/(s**2 + 1), 0, True)
|
||||
assert LT(a*f(t), t, w) == (a*LaplaceTransform(f(t), t, w), -oo, True)
|
||||
assert (LT(a*Heaviside(t+1)*f(t+1), t, s) ==
|
||||
(a*LaplaceTransform(f(t + 1), t, s), -oo, True))
|
||||
assert (LT(a*Heaviside(t-1)*f(t-1), t, s) ==
|
||||
(a*LaplaceTransform(f(t), t, s)*exp(-s), -oo, True))
|
||||
assert (LT(b*f(t/a), t, s) ==
|
||||
(a*b*LaplaceTransform(f(t), t, a*s), -oo, True))
|
||||
assert LT(exp(-f(x)*t), t, s) == (1/(s + f(x)), -re(f(x)), True)
|
||||
assert (LT(exp(-a*t)*f(t), t, s) ==
|
||||
(LaplaceTransform(f(t), t, a + s), -oo, True))
|
||||
# assert (LT(exp(-a*t)*erfc(sqrt(b/t)/2), t, s) ==
|
||||
# (exp(-sqrt(b)*sqrt(a + s))/(a + s), -a, True))
|
||||
assert (LT(sinh(a*t)*f(t), t, s) ==
|
||||
(LaplaceTransform(f(t), t, -a + s)/2 -
|
||||
LaplaceTransform(f(t), t, a + s)/2, -oo, True))
|
||||
assert (LT(sinh(a*t)*t, t, s, simplify=True) ==
|
||||
(2*a*s/(a**4 - 2*a**2*s**2 + s**4), a, True))
|
||||
assert (LT(cosh(a*t)*f(t), t, s) ==
|
||||
(LaplaceTransform(f(t), t, -a + s)/2 +
|
||||
LaplaceTransform(f(t), t, a + s)/2, -oo, True))
|
||||
assert (LT(cosh(a*t)*t, t, s, simplify=True) ==
|
||||
(1/(2*(a + s)**2) + 1/(2*(a - s)**2), a, True))
|
||||
assert (LT(sin(a*t)*f(t), t, s, simplify=True) ==
|
||||
(I*(-LaplaceTransform(f(t), t, -I*a + s) +
|
||||
LaplaceTransform(f(t), t, I*a + s))/2, -oo, True))
|
||||
assert (LT(sin(f(t)), t, s) ==
|
||||
(LaplaceTransform(sin(f(t)), t, s), -oo, True))
|
||||
assert (LT(sin(a*t)*t, t, s, simplify=True) ==
|
||||
(2*a*s/(a**4 + 2*a**2*s**2 + s**4), 0, True))
|
||||
assert (LT(cos(a*t)*f(t), t, s) ==
|
||||
(LaplaceTransform(f(t), t, -I*a + s)/2 +
|
||||
LaplaceTransform(f(t), t, I*a + s)/2, -oo, True))
|
||||
assert (LT(cos(a*t)*t, t, s, simplify=True) ==
|
||||
((-a**2 + s**2)/(a**4 + 2*a**2*s**2 + s**4), 0, True))
|
||||
L, plane, _ = LT(sin(a*t+b)**2*f(t), t, s)
|
||||
assert plane == -oo
|
||||
assert (
|
||||
-L + (
|
||||
LaplaceTransform(f(t), t, s)/2 -
|
||||
LaplaceTransform(f(t), t, -2*I*a + s)*exp(2*I*b)/4 -
|
||||
LaplaceTransform(f(t), t, 2*I*a + s)*exp(-2*I*b)/4)) == 0
|
||||
L = LT(sin(a*t+b)**2*f(t), t, s, noconds=True)
|
||||
assert (
|
||||
laplace_correspondence(L, {f: F}) ==
|
||||
F(s)/2 - F(-2*I*a + s)*exp(2*I*b)/4 -
|
||||
F(2*I*a + s)*exp(-2*I*b)/4)
|
||||
L, plane, _ = LT(sin(a*t)**3*cosh(b*t), t, s)
|
||||
assert plane == b
|
||||
assert (
|
||||
-L - 3*a/(8*(9*a**2 + b**2 + 2*b*s + s**2)) -
|
||||
3*a/(8*(9*a**2 + b**2 - 2*b*s + s**2)) +
|
||||
3*a/(8*(a**2 + b**2 + 2*b*s + s**2)) +
|
||||
3*a/(8*(a**2 + b**2 - 2*b*s + s**2))).simplify() == 0
|
||||
assert (LT(t**2*exp(-t**2), t, s) ==
|
||||
(sqrt(pi)*s**2*exp(s**2/4)*erfc(s/2)/8 - s/4 +
|
||||
sqrt(pi)*exp(s**2/4)*erfc(s/2)/4, 0, True))
|
||||
assert (LT((a*t**2 + b*t + c)*f(t), t, s) ==
|
||||
(a*Derivative(LaplaceTransform(f(t), t, s), (s, 2)) -
|
||||
b*Derivative(LaplaceTransform(f(t), t, s), s) +
|
||||
c*LaplaceTransform(f(t), t, s), -oo, True))
|
||||
assert (LT(t**np*g(t), t, s) ==
|
||||
((-1)**np*Derivative(LaplaceTransform(g(t), t, s), (s, np)),
|
||||
-oo, True))
|
||||
# The following tests check whether _piecewise_to_heaviside works:
|
||||
x1 = Piecewise((0, t <= 0), (1, t <= 1), (0, True))
|
||||
X1 = LT(x1, t, s)[0]
|
||||
assert X1 == 1/s - exp(-s)/s
|
||||
y1 = ILT(X1, s, t)
|
||||
assert y1 == Heaviside(t) - Heaviside(t - 1)
|
||||
x1 = Piecewise((0, t <= 0), (t, t <= 1), (2-t, t <= 2), (0, True))
|
||||
X1 = LT(x1, t, s)[0].simplify()
|
||||
assert X1 == (exp(2*s) - 2*exp(s) + 1)*exp(-2*s)/s**2
|
||||
y1 = ILT(X1, s, t)
|
||||
assert (
|
||||
-y1 + t*Heaviside(t) + (t - 2)*Heaviside(t - 2) -
|
||||
2*(t - 1)*Heaviside(t - 1)).simplify() == 0
|
||||
x1 = Piecewise((exp(t), t <= 0), (1, t <= 1), (exp(-(t)), True))
|
||||
X1 = LT(x1, t, s)[0]
|
||||
assert X1 == exp(-1)*exp(-s)/(s + 1) + 1/s - exp(-s)/s
|
||||
y1 = ILT(X1, s, t)
|
||||
assert y1 == (
|
||||
exp(-1)*exp(1 - t)*Heaviside(t - 1) + Heaviside(t) - Heaviside(t - 1))
|
||||
x1 = Piecewise((0, x <= 0), (1, x <= 1), (0, True))
|
||||
X1 = LT(x1, t, s)[0]
|
||||
assert X1 == Piecewise((0, x <= 0), (1, x <= 1), (0, True))/s
|
||||
x1 = [
|
||||
a*Piecewise((1, And(t > 1, t <= 3)), (2, True)),
|
||||
a*Piecewise((1, And(t >= 1, t <= 3)), (2, True)),
|
||||
a*Piecewise((1, And(t >= 1, t < 3)), (2, True)),
|
||||
a*Piecewise((1, And(t > 1, t < 3)), (2, True))]
|
||||
for x2 in x1:
|
||||
assert LT(x2, t, s)[0].expand() == 2*a/s - a*exp(-s)/s + a*exp(-3*s)/s
|
||||
assert (
|
||||
LT(Piecewise((1, Eq(t, 1)), (2, True)), t, s)[0] ==
|
||||
LaplaceTransform(Piecewise((1, Eq(t, 1)), (2, True)), t, s))
|
||||
# The following lines test whether _laplace_transform successfully
|
||||
# removes Heaviside(1) before processing espressions. It fails if
|
||||
# Heaviside(t) remains because then meijerg functions will appear.
|
||||
X1 = 1/sqrt(a*s**2-b)
|
||||
x1 = ILT(X1, s, t)
|
||||
Y1 = LT(x1, t, s)[0]
|
||||
Z1 = (Y1**2/X1**2).simplify()
|
||||
assert Z1 == 1
|
||||
# The following two lines test whether issues #5813 and #7176 are solved.
|
||||
assert (LT(diff(f(t), (t, 1)), t, s, noconds=True) ==
|
||||
s*LaplaceTransform(f(t), t, s) - f(0))
|
||||
assert (LT(diff(f(t), (t, 3)), t, s, noconds=True) ==
|
||||
s**3*LaplaceTransform(f(t), t, s) - s**2*f(0) -
|
||||
s*Subs(Derivative(f(t), t), t, 0) -
|
||||
Subs(Derivative(f(t), (t, 2)), t, 0))
|
||||
# Issue #7219
|
||||
assert (LT(diff(f(x, t, w), t, 2), t, s) ==
|
||||
(s**2*LaplaceTransform(f(x, t, w), t, s) - s*f(x, 0, w) -
|
||||
Subs(Derivative(f(x, t, w), t), t, 0), -oo, True))
|
||||
# Issue #23307
|
||||
assert (LT(10*diff(f(t), (t, 1)), t, s, noconds=True) ==
|
||||
10*s*LaplaceTransform(f(t), t, s) - 10*f(0))
|
||||
assert (LT(a*f(b*t)+g(c*t), t, s, noconds=True) ==
|
||||
a*LaplaceTransform(f(t), t, s/b)/b +
|
||||
LaplaceTransform(g(t), t, s/c)/c)
|
||||
assert inverse_laplace_transform(
|
||||
f(w), w, t, plane=0) == InverseLaplaceTransform(f(w), w, t, 0)
|
||||
assert (LT(f(t)*g(t), t, s, noconds=True) ==
|
||||
LaplaceTransform(f(t)*g(t), t, s))
|
||||
# Issue #24294
|
||||
assert (LT(b*f(a*t), t, s, noconds=True) ==
|
||||
b*LaplaceTransform(f(t), t, s/a)/a)
|
||||
assert LT(3*exp(t)*Heaviside(t), t, s) == (3/(s - 1), 1, True)
|
||||
assert (LT(2*sin(t)*Heaviside(t), t, s, simplify=True) ==
|
||||
(2/(s**2 + 1), 0, True))
|
||||
# Issue #25293
|
||||
assert (
|
||||
LT((1/(t-1))*sin(4*pi*(t-1))*DiracDelta(t-1) *
|
||||
(Heaviside(t-1/4) - Heaviside(t-2)), t, s)[0] == 4*pi*exp(-s))
|
||||
# additional basic tests from wikipedia
|
||||
assert (LT((t - a)**b*exp(-c*(t - a))*Heaviside(t - a), t, s) ==
|
||||
((c + s)**(-b - 1)*exp(-a*s)*gamma(b + 1), -c, True))
|
||||
assert (
|
||||
LT((exp(2*t)-1)*exp(-b-t)*Heaviside(t)/2, t, s, noconds=True,
|
||||
simplify=True) ==
|
||||
exp(-b)/(s**2 - 1))
|
||||
# DiracDelta function: standard cases
|
||||
assert LT(DiracDelta(t), t, s) == (1, -oo, True)
|
||||
assert LT(DiracDelta(a*t), t, s) == (1/a, -oo, True)
|
||||
assert LT(DiracDelta(t/42), t, s) == (42, -oo, True)
|
||||
assert LT(DiracDelta(t+42), t, s) == (0, -oo, True)
|
||||
assert (LT(DiracDelta(t)+DiracDelta(t-42), t, s) ==
|
||||
(1 + exp(-42*s), -oo, True))
|
||||
assert (LT(DiracDelta(t)-a*exp(-a*t), t, s, simplify=True) ==
|
||||
(s/(a + s), -a, True))
|
||||
assert (
|
||||
LT(exp(-t)*(DiracDelta(t)+DiracDelta(t-42)), t, s, simplify=True) ==
|
||||
(exp(-42*s - 42) + 1, -oo, True))
|
||||
assert LT(f(t)*DiracDelta(t-42), t, s) == (f(42)*exp(-42*s), -oo, True)
|
||||
assert LT(f(t)*DiracDelta(b*t-a), t, s) == (f(a/b)*exp(-a*s/b)/b,
|
||||
-oo, True)
|
||||
assert LT(f(t)*DiracDelta(b*t+a), t, s) == (0, -oo, True)
|
||||
# SingularityFunction
|
||||
assert LT(SingularityFunction(t, a, -1), t, s)[0] == exp(-a*s)
|
||||
assert LT(SingularityFunction(t, a, 1), t, s)[0] == exp(-a*s)/s**2
|
||||
assert LT(SingularityFunction(t, a, x), t, s)[0] == (
|
||||
LaplaceTransform(SingularityFunction(t, a, x), t, s))
|
||||
# Collection of cases that cannot be fully evaluated and/or would catch
|
||||
# some common implementation errors
|
||||
assert (LT(DiracDelta(t**2), t, s, noconds=True) ==
|
||||
LaplaceTransform(DiracDelta(t**2), t, s))
|
||||
assert LT(DiracDelta(t**2 - 1), t, s) == (exp(-s)/2, -oo, True)
|
||||
assert LT(DiracDelta(t*(1 - t)), t, s) == (1 - exp(-s), -oo, True)
|
||||
assert (LT((DiracDelta(t) + 1)*(DiracDelta(t - 1) + 1), t, s) ==
|
||||
(LaplaceTransform(DiracDelta(t)*DiracDelta(t - 1), t, s) +
|
||||
1 + exp(-s) + 1/s, 0, True))
|
||||
assert LT(DiracDelta(2*t-2*exp(a)), t, s) == (exp(-s*exp(a))/2, -oo, True)
|
||||
assert LT(DiracDelta(-2*t+2*exp(a)), t, s) == (exp(-s*exp(a))/2, -oo, True)
|
||||
# Heaviside tests
|
||||
assert LT(Heaviside(t), t, s) == (1/s, 0, True)
|
||||
assert LT(Heaviside(t - a), t, s) == (exp(-a*s)/s, 0, True)
|
||||
assert LT(Heaviside(t-1), t, s) == (exp(-s)/s, 0, True)
|
||||
assert LT(Heaviside(2*t-4), t, s) == (exp(-2*s)/s, 0, True)
|
||||
assert LT(Heaviside(2*t+4), t, s) == (1/s, 0, True)
|
||||
assert (LT(Heaviside(-2*t+4), t, s, simplify=True) ==
|
||||
(1/s - exp(-2*s)/s, 0, True))
|
||||
assert (LT(g(t)*Heaviside(t - w), t, s) ==
|
||||
(LaplaceTransform(g(t)*Heaviside(t - w), t, s), -oo, True))
|
||||
assert (
|
||||
LT(Heaviside(t-a)*g(t), t, s) ==
|
||||
(LaplaceTransform(g(a + t), t, s)*exp(-a*s), -oo, True))
|
||||
assert (
|
||||
LT(Heaviside(t+a)*g(t), t, s) ==
|
||||
(LaplaceTransform(g(t), t, s), -oo, True))
|
||||
assert (
|
||||
LT(Heaviside(-t+a)*g(t), t, s) ==
|
||||
(LaplaceTransform(g(t), t, s) -
|
||||
LaplaceTransform(g(a + t), t, s)*exp(-a*s), -oo, True))
|
||||
assert (
|
||||
LT(Heaviside(-t-a)*g(t), t, s) == (0, 0, True))
|
||||
# Fresnel functions
|
||||
assert (laplace_transform(fresnels(t), t, s, simplify=True) ==
|
||||
((-sin(s**2/(2*pi))*fresnels(s/pi) +
|
||||
sqrt(2)*sin(s**2/(2*pi) + pi/4)/2 -
|
||||
cos(s**2/(2*pi))*fresnelc(s/pi))/s, 0, True))
|
||||
assert (laplace_transform(fresnelc(t), t, s, simplify=True) ==
|
||||
((sin(s**2/(2*pi))*fresnelc(s/pi) -
|
||||
cos(s**2/(2*pi))*fresnels(s/pi) +
|
||||
sqrt(2)*cos(s**2/(2*pi) + pi/4)/2)/s, 0, True))
|
||||
# Matrix tests
|
||||
Mt = Matrix([[exp(t), t*exp(-t)], [t*exp(-t), exp(t)]])
|
||||
Ms = Matrix([[1/(s - 1), (s + 1)**(-2)],
|
||||
[(s + 1)**(-2), 1/(s - 1)]])
|
||||
# The default behaviour for Laplace transform of a Matrix returns a Matrix
|
||||
# of Tuples and is deprecated:
|
||||
with warns_deprecated_sympy():
|
||||
Ms_conds = Matrix(
|
||||
[[(1/(s - 1), 1, True), ((s + 1)**(-2), -1, True)],
|
||||
[((s + 1)**(-2), -1, True), (1/(s - 1), 1, True)]])
|
||||
with warns_deprecated_sympy():
|
||||
assert LT(Mt, t, s) == Ms_conds
|
||||
# The new behavior is to return a tuple of a Matrix and the convergence
|
||||
# conditions for the matrix as a whole:
|
||||
assert LT(Mt, t, s, legacy_matrix=False) == (Ms, 1, True)
|
||||
# With noconds=True the transformed matrix is returned without conditions
|
||||
# either way:
|
||||
assert LT(Mt, t, s, noconds=True) == Ms
|
||||
assert LT(Mt, t, s, legacy_matrix=False, noconds=True) == Ms
|
||||
|
||||
|
||||
@slow
|
||||
def test_inverse_laplace_transform():
|
||||
s = symbols('s')
|
||||
k, n, t = symbols('k, n, t', real=True)
|
||||
a, b, c, d = symbols('a, b, c, d', positive=True)
|
||||
f = Function('f')
|
||||
F = Function('F')
|
||||
|
||||
def ILT(g):
|
||||
return inverse_laplace_transform(g, s, t)
|
||||
|
||||
def ILTS(g):
|
||||
return inverse_laplace_transform(g, s, t, simplify=True)
|
||||
|
||||
def ILTF(g):
|
||||
return laplace_correspondence(
|
||||
inverse_laplace_transform(g, s, t), {f: F})
|
||||
|
||||
# Tests for the rules in Bateman54.
|
||||
|
||||
# Section 4.1: Some of the Laplace transform rules can also be used well
|
||||
# in the inverse transform.
|
||||
assert ILTF(exp(-a*s)*F(s)) == f(-a + t)
|
||||
assert ILTF(k*F(s-a)) == k*f(t)*exp(-a*t)
|
||||
assert ILTF(diff(F(s), s, 3)) == -t**3*f(t)
|
||||
assert ILTF(diff(F(s), s, 4)) == t**4*f(t)
|
||||
|
||||
# Section 5.1: Most rules are impractical for a computer algebra system.
|
||||
|
||||
# Section 5.2: Rational functions
|
||||
assert ILT(2) == 2*DiracDelta(t)
|
||||
assert ILT(1/s) == Heaviside(t)
|
||||
assert ILT(1/s**2) == t*Heaviside(t)
|
||||
assert ILT(1/s**5) == t**4*Heaviside(t)/24
|
||||
assert ILT(1/s**n) == t**(n - 1)*Heaviside(t)/gamma(n)
|
||||
assert ILT(a/(a + s)) == a*exp(-a*t)*Heaviside(t)
|
||||
assert ILT(s/(a + s)) == -a*exp(-a*t)*Heaviside(t) + DiracDelta(t)
|
||||
assert (ILT(b*s/(s+a)**2) ==
|
||||
b*(-a*t*exp(-a*t)*Heaviside(t) + exp(-a*t)*Heaviside(t)))
|
||||
assert (ILTS(c/((s+a)*(s+b))) ==
|
||||
c*(exp(a*t) - exp(b*t))*exp(-t*(a + b))*Heaviside(t)/(a - b))
|
||||
assert (ILTS(c*s/((s+a)*(s+b))) ==
|
||||
c*(a*exp(b*t) - b*exp(a*t))*exp(-t*(a + b))*Heaviside(t)/(a - b))
|
||||
assert ILTS(s/(a + s)**3) == t*(-a*t + 2)*exp(-a*t)*Heaviside(t)/2
|
||||
assert ILTS(1/(s*(a + s)**3)) == (
|
||||
-a**2*t**2 - 2*a*t + 2*exp(a*t) - 2)*exp(-a*t)*Heaviside(t)/(2*a**3)
|
||||
assert ILT(1/(s*(a + s)**n)) == (
|
||||
Heaviside(t)*lowergamma(n, a*t)/(a**n*gamma(n)))
|
||||
assert ILT((s-a)**(-b)) == t**(b - 1)*exp(a*t)*Heaviside(t)/gamma(b)
|
||||
assert ILT((a + s)**(-2)) == t*exp(-a*t)*Heaviside(t)
|
||||
assert ILT((a + s)**(-5)) == t**4*exp(-a*t)*Heaviside(t)/24
|
||||
assert ILT(s**2/(s**2 + 1)) == -sin(t)*Heaviside(t) + DiracDelta(t)
|
||||
assert ILT(1 - 1/(s**2 + 1)) == -sin(t)*Heaviside(t) + DiracDelta(t)
|
||||
assert ILT(a/(a**2 + s**2)) == sin(a*t)*Heaviside(t)
|
||||
assert ILT(s/(s**2 + a**2)) == cos(a*t)*Heaviside(t)
|
||||
assert ILT(b/(b**2 + (a + s)**2)) == exp(-a*t)*sin(b*t)*Heaviside(t)
|
||||
assert (ILT(b*s/(b**2 + (a + s)**2)) ==
|
||||
b*(-a*exp(-a*t)*sin(b*t)/b + exp(-a*t)*cos(b*t))*Heaviside(t))
|
||||
assert ILT(1/(s**2*(s**2 + 1))) == t*Heaviside(t) - sin(t)*Heaviside(t)
|
||||
assert (ILTS(c*s/(d**2*(s+a)**2+b**2)) ==
|
||||
c*(-a*d*sin(b*t/d) + b*cos(b*t/d))*exp(-a*t)*Heaviside(t)/(b*d**2))
|
||||
assert ILTS((b*s**2 + d)/(a**2 + s**2)**2) == (
|
||||
2*a**2*b*sin(a*t) + (a**2*b - d)*(a*t*cos(a*t) -
|
||||
sin(a*t)))*Heaviside(t)/(2*a**3)
|
||||
assert ILTS(b/(s**2-a**2)) == b*sinh(a*t)*Heaviside(t)/a
|
||||
assert (ILT(b/(s**2-a**2)) ==
|
||||
b*(exp(a*t)*Heaviside(t)/(2*a) - exp(-a*t)*Heaviside(t)/(2*a)))
|
||||
assert ILTS(b*s/(s**2-a**2)) == b*cosh(a*t)*Heaviside(t)
|
||||
assert (ILT(b/(s*(s+a))) ==
|
||||
b*(Heaviside(t)/a - exp(-a*t)*Heaviside(t)/a))
|
||||
# Issue #24424
|
||||
assert (ILTS((s + 8)/((s + 2)*(s**2 + 2*s + 10))) ==
|
||||
((8*sin(3*t) - 9*cos(3*t))*exp(t) + 9)*exp(-2*t)*Heaviside(t)/15)
|
||||
# Issue #8514; this is not important anymore, since this function
|
||||
# is not solved by integration anymore
|
||||
assert (ILT(1/(a*s**2+b*s+c)) ==
|
||||
2*exp(-b*t/(2*a))*sin(t*sqrt(4*a*c - b**2)/(2*a)) *
|
||||
Heaviside(t)/sqrt(4*a*c - b**2))
|
||||
|
||||
# Section 5.3: Irrational algebraic functions
|
||||
assert ( # (1)
|
||||
ILT(1/sqrt(s)/(b*s-a)) ==
|
||||
exp(a*t/b)*Heaviside(t)*erf(sqrt(a)*sqrt(t)/sqrt(b))/(sqrt(a)*sqrt(b)))
|
||||
assert ( # (2)
|
||||
ILT(1/sqrt(k*s)/(c*s-a)/s) ==
|
||||
(-2*c*sqrt(t)/(sqrt(pi)*a) +
|
||||
c**(S(3)/2)*exp(a*t/c)*erf(sqrt(a)*sqrt(t)/sqrt(c))/a**(S(3)/2)) *
|
||||
Heaviside(t)/(c*sqrt(k)))
|
||||
assert ( # (4)
|
||||
ILT(1/(sqrt(c*s)+a)) == (-a*exp(a**2*t/c)*erfc(a*sqrt(t)/sqrt(c))/c +
|
||||
1/(sqrt(pi)*sqrt(c)*sqrt(t)))*Heaviside(t))
|
||||
assert ( # (5)
|
||||
ILT(a/s/(b*sqrt(s)+a)) ==
|
||||
(-exp(a**2*t/b**2)*erfc(a*sqrt(t)/b) + 1)*Heaviside(t))
|
||||
assert ( # (6)
|
||||
ILT((a-b)*sqrt(s)/(sqrt(s)+sqrt(a))/(s-b)) ==
|
||||
(sqrt(a)*sqrt(b)*exp(b*t)*erfc(sqrt(b)*sqrt(t)) +
|
||||
a*exp(a*t)*erfc(sqrt(a)*sqrt(t)) - b*exp(b*t))*Heaviside(t))
|
||||
assert ( # (7)
|
||||
ILT(1/sqrt(s)/(sqrt(b*s)+a)) ==
|
||||
exp(a**2*t/b)*Heaviside(t)*erfc(a*sqrt(t)/sqrt(b))/sqrt(b))
|
||||
assert ( # (8)
|
||||
ILT(a**2/(sqrt(s)+a)/s**(S(3)/2)) ==
|
||||
(2*a*sqrt(t)/sqrt(pi) + exp(a**2*t)*erfc(a*sqrt(t)) - 1) *
|
||||
Heaviside(t))
|
||||
assert ( # (9)
|
||||
ILT((a-b)*sqrt(b)/(s-b)/sqrt(s)/(sqrt(s)+sqrt(a))) ==
|
||||
(sqrt(a)*exp(b*t)*erf(sqrt(b)*sqrt(t)) +
|
||||
sqrt(b)*exp(a*t)*erfc(sqrt(a)*sqrt(t)) -
|
||||
sqrt(b)*exp(b*t))*Heaviside(t))
|
||||
assert ( # (10)
|
||||
ILT(1/(sqrt(s)+sqrt(a))**2) ==
|
||||
(-2*sqrt(a)*sqrt(t)/sqrt(pi) +
|
||||
(-2*a*t + 1)*(erf(sqrt(a)*sqrt(t)) -
|
||||
1)*exp(a*t) + 1)*Heaviside(t))
|
||||
assert ( # (11)
|
||||
ILT(1/(sqrt(s)+sqrt(a))**2/s) ==
|
||||
((2*t - 1/a)*exp(a*t)*erfc(sqrt(a)*sqrt(t)) + 1/a -
|
||||
2*sqrt(t)/(sqrt(pi)*sqrt(a)))*Heaviside(t))
|
||||
assert ( # (12)
|
||||
ILT(1/(sqrt(s)+a)**2/sqrt(s)) ==
|
||||
(-2*a*t*exp(a**2*t)*erfc(a*sqrt(t)) +
|
||||
2*sqrt(t)/sqrt(pi))*Heaviside(t))
|
||||
assert ( # (13)
|
||||
ILT(1/(sqrt(s)+a)**3) ==
|
||||
(-a*t*(2*a**2*t + 3)*exp(a**2*t)*erfc(a*sqrt(t)) +
|
||||
2*sqrt(t)*(a**2*t + 1)/sqrt(pi))*Heaviside(t))
|
||||
x = (
|
||||
- ILT(sqrt(s)/(sqrt(s)+a)**3) +
|
||||
2*(sqrt(pi)*a**2*t*(-2*sqrt(pi)*erfc(a*sqrt(t)) +
|
||||
2*exp(-a**2*t)/(a*sqrt(t))) *
|
||||
(-a**4*t**2 - 5*a**2*t/2 - S.Half) * exp(a**2*t)/2 +
|
||||
sqrt(pi)*a*sqrt(t)*(a**2*t + 1)/2) *
|
||||
Heaviside(t)/(pi*a**2*t)).simplify()
|
||||
assert ( # (14)
|
||||
x == 0)
|
||||
x = (
|
||||
- ILT(1/sqrt(s)/(sqrt(s)+a)**3) +
|
||||
Heaviside(t)*(sqrt(t)*((2*a**2*t + 1) *
|
||||
(sqrt(pi)*a*sqrt(t)*exp(a**2*t) *
|
||||
erfc(a*sqrt(t)) - 1) + 1) /
|
||||
(sqrt(pi)*a))).simplify()
|
||||
assert ( # (15)
|
||||
x == 0)
|
||||
assert ( # (16)
|
||||
factor_terms(ILT(3/(sqrt(s)+a)**4)) ==
|
||||
3*(-2*a**3*t**(S(5)/2)*(2*a**2*t + 5)/(3*sqrt(pi)) +
|
||||
t*(4*a**4*t**2 + 12*a**2*t + 3)*exp(a**2*t) *
|
||||
erfc(a*sqrt(t))/3)*Heaviside(t))
|
||||
assert ( # (17)
|
||||
ILT((sqrt(s)-a)/(s*(sqrt(s)+a))) ==
|
||||
(2*exp(a**2*t)*erfc(a*sqrt(t))-1)*Heaviside(t))
|
||||
assert ( # (18)
|
||||
ILT((sqrt(s)-a)**2/(s*(sqrt(s)+a)**2)) == (
|
||||
1 + 8*a**2*t*exp(a**2*t)*erfc(a*sqrt(t)) -
|
||||
8/sqrt(pi)*a*sqrt(t))*Heaviside(t))
|
||||
assert ( # (19)
|
||||
ILT((sqrt(s)-a)**3/(s*(sqrt(s)+a)**3)) == Heaviside(t)*(
|
||||
2*(8*a**4*t**2+8*a**2*t+1)*exp(a**2*t) *
|
||||
erfc(a*sqrt(t))-8/sqrt(pi)*a*sqrt(t)*(2*a**2*t+1)-1))
|
||||
assert ( # (22)
|
||||
ILT(sqrt(s+a)/(s+b)) == Heaviside(t)*(
|
||||
exp(-a*t)/sqrt(t)/sqrt(pi) +
|
||||
sqrt(a-b)*exp(-b*t)*erf(sqrt(a-b)*sqrt(t))))
|
||||
assert ( # (23)
|
||||
ILT(1/sqrt(s+b)/(s+a)) == Heaviside(t)*(
|
||||
1/sqrt(b-a)*exp(-a*t)*erf(sqrt(b-a)*sqrt(t))))
|
||||
assert ( # (35)
|
||||
ILT(1/sqrt(s**2+a**2)) == Heaviside(t)*(
|
||||
besselj(0, a*t)))
|
||||
assert ( # (44)
|
||||
ILT(1/sqrt(s**2-a**2)) == Heaviside(t)*(
|
||||
besseli(0, a*t)))
|
||||
|
||||
# Miscellaneous tests
|
||||
# Can _inverse_laplace_time_shift deal with positive exponents?
|
||||
assert (
|
||||
- ILT((s**2*exp(2*s) + 4*exp(s) - 4)*exp(-2*s)/(s*(s**2 + 1))) +
|
||||
cos(t)*Heaviside(t) + 4*cos(t - 2)*Heaviside(t - 2) -
|
||||
4*cos(t - 1)*Heaviside(t - 1) - 4*Heaviside(t - 2) +
|
||||
4*Heaviside(t - 1)).simplify() == 0
|
||||
|
||||
|
||||
@slow
|
||||
def test_inverse_laplace_transform_old():
|
||||
from sympy.functions.special.delta_functions import DiracDelta
|
||||
ILT = inverse_laplace_transform
|
||||
a, b, c, d = symbols('a b c d', positive=True)
|
||||
n, r = symbols('n, r', real=True)
|
||||
t, z = symbols('t z')
|
||||
f = Function('f')
|
||||
F = Function('F')
|
||||
|
||||
def simp_hyp(expr):
|
||||
return factor_terms(expand_mul(expr)).rewrite(sin)
|
||||
|
||||
L = ILT(F(s), s, t)
|
||||
assert laplace_correspondence(L, {f: F}) == f(t)
|
||||
assert ILT(exp(-a*s)/s, s, t) == Heaviside(-a + t)
|
||||
assert ILT(exp(-a*s)/(b + s), s, t) == exp(-b*(-a + t))*Heaviside(-a + t)
|
||||
assert (ILT((b + s)/(a**2 + (b + s)**2), s, t) ==
|
||||
exp(-b*t)*cos(a*t)*Heaviside(t))
|
||||
assert (ILT(exp(-a*s)/s**b, s, t) ==
|
||||
(-a + t)**(b - 1)*Heaviside(-a + t)/gamma(b))
|
||||
assert (ILT(exp(-a*s)/sqrt(s**2 + 1), s, t) ==
|
||||
Heaviside(-a + t)*besselj(0, a - t))
|
||||
assert ILT(1/(s*sqrt(s + 1)), s, t) == Heaviside(t)*erf(sqrt(t))
|
||||
# TODO sinh/cosh shifted come out a mess. also delayed trig is a mess
|
||||
# TODO should this simplify further?
|
||||
assert (ILT(exp(-a*s)/s**b, s, t) ==
|
||||
(t - a)**(b - 1)*Heaviside(t - a)/gamma(b))
|
||||
assert (ILT(exp(-a*s)/sqrt(1 + s**2), s, t) ==
|
||||
Heaviside(t - a)*besselj(0, a - t)) # note: besselj(0, x) is even
|
||||
# XXX ILT turns these branch factor into trig functions ...
|
||||
assert (
|
||||
simplify(ILT(a**b*(s + sqrt(s**2 - a**2))**(-b)/sqrt(s**2 - a**2),
|
||||
s, t).rewrite(exp)) ==
|
||||
Heaviside(t)*besseli(b, a*t))
|
||||
assert (
|
||||
ILT(a**b*(s + sqrt(s**2 + a**2))**(-b)/sqrt(s**2 + a**2),
|
||||
s, t, simplify=True).rewrite(exp) ==
|
||||
Heaviside(t)*besselj(b, a*t))
|
||||
assert ILT(1/(s*sqrt(s + 1)), s, t) == Heaviside(t)*erf(sqrt(t))
|
||||
# TODO can we make erf(t) work?
|
||||
assert (ILT((s * eye(2) - Matrix([[1, 0], [0, 2]])).inv(), s, t) ==
|
||||
Matrix([[exp(t)*Heaviside(t), 0], [0, exp(2*t)*Heaviside(t)]]))
|
||||
# Test time_diff rule
|
||||
assert (ILT(s**42*f(s), s, t) ==
|
||||
Derivative(InverseLaplaceTransform(f(s), s, t, None), (t, 42)))
|
||||
assert ILT(cos(s), s, t) == InverseLaplaceTransform(cos(s), s, t, None)
|
||||
# Rules for testing different DiracDelta cases
|
||||
assert (
|
||||
ILT(1 + 2*s + 3*s**2 + 5*s**3, s, t) == DiracDelta(t) +
|
||||
2*DiracDelta(t, 1) + 3*DiracDelta(t, 2) + 5*DiracDelta(t, 3))
|
||||
assert (ILT(2*exp(3*s) - 5*exp(-7*s), s, t) ==
|
||||
2*InverseLaplaceTransform(exp(3*s), s, t, None) -
|
||||
5*DiracDelta(t - 7))
|
||||
a = cos(sin(7)/2)
|
||||
assert ILT(a*exp(-3*s), s, t) == a*DiracDelta(t - 3)
|
||||
assert ILT(exp(2*s), s, t) == InverseLaplaceTransform(exp(2*s), s, t, None)
|
||||
r = Symbol('r', real=True)
|
||||
assert ILT(exp(r*s), s, t) == InverseLaplaceTransform(exp(r*s), s, t, None)
|
||||
# Rules for testing whether Heaviside(t) is treated properly in diff rule
|
||||
assert ILT(s**2/(a**2 + s**2), s, t) == (
|
||||
-a*sin(a*t)*Heaviside(t) + DiracDelta(t))
|
||||
assert ILT(s**2*(f(s) + 1/(a**2 + s**2)), s, t) == (
|
||||
-a*sin(a*t)*Heaviside(t) + DiracDelta(t) +
|
||||
Derivative(InverseLaplaceTransform(f(s), s, t, None), (t, 2)))
|
||||
# Rules from the previous test_inverse_laplace_transform_delta_cond():
|
||||
assert (ILT(exp(r*s), s, t, noconds=False) ==
|
||||
(InverseLaplaceTransform(exp(r*s), s, t, None), True))
|
||||
# inversion does not exist: verify it doesn't evaluate to DiracDelta
|
||||
for z in (Symbol('z', extended_real=False),
|
||||
Symbol('z', imaginary=True, zero=False)):
|
||||
f = ILT(exp(z*s), s, t, noconds=False)
|
||||
f = f[0] if isinstance(f, tuple) else f
|
||||
assert f.func != DiracDelta
|
||||
|
||||
|
||||
@slow
|
||||
def test_expint():
|
||||
x = Symbol('x')
|
||||
a = Symbol('a')
|
||||
u = Symbol('u', polar=True)
|
||||
|
||||
# TODO LT of Si, Shi, Chi is a mess ...
|
||||
assert laplace_transform(Ci(x), x, s) == (-log(1 + s**2)/2/s, 0, True)
|
||||
assert (laplace_transform(expint(a, x), x, s, simplify=True) ==
|
||||
(lerchphi(s*exp_polar(I*pi), 1, a), 0, re(a) > S.Zero))
|
||||
assert (laplace_transform(expint(1, x), x, s, simplify=True) ==
|
||||
(log(s + 1)/s, 0, True))
|
||||
assert (laplace_transform(expint(2, x), x, s, simplify=True) ==
|
||||
((s - log(s + 1))/s**2, 0, True))
|
||||
assert (inverse_laplace_transform(-log(1 + s**2)/2/s, s, u).expand() ==
|
||||
Heaviside(u)*Ci(u))
|
||||
assert (
|
||||
inverse_laplace_transform(log(s + 1)/s, s, x,
|
||||
simplify=True).rewrite(expint) ==
|
||||
Heaviside(x)*E1(x))
|
||||
assert (
|
||||
inverse_laplace_transform(
|
||||
(s - log(s + 1))/s**2, s, x,
|
||||
simplify=True).rewrite(expint).expand() ==
|
||||
(expint(2, x)*Heaviside(x)).rewrite(Ei).rewrite(expint).expand())
|
||||
@@ -0,0 +1,13 @@
|
||||
from sympy.core.numbers import E
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.exponential import log
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.geometry.curve import Curve
|
||||
from sympy.integrals.integrals import line_integrate
|
||||
|
||||
s, t, x, y, z = symbols('s,t,x,y,z')
|
||||
|
||||
|
||||
def test_lineintegral():
|
||||
c = Curve([E**t + 1, E**t - 1], (t, 0, log(2)))
|
||||
assert line_integrate(x + y, c, [x, y]) == 3*sqrt(2)
|
||||
@@ -0,0 +1,714 @@
|
||||
from sympy.core.expr import Expr
|
||||
from sympy.core.mul import Mul
|
||||
from sympy.core.function import (Derivative, Function, diff, expand)
|
||||
from sympy.core.numbers import (I, Rational, pi)
|
||||
from sympy.core.relational import Ne
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Dummy, Symbol, symbols)
|
||||
from sympy.functions.elementary.exponential import (exp, log)
|
||||
from sympy.functions.elementary.hyperbolic import (asinh, csch, cosh, coth, sech, sinh, tanh)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.piecewise import Piecewise, piecewise_fold
|
||||
from sympy.functions.elementary.trigonometric import (acos, acot, acsc, asec, asin, atan, cos, cot, csc, sec, sin, tan)
|
||||
from sympy.functions.special.delta_functions import Heaviside, DiracDelta
|
||||
from sympy.functions.special.elliptic_integrals import (elliptic_e, elliptic_f)
|
||||
from sympy.functions.special.error_functions import (Chi, Ci, Ei, Shi, Si, erf, erfi, fresnelc, fresnels, li)
|
||||
from sympy.functions.special.gamma_functions import uppergamma
|
||||
from sympy.functions.special.polynomials import (assoc_laguerre, chebyshevt, chebyshevu, gegenbauer, hermite, jacobi, laguerre, legendre)
|
||||
from sympy.functions.special.zeta_functions import polylog
|
||||
from sympy.integrals.integrals import (Integral, integrate)
|
||||
from sympy.logic.boolalg import And
|
||||
from sympy.integrals.manualintegrate import (manualintegrate, find_substitutions,
|
||||
_parts_rule, integral_steps, manual_subs)
|
||||
from sympy.testing.pytest import raises, slow
|
||||
|
||||
x, y, z, u, n, a, b, c, d, e = symbols('x y z u n a b c d e')
|
||||
f = Function('f')
|
||||
|
||||
|
||||
def assert_is_integral_of(f: Expr, F: Expr):
|
||||
assert manualintegrate(f, x) == F
|
||||
assert F.diff(x).equals(f)
|
||||
|
||||
|
||||
def test_find_substitutions():
|
||||
assert find_substitutions((cot(x)**2 + 1)**2*csc(x)**2*cot(x)**2, x, u) == \
|
||||
[(cot(x), 1, -u**6 - 2*u**4 - u**2)]
|
||||
assert find_substitutions((sec(x)**2 + tan(x) * sec(x)) / (sec(x) + tan(x)),
|
||||
x, u) == [(sec(x) + tan(x), 1, 1/u)]
|
||||
assert (-x**2, Rational(-1, 2), exp(u)) in find_substitutions(x * exp(-x**2), x, u)
|
||||
assert not find_substitutions(Derivative(f(x), x)**2, x, u)
|
||||
|
||||
|
||||
def test_manualintegrate_polynomials():
|
||||
assert manualintegrate(y, x) == x*y
|
||||
assert manualintegrate(exp(2), x) == x * exp(2)
|
||||
assert manualintegrate(x**2, x) == x**3 / 3
|
||||
assert manualintegrate(3 * x**2 + 4 * x**3, x) == x**3 + x**4
|
||||
|
||||
assert manualintegrate((x + 2)**3, x) == (x + 2)**4 / 4
|
||||
assert manualintegrate((3*x + 4)**2, x) == (3*x + 4)**3 / 9
|
||||
|
||||
assert manualintegrate((u + 2)**3, u) == (u + 2)**4 / 4
|
||||
assert manualintegrate((3*u + 4)**2, u) == (3*u + 4)**3 / 9
|
||||
|
||||
|
||||
def test_manualintegrate_exponentials():
|
||||
assert manualintegrate(exp(2*x), x) == exp(2*x) / 2
|
||||
assert manualintegrate(2**x, x) == (2 ** x) / log(2)
|
||||
assert_is_integral_of(1/sqrt(1-exp(2*x)),
|
||||
log(sqrt(1 - exp(2*x)) - 1)/2 - log(sqrt(1 - exp(2*x)) + 1)/2)
|
||||
|
||||
assert manualintegrate(1 / x, x) == log(x)
|
||||
assert manualintegrate(1 / (2*x + 3), x) == log(2*x + 3) / 2
|
||||
assert manualintegrate(log(x)**2 / x, x) == log(x)**3 / 3
|
||||
|
||||
assert_is_integral_of(x**x*(log(x)+1), x**x)
|
||||
|
||||
|
||||
def test_manualintegrate_parts():
|
||||
assert manualintegrate(exp(x) * sin(x), x) == \
|
||||
(exp(x) * sin(x)) / 2 - (exp(x) * cos(x)) / 2
|
||||
assert manualintegrate(2*x*cos(x), x) == 2*x*sin(x) + 2*cos(x)
|
||||
assert manualintegrate(x * log(x), x) == x**2*log(x)/2 - x**2/4
|
||||
assert manualintegrate(log(x), x) == x * log(x) - x
|
||||
assert manualintegrate((3*x**2 + 5) * exp(x), x) == \
|
||||
3*x**2*exp(x) - 6*x*exp(x) + 11*exp(x)
|
||||
assert manualintegrate(atan(x), x) == x*atan(x) - log(x**2 + 1)/2
|
||||
|
||||
# Make sure _parts_rule doesn't pick u = constant but can pick dv =
|
||||
# constant if necessary, e.g. for integrate(atan(x))
|
||||
assert _parts_rule(cos(x), x) == None
|
||||
assert _parts_rule(exp(x), x) == None
|
||||
assert _parts_rule(x**2, x) == None
|
||||
result = _parts_rule(atan(x), x)
|
||||
assert result[0] == atan(x) and result[1] == 1
|
||||
|
||||
|
||||
def test_manualintegrate_trigonometry():
|
||||
assert manualintegrate(sin(x), x) == -cos(x)
|
||||
assert manualintegrate(tan(x), x) == -log(cos(x))
|
||||
|
||||
assert manualintegrate(sec(x), x) == log(sec(x) + tan(x))
|
||||
assert manualintegrate(csc(x), x) == -log(csc(x) + cot(x))
|
||||
|
||||
assert manualintegrate(sin(x) * cos(x), x) in [sin(x) ** 2 / 2, -cos(x)**2 / 2]
|
||||
assert manualintegrate(-sec(x) * tan(x), x) == -sec(x)
|
||||
assert manualintegrate(csc(x) * cot(x), x) == -csc(x)
|
||||
assert manualintegrate(sec(x)**2, x) == tan(x)
|
||||
assert manualintegrate(csc(x)**2, x) == -cot(x)
|
||||
|
||||
assert manualintegrate(x * sec(x**2), x) == log(tan(x**2) + sec(x**2))/2
|
||||
assert manualintegrate(cos(x)*csc(sin(x)), x) == -log(cot(sin(x)) + csc(sin(x)))
|
||||
assert manualintegrate(cos(3*x)*sec(x), x) == -x + sin(2*x)
|
||||
assert manualintegrate(sin(3*x)*sec(x), x) == \
|
||||
-3*log(cos(x)) + 2*log(cos(x)**2) - 2*cos(x)**2
|
||||
|
||||
assert_is_integral_of(sinh(2*x), cosh(2*x)/2)
|
||||
assert_is_integral_of(x*cosh(x**2), sinh(x**2)/2)
|
||||
assert_is_integral_of(tanh(x), log(cosh(x)))
|
||||
assert_is_integral_of(coth(x), log(sinh(x)))
|
||||
f, F = sech(x), 2*atan(tanh(x/2))
|
||||
assert manualintegrate(f, x) == F
|
||||
assert (F.diff(x) - f).rewrite(exp).simplify() == 0 # todo: equals returns None
|
||||
f, F = csch(x), log(tanh(x/2))
|
||||
assert manualintegrate(f, x) == F
|
||||
assert (F.diff(x) - f).rewrite(exp).simplify() == 0
|
||||
|
||||
|
||||
@slow
|
||||
def test_manualintegrate_trigpowers():
|
||||
assert manualintegrate(sin(x)**2 * cos(x), x) == sin(x)**3 / 3
|
||||
assert manualintegrate(sin(x)**2 * cos(x) **2, x) == \
|
||||
x / 8 - sin(4*x) / 32
|
||||
assert manualintegrate(sin(x) * cos(x)**3, x) == -cos(x)**4 / 4
|
||||
assert manualintegrate(sin(x)**3 * cos(x)**2, x) == \
|
||||
cos(x)**5 / 5 - cos(x)**3 / 3
|
||||
|
||||
assert manualintegrate(tan(x)**3 * sec(x), x) == sec(x)**3/3 - sec(x)
|
||||
assert manualintegrate(tan(x) * sec(x) **2, x) == sec(x)**2/2
|
||||
|
||||
assert manualintegrate(cot(x)**5 * csc(x), x) == \
|
||||
-csc(x)**5/5 + 2*csc(x)**3/3 - csc(x)
|
||||
assert manualintegrate(cot(x)**2 * csc(x)**6, x) == \
|
||||
-cot(x)**7/7 - 2*cot(x)**5/5 - cot(x)**3/3
|
||||
|
||||
|
||||
@slow
|
||||
def test_manualintegrate_inversetrig():
|
||||
# atan
|
||||
assert manualintegrate(exp(x) / (1 + exp(2*x)), x) == atan(exp(x))
|
||||
assert manualintegrate(1 / (4 + 9 * x**2), x) == atan(3 * x/2) / 6
|
||||
assert manualintegrate(1 / (16 + 16 * x**2), x) == atan(x) / 16
|
||||
assert manualintegrate(1 / (4 + x**2), x) == atan(x / 2) / 2
|
||||
assert manualintegrate(1 / (1 + 4 * x**2), x) == atan(2*x) / 2
|
||||
ra = Symbol('a', real=True)
|
||||
rb = Symbol('b', real=True)
|
||||
assert manualintegrate(1/(ra + rb*x**2), x) == \
|
||||
Piecewise((atan(x/sqrt(ra/rb))/(rb*sqrt(ra/rb)), ra/rb > 0),
|
||||
((log(x - sqrt(-ra/rb)) - log(x + sqrt(-ra/rb)))/(2*sqrt(rb)*sqrt(-ra)), True))
|
||||
assert manualintegrate(1/(4 + rb*x**2), x) == \
|
||||
Piecewise((atan(x/(2*sqrt(1/rb)))/(2*rb*sqrt(1/rb)), 1/rb > 0),
|
||||
(-I*(log(x - 2*sqrt(-1/rb)) - log(x + 2*sqrt(-1/rb)))/(4*sqrt(rb)), True))
|
||||
assert manualintegrate(1/(ra + 4*x**2), x) == \
|
||||
Piecewise((atan(2*x/sqrt(ra))/(2*sqrt(ra)), ra > 0),
|
||||
((log(x - sqrt(-ra)/2) - log(x + sqrt(-ra)/2))/(4*sqrt(-ra)), True))
|
||||
assert manualintegrate(1/(4 + 4*x**2), x) == atan(x) / 4
|
||||
|
||||
assert manualintegrate(1/(a + b*x**2), x) == Piecewise((atan(x/sqrt(a/b))/(b*sqrt(a/b)), Ne(a, 0)),
|
||||
(-1/(b*x), True))
|
||||
|
||||
# asin
|
||||
assert manualintegrate(1/sqrt(1-x**2), x) == asin(x)
|
||||
assert manualintegrate(1/sqrt(4-4*x**2), x) == asin(x)/2
|
||||
assert manualintegrate(3/sqrt(1-9*x**2), x) == asin(3*x)
|
||||
assert manualintegrate(1/sqrt(4-9*x**2), x) == asin(x*Rational(3, 2))/3
|
||||
|
||||
# asinh
|
||||
assert manualintegrate(1/sqrt(x**2 + 1), x) == \
|
||||
asinh(x)
|
||||
assert manualintegrate(1/sqrt(x**2 + 4), x) == \
|
||||
asinh(x/2)
|
||||
assert manualintegrate(1/sqrt(4*x**2 + 4), x) == \
|
||||
asinh(x)/2
|
||||
assert manualintegrate(1/sqrt(4*x**2 + 1), x) == \
|
||||
asinh(2*x)/2
|
||||
assert manualintegrate(1/sqrt(ra*x**2 + 1), x) == \
|
||||
Piecewise((asin(x*sqrt(-ra))/sqrt(-ra), ra < 0), (asinh(sqrt(ra)*x)/sqrt(ra), ra > 0), (x, True))
|
||||
assert manualintegrate(1/sqrt(ra + x**2), x) == \
|
||||
Piecewise((asinh(x*sqrt(1/ra)), ra > 0), (log(2*x + 2*sqrt(ra + x**2)), True))
|
||||
|
||||
# log
|
||||
assert manualintegrate(1/sqrt(x**2 - 1), x) == log(2*x + 2*sqrt(x**2 - 1))
|
||||
assert manualintegrate(1/sqrt(x**2 - 4), x) == log(2*x + 2*sqrt(x**2 - 4))
|
||||
assert manualintegrate(1/sqrt(4*x**2 - 4), x) == log(8*x + 4*sqrt(4*x**2 - 4))/2
|
||||
assert manualintegrate(1/sqrt(9*x**2 - 1), x) == log(18*x + 6*sqrt(9*x**2 - 1))/3
|
||||
assert manualintegrate(1/sqrt(ra*x**2 - 4), x) == \
|
||||
Piecewise((log(2*sqrt(ra)*sqrt(ra*x**2 - 4) + 2*ra*x)/sqrt(ra), Ne(ra, 0)), (-I*x/2, True))
|
||||
assert manualintegrate(1/sqrt(-ra + 4*x**2), x) == \
|
||||
Piecewise((asinh(2*x*sqrt(-1/ra))/2, ra < 0), (log(8*x + 4*sqrt(-ra + 4*x**2))/2, True))
|
||||
|
||||
# From https://www.wikiwand.com/en/List_of_integrals_of_inverse_trigonometric_functions
|
||||
# asin
|
||||
assert manualintegrate(asin(x), x) == x*asin(x) + sqrt(1 - x**2)
|
||||
assert manualintegrate(asin(a*x), x) == Piecewise(((a*x*asin(a*x) + sqrt(-a**2*x**2 + 1))/a, Ne(a, 0)), (0, True))
|
||||
assert manualintegrate(x*asin(a*x), x) == \
|
||||
-a*Piecewise((-x*sqrt(-a**2*x**2 + 1)/(2*a**2) +
|
||||
log(-2*a**2*x + 2*sqrt(-a**2)*sqrt(-a**2*x**2 + 1))/(2*a**2*sqrt(-a**2)), Ne(a**2, 0)),
|
||||
(x**3/3, True))/2 + x**2*asin(a*x)/2
|
||||
# acos
|
||||
assert manualintegrate(acos(x), x) == x*acos(x) - sqrt(1 - x**2)
|
||||
assert manualintegrate(acos(a*x), x) == Piecewise(((a*x*acos(a*x) - sqrt(-a**2*x**2 + 1))/a, Ne(a, 0)), (pi*x/2, True))
|
||||
assert manualintegrate(x*acos(a*x), x) == \
|
||||
a*Piecewise((-x*sqrt(-a**2*x**2 + 1)/(2*a**2) +
|
||||
log(-2*a**2*x + 2*sqrt(-a**2)*sqrt(-a**2*x**2 + 1))/(2*a**2*sqrt(-a**2)), Ne(a**2, 0)),
|
||||
(x**3/3, True))/2 + x**2*acos(a*x)/2
|
||||
# atan
|
||||
assert manualintegrate(atan(x), x) == x*atan(x) - log(x**2 + 1)/2
|
||||
assert manualintegrate(atan(a*x), x) == Piecewise(((a*x*atan(a*x) - log(a**2*x**2 + 1)/2)/a, Ne(a, 0)), (0, True))
|
||||
assert manualintegrate(x*atan(a*x), x) == -a*(x/a**2 - atan(x/sqrt(a**(-2)))/(a**4*sqrt(a**(-2))))/2 + x**2*atan(a*x)/2
|
||||
# acsc
|
||||
assert manualintegrate(acsc(x), x) == x*acsc(x) + Integral(1/(x*sqrt(1 - 1/x**2)), x)
|
||||
assert manualintegrate(acsc(a*x), x) == x*acsc(a*x) + Integral(1/(x*sqrt(1 - 1/(a**2*x**2))), x)/a
|
||||
assert manualintegrate(x*acsc(a*x), x) == x**2*acsc(a*x)/2 + Integral(1/sqrt(1 - 1/(a**2*x**2)), x)/(2*a)
|
||||
# asec
|
||||
assert manualintegrate(asec(x), x) == x*asec(x) - Integral(1/(x*sqrt(1 - 1/x**2)), x)
|
||||
assert manualintegrate(asec(a*x), x) == x*asec(a*x) - Integral(1/(x*sqrt(1 - 1/(a**2*x**2))), x)/a
|
||||
assert manualintegrate(x*asec(a*x), x) == x**2*asec(a*x)/2 - Integral(1/sqrt(1 - 1/(a**2*x**2)), x)/(2*a)
|
||||
# acot
|
||||
assert manualintegrate(acot(x), x) == x*acot(x) + log(x**2 + 1)/2
|
||||
assert manualintegrate(acot(a*x), x) == Piecewise(((a*x*acot(a*x) + log(a**2*x**2 + 1)/2)/a, Ne(a, 0)), (pi*x/2, True))
|
||||
assert manualintegrate(x*acot(a*x), x) == a*(x/a**2 - atan(x/sqrt(a**(-2)))/(a**4*sqrt(a**(-2))))/2 + x**2*acot(a*x)/2
|
||||
|
||||
# piecewise
|
||||
assert manualintegrate(1/sqrt(ra-rb*x**2), x) == \
|
||||
Piecewise((asin(x*sqrt(rb/ra))/sqrt(rb), And(-rb < 0, ra > 0)),
|
||||
(asinh(x*sqrt(-rb/ra))/sqrt(-rb), And(-rb > 0, ra > 0)),
|
||||
(log(-2*rb*x + 2*sqrt(-rb)*sqrt(ra - rb*x**2))/sqrt(-rb), Ne(rb, 0)),
|
||||
(x/sqrt(ra), True))
|
||||
assert manualintegrate(1/sqrt(ra + rb*x**2), x) == \
|
||||
Piecewise((asin(x*sqrt(-rb/ra))/sqrt(-rb), And(ra > 0, rb < 0)),
|
||||
(asinh(x*sqrt(rb/ra))/sqrt(rb), And(ra > 0, rb > 0)),
|
||||
(log(2*sqrt(rb)*sqrt(ra + rb*x**2) + 2*rb*x)/sqrt(rb), Ne(rb, 0)),
|
||||
(x/sqrt(ra), True))
|
||||
|
||||
|
||||
def test_manualintegrate_trig_substitution():
|
||||
assert manualintegrate(sqrt(16*x**2 - 9)/x, x) == \
|
||||
Piecewise((sqrt(16*x**2 - 9) - 3*acos(3/(4*x)),
|
||||
And(x < Rational(3, 4), x > Rational(-3, 4))))
|
||||
assert manualintegrate(1/(x**4 * sqrt(25-x**2)), x) == \
|
||||
Piecewise((-sqrt(-x**2/25 + 1)/(125*x) -
|
||||
(-x**2/25 + 1)**(3*S.Half)/(15*x**3), And(x < 5, x > -5)))
|
||||
assert manualintegrate(x**7/(49*x**2 + 1)**(3 * S.Half), x) == \
|
||||
((49*x**2 + 1)**(5*S.Half)/28824005 -
|
||||
(49*x**2 + 1)**(3*S.Half)/5764801 +
|
||||
3*sqrt(49*x**2 + 1)/5764801 + 1/(5764801*sqrt(49*x**2 + 1)))
|
||||
|
||||
def test_manualintegrate_trivial_substitution():
|
||||
assert manualintegrate((exp(x) - exp(-x))/x, x) == -Ei(-x) + Ei(x)
|
||||
f = Function('f')
|
||||
assert manualintegrate((f(x) - f(-x))/x, x) == \
|
||||
-Integral(f(-x)/x, x) + Integral(f(x)/x, x)
|
||||
|
||||
|
||||
def test_manualintegrate_rational():
|
||||
assert manualintegrate(1/(4 - x**2), x) == -log(x - 2)/4 + log(x + 2)/4
|
||||
assert manualintegrate(1/(-1 + x**2), x) == log(x - 1)/2 - log(x + 1)/2
|
||||
|
||||
|
||||
def test_manualintegrate_special():
|
||||
f, F = 4*exp(-x**2/3), 2*sqrt(3)*sqrt(pi)*erf(sqrt(3)*x/3)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = 3*exp(4*x**2), 3*sqrt(pi)*erfi(2*x)/4
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = x**Rational(1, 3)*exp(-x/8), -16*uppergamma(Rational(4, 3), x/8)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = exp(2*x)/x, Ei(2*x)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = exp(1 + 2*x - x**2), sqrt(pi)*exp(2)*erf(x - 1)/2
|
||||
assert_is_integral_of(f, F)
|
||||
f = sin(x**2 + 4*x + 1)
|
||||
F = (sqrt(2)*sqrt(pi)*(-sin(3)*fresnelc(sqrt(2)*(2*x + 4)/(2*sqrt(pi))) +
|
||||
cos(3)*fresnels(sqrt(2)*(2*x + 4)/(2*sqrt(pi))))/2)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = cos(4*x**2), sqrt(2)*sqrt(pi)*fresnelc(2*sqrt(2)*x/sqrt(pi))/4
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = sin(3*x + 2)/x, sin(2)*Ci(3*x) + cos(2)*Si(3*x)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = sinh(3*x - 2)/x, -sinh(2)*Chi(3*x) + cosh(2)*Shi(3*x)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = 5*cos(2*x - 3)/x, 5*cos(3)*Ci(2*x) + 5*sin(3)*Si(2*x)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = cosh(x/2)/x, Chi(x/2)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = cos(x**2)/x, Ci(x**2)/2
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = 1/log(2*x + 1), li(2*x + 1)/2
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = polylog(2, 5*x)/x, polylog(3, 5*x)
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = 5/sqrt(3 - 2*sin(x)**2), 5*sqrt(3)*elliptic_f(x, Rational(2, 3))/3
|
||||
assert_is_integral_of(f, F)
|
||||
f, F = sqrt(4 + 9*sin(x)**2), 2*elliptic_e(x, Rational(-9, 4))
|
||||
assert_is_integral_of(f, F)
|
||||
|
||||
|
||||
def test_manualintegrate_derivative():
|
||||
assert manualintegrate(pi * Derivative(x**2 + 2*x + 3), x) == \
|
||||
pi * (x**2 + 2*x + 3)
|
||||
assert manualintegrate(Derivative(x**2 + 2*x + 3, y), x) == \
|
||||
Integral(Derivative(x**2 + 2*x + 3, y))
|
||||
assert manualintegrate(Derivative(sin(x), x, x, x, y), x) == \
|
||||
Derivative(sin(x), x, x, y)
|
||||
|
||||
|
||||
def test_manualintegrate_Heaviside():
|
||||
assert_is_integral_of(DiracDelta(3*x+2), Heaviside(3*x+2)/3)
|
||||
assert_is_integral_of(DiracDelta(3*x, 0), Heaviside(3*x)/3)
|
||||
assert manualintegrate(DiracDelta(a+b*x, 1), x) == \
|
||||
Piecewise((DiracDelta(a + b*x)/b, Ne(b, 0)), (x*DiracDelta(a, 1), True))
|
||||
assert_is_integral_of(DiracDelta(x/3-1, 2), 3*DiracDelta(x/3-1, 1))
|
||||
assert manualintegrate(Heaviside(x), x) == x*Heaviside(x)
|
||||
assert manualintegrate(x*Heaviside(2), x) == x**2/2
|
||||
assert manualintegrate(x*Heaviside(-2), x) == 0
|
||||
assert manualintegrate(x*Heaviside( x), x) == x**2*Heaviside( x)/2
|
||||
assert manualintegrate(x*Heaviside(-x), x) == x**2*Heaviside(-x)/2
|
||||
assert manualintegrate(Heaviside(2*x + 4), x) == (x+2)*Heaviside(2*x + 4)
|
||||
assert manualintegrate(x*Heaviside(x), x) == x**2*Heaviside(x)/2
|
||||
assert manualintegrate(Heaviside(x + 1)*Heaviside(1 - x)*x**2, x) == \
|
||||
((x**3/3 + Rational(1, 3))*Heaviside(x + 1) - Rational(2, 3))*Heaviside(-x + 1)
|
||||
|
||||
y = Symbol('y')
|
||||
assert manualintegrate(sin(7 + x)*Heaviside(3*x - 7), x) == \
|
||||
(- cos(x + 7) + cos(Rational(28, 3)))*Heaviside(3*x - S(7))
|
||||
|
||||
assert manualintegrate(sin(y + x)*Heaviside(3*x - y), x) == \
|
||||
(cos(y*Rational(4, 3)) - cos(x + y))*Heaviside(3*x - y)
|
||||
|
||||
|
||||
def test_manualintegrate_orthogonal_poly():
|
||||
n = symbols('n')
|
||||
a, b = 7, Rational(5, 3)
|
||||
polys = [jacobi(n, a, b, x), gegenbauer(n, a, x), chebyshevt(n, x),
|
||||
chebyshevu(n, x), legendre(n, x), hermite(n, x), laguerre(n, x),
|
||||
assoc_laguerre(n, a, x)]
|
||||
for p in polys:
|
||||
integral = manualintegrate(p, x)
|
||||
for deg in [-2, -1, 0, 1, 3, 5, 8]:
|
||||
# some accept negative "degree", some do not
|
||||
try:
|
||||
p_subbed = p.subs(n, deg)
|
||||
except ValueError:
|
||||
continue
|
||||
assert (integral.subs(n, deg).diff(x) - p_subbed).expand() == 0
|
||||
|
||||
# can also integrate simple expressions with these polynomials
|
||||
q = x*p.subs(x, 2*x + 1)
|
||||
integral = manualintegrate(q, x)
|
||||
for deg in [2, 4, 7]:
|
||||
assert (integral.subs(n, deg).diff(x) - q.subs(n, deg)).expand() == 0
|
||||
|
||||
# cannot integrate with respect to any other parameter
|
||||
t = symbols('t')
|
||||
for i in range(len(p.args) - 1):
|
||||
new_args = list(p.args)
|
||||
new_args[i] = t
|
||||
assert isinstance(manualintegrate(p.func(*new_args), t), Integral)
|
||||
|
||||
|
||||
@slow
|
||||
def test_issue_6799():
|
||||
r, x, phi = map(Symbol, 'r x phi'.split())
|
||||
n = Symbol('n', integer=True, positive=True)
|
||||
|
||||
integrand = (cos(n*(x-phi))*cos(n*x))
|
||||
limits = (x, -pi, pi)
|
||||
assert manualintegrate(integrand, x) == \
|
||||
((n*x/2 + sin(2*n*x)/4)*cos(n*phi) - sin(n*phi)*cos(n*x)**2/2)/n
|
||||
assert r * integrate(integrand, limits).trigsimp() / pi == r * cos(n * phi)
|
||||
assert not integrate(integrand, limits).has(Dummy)
|
||||
|
||||
|
||||
def test_issue_12251():
|
||||
assert manualintegrate(x**y, x) == Piecewise(
|
||||
(x**(y + 1)/(y + 1), Ne(y, -1)), (log(x), True))
|
||||
|
||||
|
||||
def test_issue_3796():
|
||||
assert manualintegrate(diff(exp(x + x**2)), x) == exp(x + x**2)
|
||||
assert integrate(x * exp(x**4), x, risch=False) == -I*sqrt(pi)*erf(I*x**2)/4
|
||||
|
||||
|
||||
def test_manual_true():
|
||||
assert integrate(exp(x) * sin(x), x, manual=True) == \
|
||||
(exp(x) * sin(x)) / 2 - (exp(x) * cos(x)) / 2
|
||||
assert integrate(sin(x) * cos(x), x, manual=True) in \
|
||||
[sin(x) ** 2 / 2, -cos(x)**2 / 2]
|
||||
|
||||
|
||||
def test_issue_6746():
|
||||
y = Symbol('y')
|
||||
n = Symbol('n')
|
||||
assert manualintegrate(y**x, x) == Piecewise(
|
||||
(y**x/log(y), Ne(log(y), 0)), (x, True))
|
||||
assert manualintegrate(y**(n*x), x) == Piecewise(
|
||||
(Piecewise(
|
||||
(y**(n*x)/log(y), Ne(log(y), 0)),
|
||||
(n*x, True)
|
||||
)/n, Ne(n, 0)),
|
||||
(x, True))
|
||||
assert manualintegrate(exp(n*x), x) == Piecewise(
|
||||
(exp(n*x)/n, Ne(n, 0)), (x, True))
|
||||
|
||||
y = Symbol('y', positive=True)
|
||||
assert manualintegrate((y + 1)**x, x) == (y + 1)**x/log(y + 1)
|
||||
y = Symbol('y', zero=True)
|
||||
assert manualintegrate((y + 1)**x, x) == x
|
||||
y = Symbol('y')
|
||||
n = Symbol('n', nonzero=True)
|
||||
assert manualintegrate(y**(n*x), x) == Piecewise(
|
||||
(y**(n*x)/log(y), Ne(log(y), 0)), (n*x, True))/n
|
||||
y = Symbol('y', positive=True)
|
||||
assert manualintegrate((y + 1)**(n*x), x) == \
|
||||
(y + 1)**(n*x)/(n*log(y + 1))
|
||||
a = Symbol('a', negative=True)
|
||||
b = Symbol('b')
|
||||
assert manualintegrate(1/(a + b*x**2), x) == atan(x/sqrt(a/b))/(b*sqrt(a/b))
|
||||
b = Symbol('b', negative=True)
|
||||
assert manualintegrate(1/(a + b*x**2), x) == \
|
||||
atan(x/(sqrt(-a)*sqrt(-1/b)))/(b*sqrt(-a)*sqrt(-1/b))
|
||||
assert manualintegrate(1/((x**a + y**b + 4)*sqrt(a*x**2 + 1)), x) == \
|
||||
y**(-b)*Integral(x**(-a)/(y**(-b)*sqrt(a*x**2 + 1) +
|
||||
x**(-a)*sqrt(a*x**2 + 1) + 4*x**(-a)*y**(-b)*sqrt(a*x**2 + 1)), x)
|
||||
assert manualintegrate(1/((x**2 + 4)*sqrt(4*x**2 + 1)), x) == \
|
||||
Integral(1/((x**2 + 4)*sqrt(4*x**2 + 1)), x)
|
||||
assert manualintegrate(1/(x - a**x + x*b**2), x) == \
|
||||
Integral(1/(-a**x + b**2*x + x), x)
|
||||
|
||||
|
||||
@slow
|
||||
def test_issue_2850():
|
||||
assert manualintegrate(asin(x)*log(x), x) == -x*asin(x) - sqrt(-x**2 + 1) \
|
||||
+ (x*asin(x) + sqrt(-x**2 + 1))*log(x) - Integral(sqrt(-x**2 + 1)/x, x)
|
||||
assert manualintegrate(acos(x)*log(x), x) == -x*acos(x) + sqrt(-x**2 + 1) + \
|
||||
(x*acos(x) - sqrt(-x**2 + 1))*log(x) + Integral(sqrt(-x**2 + 1)/x, x)
|
||||
assert manualintegrate(atan(x)*log(x), x) == -x*atan(x) + (x*atan(x) - \
|
||||
log(x**2 + 1)/2)*log(x) + log(x**2 + 1)/2 + Integral(log(x**2 + 1)/x, x)/2
|
||||
|
||||
|
||||
def test_issue_9462():
|
||||
assert manualintegrate(sin(2*x)*exp(x), x) == exp(x)*sin(2*x)/5 - 2*exp(x)*cos(2*x)/5
|
||||
assert not integral_steps(sin(2*x)*exp(x), x).contains_dont_know()
|
||||
assert manualintegrate((x - 3) / (x**2 - 2*x + 2)**2, x) == \
|
||||
Integral(x/(x**4 - 4*x**3 + 8*x**2 - 8*x + 4), x) \
|
||||
- 3*Integral(1/(x**4 - 4*x**3 + 8*x**2 - 8*x + 4), x)
|
||||
|
||||
|
||||
def test_cyclic_parts():
|
||||
f = cos(x)*exp(x/4)
|
||||
F = 16*exp(x/4)*sin(x)/17 + 4*exp(x/4)*cos(x)/17
|
||||
assert manualintegrate(f, x) == F and F.diff(x) == f
|
||||
f = x*cos(x)*exp(x/4)
|
||||
F = (x*(16*exp(x/4)*sin(x)/17 + 4*exp(x/4)*cos(x)/17) -
|
||||
128*exp(x/4)*sin(x)/289 + 240*exp(x/4)*cos(x)/289)
|
||||
assert manualintegrate(f, x) == F and F.diff(x) == f
|
||||
|
||||
|
||||
@slow
|
||||
def test_issue_10847_slow():
|
||||
assert manualintegrate((4*x**4 + 4*x**3 + 16*x**2 + 12*x + 8)
|
||||
/ (x**6 + 2*x**5 + 3*x**4 + 4*x**3 + 3*x**2 + 2*x + 1), x) == \
|
||||
2*x/(x**2 + 1) + 3*atan(x) - 1/(x**2 + 1) - 3/(x + 1)
|
||||
|
||||
|
||||
@slow
|
||||
def test_issue_10847():
|
||||
|
||||
assert manualintegrate(x**2 / (x**2 - c), x) == \
|
||||
c*Piecewise((atan(x/sqrt(-c))/sqrt(-c), Ne(c, 0)), (-1/x, True)) + x
|
||||
|
||||
rc = Symbol('c', real=True)
|
||||
assert manualintegrate(x**2 / (x**2 - rc), x) == \
|
||||
rc*Piecewise((atan(x/sqrt(-rc))/sqrt(-rc), rc < 0),
|
||||
((log(-sqrt(rc) + x) - log(sqrt(rc) + x))/(2*sqrt(rc)), True)) + x
|
||||
|
||||
assert manualintegrate(sqrt(x - y) * log(z / x), x) == \
|
||||
4*y**2*Piecewise((atan(sqrt(x - y)/sqrt(y))/sqrt(y), Ne(y, 0)),
|
||||
(-1/sqrt(x - y), True))/3 - 4*y*sqrt(x - y)/3 + \
|
||||
2*(x - y)**Rational(3, 2)*log(z/x)/3 + 4*(x - y)**Rational(3, 2)/9
|
||||
ry = Symbol('y', real=True)
|
||||
rz = Symbol('z', real=True)
|
||||
assert manualintegrate(sqrt(x - ry) * log(rz / x), x) == \
|
||||
4*ry**2*Piecewise((atan(sqrt(x - ry)/sqrt(ry))/sqrt(ry), ry > 0),
|
||||
((log(-sqrt(-ry) + sqrt(x - ry)) - log(sqrt(-ry) + sqrt(x - ry)))/(2*sqrt(-ry)), True))/3 \
|
||||
- 4*ry*sqrt(x - ry)/3 + 2*(x - ry)**Rational(3, 2)*log(rz/x)/3 \
|
||||
+ 4*(x - ry)**Rational(3, 2)/9
|
||||
|
||||
assert manualintegrate(sqrt(x) * log(x), x) == 2*x**Rational(3, 2)*log(x)/3 - 4*x**Rational(3, 2)/9
|
||||
|
||||
result = manualintegrate(sqrt(a*x + b) / x, x)
|
||||
assert result == Piecewise((-2*b*Piecewise(
|
||||
(-atan(sqrt(a*x + b)/sqrt(-b))/sqrt(-b), Ne(b, 0)),
|
||||
(1/sqrt(a*x + b), True)) + 2*sqrt(a*x + b), Ne(a, 0)),
|
||||
(sqrt(b)*log(x), True))
|
||||
assert piecewise_fold(result) == Piecewise(
|
||||
(2*b*atan(sqrt(a*x + b)/sqrt(-b))/sqrt(-b) + 2*sqrt(a*x + b), Ne(a, 0) & Ne(b, 0)),
|
||||
(-2*b/sqrt(a*x + b) + 2*sqrt(a*x + b), Ne(a, 0)),
|
||||
(sqrt(b)*log(x), True))
|
||||
|
||||
ra = Symbol('a', real=True)
|
||||
rb = Symbol('b', real=True)
|
||||
assert manualintegrate(sqrt(ra*x + rb) / x, x) == \
|
||||
Piecewise(
|
||||
(-2*rb*Piecewise(
|
||||
(-atan(sqrt(ra*x + rb)/sqrt(-rb))/sqrt(-rb), rb < 0),
|
||||
(-I*(log(-sqrt(rb) + sqrt(ra*x + rb)) - log(sqrt(rb) + sqrt(ra*x + rb)))/(2*sqrt(-rb)), True)) +
|
||||
2*sqrt(ra*x + rb), Ne(ra, 0)),
|
||||
(sqrt(rb)*log(x), True))
|
||||
|
||||
assert expand(manualintegrate(sqrt(ra*x + rb) / (x + rc), x)) == \
|
||||
Piecewise((-2*ra*rc*Piecewise((atan(sqrt(ra*x + rb)/sqrt(ra*rc - rb))/sqrt(ra*rc - rb), ra*rc - rb > 0),
|
||||
(log(-sqrt(-ra*rc + rb) + sqrt(ra*x + rb))/(2*sqrt(-ra*rc + rb)) -
|
||||
log(sqrt(-ra*rc + rb) + sqrt(ra*x + rb))/(2*sqrt(-ra*rc + rb)), True)) +
|
||||
2*rb*Piecewise((atan(sqrt(ra*x + rb)/sqrt(ra*rc - rb))/sqrt(ra*rc - rb), ra*rc - rb > 0),
|
||||
(log(-sqrt(-ra*rc + rb) + sqrt(ra*x + rb))/(2*sqrt(-ra*rc + rb)) -
|
||||
log(sqrt(-ra*rc + rb) + sqrt(ra*x + rb))/(2*sqrt(-ra*rc + rb)), True)) +
|
||||
2*sqrt(ra*x + rb), Ne(ra, 0)), (sqrt(rb)*log(rc + x), True))
|
||||
|
||||
assert manualintegrate(sqrt(2*x + 3) / (x + 1), x) == 2*sqrt(2*x + 3) - log(sqrt(2*x + 3) + 1) + log(sqrt(2*x + 3) - 1)
|
||||
assert manualintegrate(sqrt(2*x + 3) / 2 * x, x) == (2*x + 3)**Rational(5, 2)/20 - (2*x + 3)**Rational(3, 2)/4
|
||||
assert manualintegrate(x**Rational(3,2) * log(x), x) == 2*x**Rational(5,2)*log(x)/5 - 4*x**Rational(5,2)/25
|
||||
assert manualintegrate(x**(-3) * log(x), x) == -log(x)/(2*x**2) - 1/(4*x**2)
|
||||
assert manualintegrate(log(y)/(y**2*(1 - 1/y)), y) == \
|
||||
log(y)*log(-1 + 1/y) - Integral(log(-1 + 1/y)/y, y)
|
||||
|
||||
|
||||
def test_issue_12899():
|
||||
assert manualintegrate(f(x,y).diff(x),y) == Integral(Derivative(f(x,y),x),y)
|
||||
assert manualintegrate(f(x,y).diff(y).diff(x),y) == Derivative(f(x,y),x)
|
||||
|
||||
|
||||
def test_constant_independent_of_symbol():
|
||||
assert manualintegrate(Integral(y, (x, 1, 2)), x) == \
|
||||
x*Integral(y, (x, 1, 2))
|
||||
|
||||
|
||||
def test_issue_12641():
|
||||
assert manualintegrate(sin(2*x), x) == -cos(2*x)/2
|
||||
assert manualintegrate(cos(x)*sin(2*x), x) == -2*cos(x)**3/3
|
||||
assert manualintegrate((sin(2*x)*cos(x))/(1 + cos(x)), x) == \
|
||||
-2*log(cos(x) + 1) - cos(x)**2 + 2*cos(x)
|
||||
|
||||
|
||||
@slow
|
||||
def test_issue_13297():
|
||||
assert manualintegrate(sin(x) * cos(x)**5, x) == -cos(x)**6 / 6
|
||||
|
||||
|
||||
def test_issue_14470():
|
||||
assert_is_integral_of(1/(x*sqrt(x + 1)), log(sqrt(x + 1) - 1) - log(sqrt(x + 1) + 1))
|
||||
|
||||
|
||||
@slow
|
||||
def test_issue_9858():
|
||||
assert manualintegrate(exp(x)*cos(exp(x)), x) == sin(exp(x))
|
||||
assert manualintegrate(exp(2*x)*cos(exp(x)), x) == \
|
||||
exp(x)*sin(exp(x)) + cos(exp(x))
|
||||
res = manualintegrate(exp(10*x)*sin(exp(x)), x)
|
||||
assert not res.has(Integral)
|
||||
assert res.diff(x) == exp(10*x)*sin(exp(x))
|
||||
# an example with many similar integrations by parts
|
||||
assert manualintegrate(sum(x*exp(k*x) for k in range(1, 8)), x) == (
|
||||
x*exp(7*x)/7 + x*exp(6*x)/6 + x*exp(5*x)/5 + x*exp(4*x)/4 +
|
||||
x*exp(3*x)/3 + x*exp(2*x)/2 + x*exp(x) - exp(7*x)/49 -exp(6*x)/36 -
|
||||
exp(5*x)/25 - exp(4*x)/16 - exp(3*x)/9 - exp(2*x)/4 - exp(x))
|
||||
|
||||
|
||||
def test_issue_8520():
|
||||
assert manualintegrate(x/(x**4 + 1), x) == atan(x**2)/2
|
||||
assert manualintegrate(x**2/(x**6 + 25), x) == atan(x**3/5)/15
|
||||
f = x/(9*x**4 + 4)**2
|
||||
assert manualintegrate(f, x).diff(x).factor() == f
|
||||
|
||||
|
||||
def test_manual_subs():
|
||||
x, y = symbols('x y')
|
||||
expr = log(x) + exp(x)
|
||||
# if log(x) is y, then exp(y) is x
|
||||
assert manual_subs(expr, log(x), y) == y + exp(exp(y))
|
||||
# if exp(x) is y, then log(y) need not be x
|
||||
assert manual_subs(expr, exp(x), y) == log(x) + y
|
||||
|
||||
raises(ValueError, lambda: manual_subs(expr, x))
|
||||
raises(ValueError, lambda: manual_subs(expr, exp(x), x, y))
|
||||
|
||||
|
||||
@slow
|
||||
def test_issue_15471():
|
||||
f = log(x)*cos(log(x))/x**Rational(3, 4)
|
||||
F = -128*x**Rational(1, 4)*sin(log(x))/289 + 240*x**Rational(1, 4)*cos(log(x))/289 + (16*x**Rational(1, 4)*sin(log(x))/17 + 4*x**Rational(1, 4)*cos(log(x))/17)*log(x)
|
||||
assert_is_integral_of(f, F)
|
||||
|
||||
|
||||
def test_quadratic_denom():
|
||||
f = (5*x + 2)/(3*x**2 - 2*x + 8)
|
||||
assert manualintegrate(f, x) == 5*log(3*x**2 - 2*x + 8)/6 + 11*sqrt(23)*atan(3*sqrt(23)*(x - Rational(1, 3))/23)/69
|
||||
g = 3/(2*x**2 + 3*x + 1)
|
||||
assert manualintegrate(g, x) == 3*log(4*x + 2) - 3*log(4*x + 4)
|
||||
|
||||
def test_issue_22757():
|
||||
assert manualintegrate(sin(x), y) == y * sin(x)
|
||||
|
||||
|
||||
def test_issue_23348():
|
||||
steps = integral_steps(tan(x), x)
|
||||
constant_times_step = steps.substep.substep
|
||||
assert constant_times_step.integrand == constant_times_step.constant * constant_times_step.other
|
||||
|
||||
|
||||
def test_issue_23566():
|
||||
i = Integral(1/sqrt(x**2 - 1), (x, -2, -1)).doit(manual=True)
|
||||
assert i == -log(4 - 2*sqrt(3)) + log(2)
|
||||
assert str(i.n()) == '1.31695789692482'
|
||||
|
||||
|
||||
def test_issue_25093():
|
||||
ap = Symbol('ap', positive=True)
|
||||
an = Symbol('an', negative=True)
|
||||
assert manualintegrate(exp(a*x**2 + b), x) == sqrt(pi)*exp(b)*erfi(sqrt(a)*x)/(2*sqrt(a))
|
||||
assert manualintegrate(exp(ap*x**2 + b), x) == sqrt(pi)*exp(b)*erfi(sqrt(ap)*x)/(2*sqrt(ap))
|
||||
assert manualintegrate(exp(an*x**2 + b), x) == -sqrt(pi)*exp(b)*erf(an*x/sqrt(-an))/(2*sqrt(-an))
|
||||
assert manualintegrate(sin(a*x**2 + b), x) == (
|
||||
sqrt(2)*sqrt(pi)*(sin(b)*fresnelc(sqrt(2)*sqrt(a)*x/sqrt(pi))
|
||||
+ cos(b)*fresnels(sqrt(2)*sqrt(a)*x/sqrt(pi)))/(2*sqrt(a)))
|
||||
assert manualintegrate(cos(a*x**2 + b), x) == (
|
||||
sqrt(2)*sqrt(pi)*(-sin(b)*fresnels(sqrt(2)*sqrt(a)*x/sqrt(pi))
|
||||
+ cos(b)*fresnelc(sqrt(2)*sqrt(a)*x/sqrt(pi)))/(2*sqrt(a)))
|
||||
|
||||
|
||||
def test_nested_pow():
|
||||
assert_is_integral_of(sqrt(x**2), x*sqrt(x**2)/2)
|
||||
assert_is_integral_of(sqrt(x**(S(5)/3)), 6*x*sqrt(x**(S(5)/3))/11)
|
||||
assert_is_integral_of(1/sqrt(x**2), x*log(x)/sqrt(x**2))
|
||||
assert_is_integral_of(x*sqrt(x**(-4)), x**2*sqrt(x**-4)*log(x))
|
||||
f = (c*(a+b*x)**d)**e
|
||||
F1 = (c*(a + b*x)**d)**e*(a/b + x)/(d*e + 1)
|
||||
F2 = (c*(a + b*x)**d)**e*(a/b + x)*log(a/b + x)
|
||||
assert manualintegrate(f, x) == \
|
||||
Piecewise((Piecewise((F1, Ne(d*e, -1)), (F2, True)), Ne(b, 0)), (x*(a**d*c)**e, True))
|
||||
assert F1.diff(x).equals(f)
|
||||
assert F2.diff(x).subs(d*e, -1).equals(f)
|
||||
|
||||
|
||||
def test_manualintegrate_sqrt_linear():
|
||||
assert_is_integral_of((5*x**3+4)/sqrt(2+3*x),
|
||||
10*(3*x + 2)**(S(7)/2)/567 - 4*(3*x + 2)**(S(5)/2)/27 +
|
||||
40*(3*x + 2)**(S(3)/2)/81 + 136*sqrt(3*x + 2)/81)
|
||||
assert manualintegrate(x/sqrt(a+b*x)**3, x) == \
|
||||
Piecewise((Mul(2, b**-2, a/sqrt(a + b*x) + sqrt(a + b*x)), Ne(b, 0)), (x**2/(2*a**(S(3)/2)), True))
|
||||
assert_is_integral_of((sqrt(3*x+3)+1)/((2*x+2)**(1/S(3))+1),
|
||||
3*sqrt(6)*(2*x + 2)**(S(7)/6)/14 - 3*sqrt(6)*(2*x + 2)**(S(5)/6)/10 -
|
||||
3*sqrt(6)*(2*x + 2)**(S.One/6)/2 + 3*(2*x + 2)**(S(2)/3)/4 - 3*(2*x + 2)**(S.One/3)/2 +
|
||||
sqrt(6)*sqrt(2*x + 2)/2 + 3*log((2*x + 2)**(S.One/3) + 1)/2 +
|
||||
3*sqrt(6)*atan((2*x + 2)**(S.One/6))/2)
|
||||
assert_is_integral_of(sqrt(x+sqrt(x)),
|
||||
2*sqrt(sqrt(x) + x)*(sqrt(x)/12 + x/3 - S(1)/8) + log(2*sqrt(x) + 2*sqrt(sqrt(x) + x) + 1)/8)
|
||||
assert_is_integral_of(sqrt(2*x+3+sqrt(4*x+5))**3,
|
||||
sqrt(2*x + sqrt(4*x + 5) + 3) *
|
||||
(9*x/10 + 11*(4*x + 5)**(S(3)/2)/40 + sqrt(4*x + 5)/40 + (4*x + 5)**2/10 + S(11)/10)/2)
|
||||
|
||||
|
||||
def test_manualintegrate_sqrt_quadratic():
|
||||
assert_is_integral_of(1/sqrt((x - I)**2-1), log(2*x + 2*sqrt(x**2 - 2*I*x - 2) - 2*I))
|
||||
assert_is_integral_of(1/sqrt(3*x**2+4*x+5), sqrt(3)*asinh(3*sqrt(11)*(x + S(2)/3)/11)/3)
|
||||
assert_is_integral_of(1/sqrt(-3*x**2+4*x+5), sqrt(3)*asin(3*sqrt(19)*(x - S(2)/3)/19)/3)
|
||||
assert_is_integral_of(1/sqrt(3*x**2+4*x-5), sqrt(3)*log(6*x + 2*sqrt(3)*sqrt(3*x**2 + 4*x - 5) + 4)/3)
|
||||
assert_is_integral_of(1/sqrt(4*x**2-4*x+1), (x - S.Half)*log(x - S.Half)/(2*sqrt((x - S.Half)**2)))
|
||||
assert manualintegrate(1/sqrt(a+b*x+c*x**2), x) == \
|
||||
Piecewise((log(b + 2*sqrt(c)*sqrt(a + b*x + c*x**2) + 2*c*x)/sqrt(c), Ne(c, 0) & Ne(a - b**2/(4*c), 0)),
|
||||
((b/(2*c) + x)*log(b/(2*c) + x)/sqrt(c*(b/(2*c) + x)**2), Ne(c, 0)),
|
||||
(2*sqrt(a + b*x)/b, Ne(b, 0)), (x/sqrt(a), True))
|
||||
|
||||
assert_is_integral_of((7*x+6)/sqrt(3*x**2+4*x+5),
|
||||
7*sqrt(3*x**2 + 4*x + 5)/3 + 4*sqrt(3)*asinh(3*sqrt(11)*(x + S(2)/3)/11)/9)
|
||||
assert_is_integral_of((7*x+6)/sqrt(-3*x**2+4*x+5),
|
||||
-7*sqrt(-3*x**2 + 4*x + 5)/3 + 32*sqrt(3)*asin(3*sqrt(19)*(x - S(2)/3)/19)/9)
|
||||
assert_is_integral_of((7*x+6)/sqrt(3*x**2+4*x-5),
|
||||
7*sqrt(3*x**2 + 4*x - 5)/3 + 4*sqrt(3)*log(6*x + 2*sqrt(3)*sqrt(3*x**2 + 4*x - 5) + 4)/9)
|
||||
assert manualintegrate((d+e*x)/sqrt(a+b*x+c*x**2), x) == \
|
||||
Piecewise(((-b*e/(2*c) + d) *
|
||||
Piecewise((log(b + 2*sqrt(c)*sqrt(a + b*x + c*x**2) + 2*c*x)/sqrt(c), Ne(a - b**2/(4*c), 0)),
|
||||
((b/(2*c) + x)*log(b/(2*c) + x)/sqrt(c*(b/(2*c) + x)**2), True)) +
|
||||
e*sqrt(a + b*x + c*x**2)/c, Ne(c, 0)),
|
||||
((2*d*sqrt(a + b*x) + 2*e*(-a*sqrt(a + b*x) + (a + b*x)**(S(3)/2)/3)/b)/b, Ne(b, 0)),
|
||||
((d*x + e*x**2/2)/sqrt(a), True))
|
||||
|
||||
assert manualintegrate((3*x**3-x**2+2*x-4)/sqrt(x**2-3*x+2), x) == \
|
||||
sqrt(x**2 - 3*x + 2)*(x**2 + 13*x/4 + S(101)/8) + 135*log(2*x + 2*sqrt(x**2 - 3*x + 2) - 3)/16
|
||||
|
||||
assert_is_integral_of(sqrt(53225*x**2-66732*x+23013),
|
||||
(x/2 - S(16683)/53225)*sqrt(53225*x**2 - 66732*x + 23013) +
|
||||
111576969*sqrt(2129)*asinh(53225*x/10563 - S(11122)/3521)/1133160250)
|
||||
assert manualintegrate(sqrt(a+c*x**2), x) == \
|
||||
Piecewise((a*Piecewise((log(2*sqrt(c)*sqrt(a + c*x**2) + 2*c*x)/sqrt(c), Ne(a, 0)),
|
||||
(x*log(x)/sqrt(c*x**2), True))/2 + x*sqrt(a + c*x**2)/2, Ne(c, 0)),
|
||||
(sqrt(a)*x, True))
|
||||
assert manualintegrate(sqrt(a+b*x+c*x**2), x) == \
|
||||
Piecewise(((a/2 - b**2/(8*c)) *
|
||||
Piecewise((log(b + 2*sqrt(c)*sqrt(a + b*x + c*x**2) + 2*c*x)/sqrt(c), Ne(a - b**2/(4*c), 0)),
|
||||
((b/(2*c) + x)*log(b/(2*c) + x)/sqrt(c*(b/(2*c) + x)**2), True)) +
|
||||
(b/(4*c) + x/2)*sqrt(a + b*x + c*x**2), Ne(c, 0)),
|
||||
(2*(a + b*x)**(S(3)/2)/(3*b), Ne(b, 0)),
|
||||
(sqrt(a)*x, True))
|
||||
|
||||
assert_is_integral_of(x*sqrt(x**2+2*x+4),
|
||||
(x**2/3 + x/6 + S(5)/6)*sqrt(x**2 + 2*x + 4) - 3*asinh(sqrt(3)*(x + 1)/3)/2)
|
||||
|
||||
|
||||
def test_mul_pow_derivative():
|
||||
assert_is_integral_of(x*sec(x)*tan(x), x*sec(x) - log(tan(x) + sec(x)))
|
||||
assert_is_integral_of(x*sec(x)**2, x*tan(x) + log(cos(x)))
|
||||
assert_is_integral_of(x**3*Derivative(f(x), (x, 4)),
|
||||
x**3*Derivative(f(x), (x, 3)) - 3*x**2*Derivative(f(x), (x, 2)) +
|
||||
6*x*Derivative(f(x), x) - 6*f(x))
|
||||
@@ -0,0 +1,774 @@
|
||||
from sympy.core.function import expand_func
|
||||
from sympy.core.numbers import (I, Rational, oo, pi)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.sorting import default_sort_key
|
||||
from sympy.functions.elementary.complexes import Abs, arg, re, unpolarify
|
||||
from sympy.functions.elementary.exponential import (exp, exp_polar, log)
|
||||
from sympy.functions.elementary.hyperbolic import cosh, acosh, sinh
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.piecewise import Piecewise, piecewise_fold
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin, sinc, asin)
|
||||
from sympy.functions.special.error_functions import (erf, erfc)
|
||||
from sympy.functions.special.gamma_functions import (gamma, polygamma)
|
||||
from sympy.functions.special.hyper import (hyper, meijerg)
|
||||
from sympy.integrals.integrals import (Integral, integrate)
|
||||
from sympy.simplify.hyperexpand import hyperexpand
|
||||
from sympy.simplify.simplify import simplify
|
||||
from sympy.integrals.meijerint import (_rewrite_single, _rewrite1,
|
||||
meijerint_indefinite, _inflate_g, _create_lookup_table,
|
||||
meijerint_definite, meijerint_inversion)
|
||||
from sympy.testing.pytest import slow
|
||||
from sympy.core.random import (verify_numerically,
|
||||
random_complex_number as randcplx)
|
||||
from sympy.abc import x, y, a, b, c, d, s, t, z
|
||||
|
||||
|
||||
def test_rewrite_single():
|
||||
def t(expr, c, m):
|
||||
e = _rewrite_single(meijerg([a], [b], [c], [d], expr), x)
|
||||
assert e is not None
|
||||
assert isinstance(e[0][0][2], meijerg)
|
||||
assert e[0][0][2].argument.as_coeff_mul(x) == (c, (m,))
|
||||
|
||||
def tn(expr):
|
||||
assert _rewrite_single(meijerg([a], [b], [c], [d], expr), x) is None
|
||||
|
||||
t(x, 1, x)
|
||||
t(x**2, 1, x**2)
|
||||
t(x**2 + y*x**2, y + 1, x**2)
|
||||
tn(x**2 + x)
|
||||
tn(x**y)
|
||||
|
||||
def u(expr, x):
|
||||
from sympy.core.add import Add
|
||||
r = _rewrite_single(expr, x)
|
||||
e = Add(*[res[0]*res[2] for res in r[0]]).replace(
|
||||
exp_polar, exp) # XXX Hack?
|
||||
assert verify_numerically(e, expr, x)
|
||||
|
||||
u(exp(-x)*sin(x), x)
|
||||
|
||||
# The following has stopped working because hyperexpand changed slightly.
|
||||
# It is probably not worth fixing
|
||||
#u(exp(-x)*sin(x)*cos(x), x)
|
||||
|
||||
# This one cannot be done numerically, since it comes out as a g-function
|
||||
# of argument 4*pi
|
||||
# NOTE This also tests a bug in inverse mellin transform (which used to
|
||||
# turn exp(4*pi*I*t) into a factor of exp(4*pi*I)**t instead of
|
||||
# exp_polar).
|
||||
#u(exp(x)*sin(x), x)
|
||||
assert _rewrite_single(exp(x)*sin(x), x) == \
|
||||
([(-sqrt(2)/(2*sqrt(pi)), 0,
|
||||
meijerg(((Rational(-1, 2), 0, Rational(1, 4), S.Half, Rational(3, 4)), (1,)),
|
||||
((), (Rational(-1, 2), 0)), 64*exp_polar(-4*I*pi)/x**4))], True)
|
||||
|
||||
|
||||
def test_rewrite1():
|
||||
assert _rewrite1(x**3*meijerg([a], [b], [c], [d], x**2 + y*x**2)*5, x) == \
|
||||
(5, x**3, [(1, 0, meijerg([a], [b], [c], [d], x**2*(y + 1)))], True)
|
||||
|
||||
|
||||
def test_meijerint_indefinite_numerically():
|
||||
def t(fac, arg):
|
||||
g = meijerg([a], [b], [c], [d], arg)*fac
|
||||
subs = {a: randcplx()/10, b: randcplx()/10 + I,
|
||||
c: randcplx(), d: randcplx()}
|
||||
integral = meijerint_indefinite(g, x)
|
||||
assert integral is not None
|
||||
assert verify_numerically(g.subs(subs), integral.diff(x).subs(subs), x)
|
||||
t(1, x)
|
||||
t(2, x)
|
||||
t(1, 2*x)
|
||||
t(1, x**2)
|
||||
t(5, x**S('3/2'))
|
||||
t(x**3, x)
|
||||
t(3*x**S('3/2'), 4*x**S('7/3'))
|
||||
|
||||
|
||||
def test_meijerint_definite():
|
||||
v, b = meijerint_definite(x, x, 0, 0)
|
||||
assert v.is_zero and b is True
|
||||
v, b = meijerint_definite(x, x, oo, oo)
|
||||
assert v.is_zero and b is True
|
||||
|
||||
|
||||
def test_inflate():
|
||||
subs = {a: randcplx()/10, b: randcplx()/10 + I, c: randcplx(),
|
||||
d: randcplx(), y: randcplx()/10}
|
||||
|
||||
def t(a, b, arg, n):
|
||||
from sympy.core.mul import Mul
|
||||
m1 = meijerg(a, b, arg)
|
||||
m2 = Mul(*_inflate_g(m1, n))
|
||||
# NOTE: (the random number)**9 must still be on the principal sheet.
|
||||
# Thus make b&d small to create random numbers of small imaginary part.
|
||||
return verify_numerically(m1.subs(subs), m2.subs(subs), x, b=0.1, d=-0.1)
|
||||
assert t([[a], [b]], [[c], [d]], x, 3)
|
||||
assert t([[a, y], [b]], [[c], [d]], x, 3)
|
||||
assert t([[a], [b]], [[c, y], [d]], 2*x**3, 3)
|
||||
|
||||
|
||||
def test_recursive():
|
||||
from sympy.core.symbol import symbols
|
||||
a, b, c = symbols('a b c', positive=True)
|
||||
r = exp(-(x - a)**2)*exp(-(x - b)**2)
|
||||
e = integrate(r, (x, 0, oo), meijerg=True)
|
||||
assert simplify(e.expand()) == (
|
||||
sqrt(2)*sqrt(pi)*(
|
||||
(erf(sqrt(2)*(a + b)/2) + 1)*exp(-a**2/2 + a*b - b**2/2))/4)
|
||||
e = integrate(exp(-(x - a)**2)*exp(-(x - b)**2)*exp(c*x), (x, 0, oo), meijerg=True)
|
||||
assert simplify(e) == (
|
||||
sqrt(2)*sqrt(pi)*(erf(sqrt(2)*(2*a + 2*b + c)/4) + 1)*exp(-a**2 - b**2
|
||||
+ (2*a + 2*b + c)**2/8)/4)
|
||||
assert simplify(integrate(exp(-(x - a - b - c)**2), (x, 0, oo), meijerg=True)) == \
|
||||
sqrt(pi)/2*(1 + erf(a + b + c))
|
||||
assert simplify(integrate(exp(-(x + a + b + c)**2), (x, 0, oo), meijerg=True)) == \
|
||||
sqrt(pi)/2*(1 - erf(a + b + c))
|
||||
|
||||
|
||||
@slow
|
||||
def test_meijerint():
|
||||
from sympy.core.function import expand
|
||||
from sympy.core.symbol import symbols
|
||||
s, t, mu = symbols('s t mu', real=True)
|
||||
assert integrate(meijerg([], [], [0], [], s*t)
|
||||
*meijerg([], [], [mu/2], [-mu/2], t**2/4),
|
||||
(t, 0, oo)).is_Piecewise
|
||||
s = symbols('s', positive=True)
|
||||
assert integrate(x**s*meijerg([[], []], [[0], []], x), (x, 0, oo)) == \
|
||||
gamma(s + 1)
|
||||
assert integrate(x**s*meijerg([[], []], [[0], []], x), (x, 0, oo),
|
||||
meijerg=True) == gamma(s + 1)
|
||||
assert isinstance(integrate(x**s*meijerg([[], []], [[0], []], x),
|
||||
(x, 0, oo), meijerg=False),
|
||||
Integral)
|
||||
|
||||
assert meijerint_indefinite(exp(x), x) == exp(x)
|
||||
|
||||
# TODO what simplifications should be done automatically?
|
||||
# This tests "extra case" for antecedents_1.
|
||||
a, b = symbols('a b', positive=True)
|
||||
assert simplify(meijerint_definite(x**a, x, 0, b)[0]) == \
|
||||
b**(a + 1)/(a + 1)
|
||||
|
||||
# This tests various conditions and expansions:
|
||||
assert meijerint_definite((x + 1)**3*exp(-x), x, 0, oo) == (16, True)
|
||||
|
||||
# Again, how about simplifications?
|
||||
sigma, mu = symbols('sigma mu', positive=True)
|
||||
i, c = meijerint_definite(exp(-((x - mu)/(2*sigma))**2), x, 0, oo)
|
||||
assert simplify(i) == sqrt(pi)*sigma*(2 - erfc(mu/(2*sigma)))
|
||||
assert c == True
|
||||
|
||||
i, _ = meijerint_definite(exp(-mu*x)*exp(sigma*x), x, 0, oo)
|
||||
# TODO it would be nice to test the condition
|
||||
assert simplify(i) == 1/(mu - sigma)
|
||||
|
||||
# Test substitutions to change limits
|
||||
assert meijerint_definite(exp(x), x, -oo, 2) == (exp(2), True)
|
||||
# Note: causes a NaN in _check_antecedents
|
||||
assert expand(meijerint_definite(exp(x), x, 0, I)[0]) == exp(I) - 1
|
||||
assert expand(meijerint_definite(exp(-x), x, 0, x)[0]) == \
|
||||
1 - exp(-exp(I*arg(x))*abs(x))
|
||||
|
||||
# Test -oo to oo
|
||||
assert meijerint_definite(exp(-x**2), x, -oo, oo) == (sqrt(pi), True)
|
||||
assert meijerint_definite(exp(-abs(x)), x, -oo, oo) == (2, True)
|
||||
assert meijerint_definite(exp(-(2*x - 3)**2), x, -oo, oo) == \
|
||||
(sqrt(pi)/2, True)
|
||||
assert meijerint_definite(exp(-abs(2*x - 3)), x, -oo, oo) == (1, True)
|
||||
assert meijerint_definite(exp(-((x - mu)/sigma)**2/2)/sqrt(2*pi*sigma**2),
|
||||
x, -oo, oo) == (1, True)
|
||||
assert meijerint_definite(sinc(x)**2, x, -oo, oo) == (pi, True)
|
||||
|
||||
# Test one of the extra conditions for 2 g-functinos
|
||||
assert meijerint_definite(exp(-x)*sin(x), x, 0, oo) == (S.Half, True)
|
||||
|
||||
# Test a bug
|
||||
def res(n):
|
||||
return (1/(1 + x**2)).diff(x, n).subs(x, 1)*(-1)**n
|
||||
for n in range(6):
|
||||
assert integrate(exp(-x)*sin(x)*x**n, (x, 0, oo), meijerg=True) == \
|
||||
res(n)
|
||||
|
||||
# This used to test trigexpand... now it is done by linear substitution
|
||||
assert simplify(integrate(exp(-x)*sin(x + a), (x, 0, oo), meijerg=True)
|
||||
) == sqrt(2)*sin(a + pi/4)/2
|
||||
|
||||
# Test the condition 14 from prudnikov.
|
||||
# (This is besselj*besselj in disguise, to stop the product from being
|
||||
# recognised in the tables.)
|
||||
a, b, s = symbols('a b s')
|
||||
assert meijerint_definite(meijerg([], [], [a/2], [-a/2], x/4)
|
||||
*meijerg([], [], [b/2], [-b/2], x/4)*x**(s - 1), x, 0, oo
|
||||
) == (
|
||||
(4*2**(2*s - 2)*gamma(-2*s + 1)*gamma(a/2 + b/2 + s)
|
||||
/(gamma(-a/2 + b/2 - s + 1)*gamma(a/2 - b/2 - s + 1)
|
||||
*gamma(a/2 + b/2 - s + 1)),
|
||||
(re(s) < 1) & (re(s) < S(1)/2) & (re(a)/2 + re(b)/2 + re(s) > 0)))
|
||||
|
||||
# test a bug
|
||||
assert integrate(sin(x**a)*sin(x**b), (x, 0, oo), meijerg=True) == \
|
||||
Integral(sin(x**a)*sin(x**b), (x, 0, oo))
|
||||
|
||||
# test better hyperexpand
|
||||
assert integrate(exp(-x**2)*log(x), (x, 0, oo), meijerg=True) == \
|
||||
(sqrt(pi)*polygamma(0, S.Half)/4).expand()
|
||||
|
||||
# Test hyperexpand bug.
|
||||
from sympy.functions.special.gamma_functions import lowergamma
|
||||
n = symbols('n', integer=True)
|
||||
assert simplify(integrate(exp(-x)*x**n, x, meijerg=True)) == \
|
||||
lowergamma(n + 1, x)
|
||||
|
||||
# Test a bug with argument 1/x
|
||||
alpha = symbols('alpha', positive=True)
|
||||
assert meijerint_definite((2 - x)**alpha*sin(alpha/x), x, 0, 2) == \
|
||||
(sqrt(pi)*alpha*gamma(alpha + 1)*meijerg(((), (alpha/2 + S.Half,
|
||||
alpha/2 + 1)), ((0, 0, S.Half), (Rational(-1, 2),)), alpha**2/16)/4, True)
|
||||
|
||||
# test a bug related to 3016
|
||||
a, s = symbols('a s', positive=True)
|
||||
assert simplify(integrate(x**s*exp(-a*x**2), (x, -oo, oo))) == \
|
||||
a**(-s/2 - S.Half)*((-1)**s + 1)*gamma(s/2 + S.Half)/2
|
||||
|
||||
|
||||
def test_bessel():
|
||||
from sympy.functions.special.bessel import (besseli, besselj)
|
||||
assert simplify(integrate(besselj(a, z)*besselj(b, z)/z, (z, 0, oo),
|
||||
meijerg=True, conds='none')) == \
|
||||
2*sin(pi*(a/2 - b/2))/(pi*(a - b)*(a + b))
|
||||
assert simplify(integrate(besselj(a, z)*besselj(a, z)/z, (z, 0, oo),
|
||||
meijerg=True, conds='none')) == 1/(2*a)
|
||||
|
||||
# TODO more orthogonality integrals
|
||||
|
||||
assert simplify(integrate(sin(z*x)*(x**2 - 1)**(-(y + S.Half)),
|
||||
(x, 1, oo), meijerg=True, conds='none')
|
||||
*2/((z/2)**y*sqrt(pi)*gamma(S.Half - y))) == \
|
||||
besselj(y, z)
|
||||
|
||||
# Werner Rosenheinrich
|
||||
# SOME INDEFINITE INTEGRALS OF BESSEL FUNCTIONS
|
||||
|
||||
assert integrate(x*besselj(0, x), x, meijerg=True) == x*besselj(1, x)
|
||||
assert integrate(x*besseli(0, x), x, meijerg=True) == x*besseli(1, x)
|
||||
# TODO can do higher powers, but come out as high order ... should they be
|
||||
# reduced to order 0, 1?
|
||||
assert integrate(besselj(1, x), x, meijerg=True) == -besselj(0, x)
|
||||
assert integrate(besselj(1, x)**2/x, x, meijerg=True) == \
|
||||
-(besselj(0, x)**2 + besselj(1, x)**2)/2
|
||||
# TODO more besseli when tables are extended or recursive mellin works
|
||||
assert integrate(besselj(0, x)**2/x**2, x, meijerg=True) == \
|
||||
-2*x*besselj(0, x)**2 - 2*x*besselj(1, x)**2 \
|
||||
+ 2*besselj(0, x)*besselj(1, x) - besselj(0, x)**2/x
|
||||
assert integrate(besselj(0, x)*besselj(1, x), x, meijerg=True) == \
|
||||
-besselj(0, x)**2/2
|
||||
assert integrate(x**2*besselj(0, x)*besselj(1, x), x, meijerg=True) == \
|
||||
x**2*besselj(1, x)**2/2
|
||||
assert integrate(besselj(0, x)*besselj(1, x)/x, x, meijerg=True) == \
|
||||
(x*besselj(0, x)**2 + x*besselj(1, x)**2 -
|
||||
besselj(0, x)*besselj(1, x))
|
||||
# TODO how does besselj(0, a*x)*besselj(0, b*x) work?
|
||||
# TODO how does besselj(0, x)**2*besselj(1, x)**2 work?
|
||||
# TODO sin(x)*besselj(0, x) etc come out a mess
|
||||
# TODO can x*log(x)*besselj(0, x) be done?
|
||||
# TODO how does besselj(1, x)*besselj(0, x+a) work?
|
||||
# TODO more indefinite integrals when struve functions etc are implemented
|
||||
|
||||
# test a substitution
|
||||
assert integrate(besselj(1, x**2)*x, x, meijerg=True) == \
|
||||
-besselj(0, x**2)/2
|
||||
|
||||
|
||||
def test_inversion():
|
||||
from sympy.functions.special.bessel import besselj
|
||||
from sympy.functions.special.delta_functions import Heaviside
|
||||
|
||||
def inv(f):
|
||||
return piecewise_fold(meijerint_inversion(f, s, t))
|
||||
assert inv(1/(s**2 + 1)) == sin(t)*Heaviside(t)
|
||||
assert inv(s/(s**2 + 1)) == cos(t)*Heaviside(t)
|
||||
assert inv(exp(-s)/s) == Heaviside(t - 1)
|
||||
assert inv(1/sqrt(1 + s**2)) == besselj(0, t)*Heaviside(t)
|
||||
|
||||
# Test some antcedents checking.
|
||||
assert meijerint_inversion(sqrt(s)/sqrt(1 + s**2), s, t) is None
|
||||
assert inv(exp(s**2)) is None
|
||||
assert meijerint_inversion(exp(-s**2), s, t) is None
|
||||
|
||||
|
||||
def test_inversion_conditional_output():
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.integrals.transforms import InverseLaplaceTransform
|
||||
|
||||
a = Symbol('a', positive=True)
|
||||
F = sqrt(pi/a)*exp(-2*sqrt(a)*sqrt(s))
|
||||
f = meijerint_inversion(F, s, t)
|
||||
assert not f.is_Piecewise
|
||||
|
||||
b = Symbol('b', real=True)
|
||||
F = F.subs(a, b)
|
||||
f2 = meijerint_inversion(F, s, t)
|
||||
assert f2.is_Piecewise
|
||||
# first piece is same as f
|
||||
assert f2.args[0][0] == f.subs(a, b)
|
||||
# last piece is an unevaluated transform
|
||||
assert f2.args[-1][1]
|
||||
ILT = InverseLaplaceTransform(F, s, t, None)
|
||||
assert f2.args[-1][0] == ILT or f2.args[-1][0] == ILT.as_integral
|
||||
|
||||
|
||||
def test_inversion_exp_real_nonreal_shift():
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.special.delta_functions import DiracDelta
|
||||
r = Symbol('r', real=True)
|
||||
c = Symbol('c', extended_real=False)
|
||||
a = 1 + 2*I
|
||||
z = Symbol('z')
|
||||
assert not meijerint_inversion(exp(r*s), s, t).is_Piecewise
|
||||
assert meijerint_inversion(exp(a*s), s, t) is None
|
||||
assert meijerint_inversion(exp(c*s), s, t) is None
|
||||
f = meijerint_inversion(exp(z*s), s, t)
|
||||
assert f.is_Piecewise
|
||||
assert isinstance(f.args[0][0], DiracDelta)
|
||||
|
||||
|
||||
@slow
|
||||
def test_lookup_table():
|
||||
from sympy.core.random import uniform, randrange
|
||||
from sympy.core.add import Add
|
||||
from sympy.integrals.meijerint import z as z_dummy
|
||||
table = {}
|
||||
_create_lookup_table(table)
|
||||
for l in table.values():
|
||||
for formula, terms, cond, hint in sorted(l, key=default_sort_key):
|
||||
subs = {}
|
||||
for ai in list(formula.free_symbols) + [z_dummy]:
|
||||
if hasattr(ai, 'properties') and ai.properties:
|
||||
# these Wilds match positive integers
|
||||
subs[ai] = randrange(1, 10)
|
||||
else:
|
||||
subs[ai] = uniform(1.5, 2.0)
|
||||
if not isinstance(terms, list):
|
||||
terms = terms(subs)
|
||||
|
||||
# First test that hyperexpand can do this.
|
||||
expanded = [hyperexpand(g) for (_, g) in terms]
|
||||
assert all(x.is_Piecewise or not x.has(meijerg) for x in expanded)
|
||||
|
||||
# Now test that the meijer g-function is indeed as advertised.
|
||||
expanded = Add(*[f*x for (f, x) in terms])
|
||||
a, b = formula.n(subs=subs), expanded.n(subs=subs)
|
||||
r = min(abs(a), abs(b))
|
||||
if r < 1:
|
||||
assert abs(a - b).n() <= 1e-10
|
||||
else:
|
||||
assert (abs(a - b)/r).n() <= 1e-10
|
||||
|
||||
|
||||
def test_branch_bug():
|
||||
from sympy.functions.special.gamma_functions import lowergamma
|
||||
from sympy.simplify.powsimp import powdenest
|
||||
# TODO gammasimp cannot prove that the factor is unity
|
||||
assert powdenest(integrate(erf(x**3), x, meijerg=True).diff(x),
|
||||
polar=True) == 2*erf(x**3)*gamma(Rational(2, 3))/3/gamma(Rational(5, 3))
|
||||
assert integrate(erf(x**3), x, meijerg=True) == \
|
||||
2*x*erf(x**3)*gamma(Rational(2, 3))/(3*gamma(Rational(5, 3))) \
|
||||
- 2*gamma(Rational(2, 3))*lowergamma(Rational(2, 3), x**6)/(3*sqrt(pi)*gamma(Rational(5, 3)))
|
||||
|
||||
|
||||
def test_linear_subs():
|
||||
from sympy.functions.special.bessel import besselj
|
||||
assert integrate(sin(x - 1), x, meijerg=True) == -cos(1 - x)
|
||||
assert integrate(besselj(1, x - 1), x, meijerg=True) == -besselj(0, 1 - x)
|
||||
|
||||
|
||||
@slow
|
||||
def test_probability():
|
||||
# various integrals from probability theory
|
||||
from sympy.core.function import expand_mul
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
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)
|
||||
|
||||
|
||||
@slow
|
||||
def test_expint():
|
||||
""" Test various exponential integrals. """
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.elementary.hyperbolic import sinh
|
||||
from sympy.functions.special.error_functions import (Chi, Ci, Ei, Shi, Si, expint)
|
||||
assert simplify(unpolarify(integrate(exp(-z*x)/x**y, (x, 1, oo),
|
||||
meijerg=True, conds='none'
|
||||
).rewrite(expint).expand(func=True))) == expint(y, z)
|
||||
|
||||
assert integrate(exp(-z*x)/x, (x, 1, oo), meijerg=True,
|
||||
conds='none').rewrite(expint).expand() == \
|
||||
expint(1, z)
|
||||
assert integrate(exp(-z*x)/x**2, (x, 1, oo), meijerg=True,
|
||||
conds='none').rewrite(expint).expand() == \
|
||||
expint(2, z).rewrite(Ei).rewrite(expint)
|
||||
assert integrate(exp(-z*x)/x**3, (x, 1, oo), meijerg=True,
|
||||
conds='none').rewrite(expint).expand() == \
|
||||
expint(3, z).rewrite(Ei).rewrite(expint).expand()
|
||||
|
||||
t = Symbol('t', positive=True)
|
||||
assert integrate(-cos(x)/x, (x, t, oo), meijerg=True).expand() == Ci(t)
|
||||
assert integrate(-sin(x)/x, (x, t, oo), meijerg=True).expand() == \
|
||||
Si(t) - pi/2
|
||||
assert integrate(sin(x)/x, (x, 0, z), meijerg=True) == Si(z)
|
||||
assert integrate(sinh(x)/x, (x, 0, z), meijerg=True) == Shi(z)
|
||||
assert integrate(exp(-x)/x, x, meijerg=True).expand().rewrite(expint) == \
|
||||
I*pi - expint(1, x)
|
||||
assert integrate(exp(-x)/x**2, x, meijerg=True).rewrite(expint).expand() \
|
||||
== expint(1, x) - exp(-x)/x - I*pi
|
||||
|
||||
u = Symbol('u', polar=True)
|
||||
assert integrate(cos(u)/u, u, meijerg=True).expand().as_independent(u)[1] \
|
||||
== Ci(u)
|
||||
assert integrate(cosh(u)/u, u, meijerg=True).expand().as_independent(u)[1] \
|
||||
== Chi(u)
|
||||
|
||||
assert integrate(expint(1, x), x, meijerg=True
|
||||
).rewrite(expint).expand() == x*expint(1, x) - exp(-x)
|
||||
assert integrate(expint(2, x), x, meijerg=True
|
||||
).rewrite(expint).expand() == \
|
||||
-x**2*expint(1, x)/2 + x*exp(-x)/2 - exp(-x)/2
|
||||
assert simplify(unpolarify(integrate(expint(y, x), x,
|
||||
meijerg=True).rewrite(expint).expand(func=True))) == \
|
||||
-expint(y + 1, x)
|
||||
|
||||
assert integrate(Si(x), x, meijerg=True) == x*Si(x) + cos(x)
|
||||
assert integrate(Ci(u), u, meijerg=True).expand() == u*Ci(u) - sin(u)
|
||||
assert integrate(Shi(x), x, meijerg=True) == x*Shi(x) - cosh(x)
|
||||
assert integrate(Chi(u), u, meijerg=True).expand() == u*Chi(u) - sinh(u)
|
||||
|
||||
assert integrate(Si(x)*exp(-x), (x, 0, oo), meijerg=True) == pi/4
|
||||
assert integrate(expint(1, x)*sin(x), (x, 0, oo), meijerg=True) == log(2)/2
|
||||
|
||||
|
||||
def test_messy():
|
||||
from sympy.functions.elementary.hyperbolic import (acosh, acoth)
|
||||
from sympy.functions.elementary.trigonometric import (asin, atan)
|
||||
from sympy.functions.special.bessel import besselj
|
||||
from sympy.functions.special.error_functions import (Chi, E1, Shi, Si)
|
||||
from sympy.integrals.transforms import (fourier_transform, laplace_transform)
|
||||
assert (laplace_transform(Si(x), x, s, simplify=True) ==
|
||||
((-atan(s) + pi/2)/s, 0, True))
|
||||
|
||||
assert laplace_transform(Shi(x), x, s, simplify=True) == (
|
||||
acoth(s)/s, -oo, s**2 > 1)
|
||||
|
||||
# where should the logs be simplified?
|
||||
assert laplace_transform(Chi(x), x, s, simplify=True) == (
|
||||
(log(s**(-2)) - log(1 - 1/s**2))/(2*s), -oo, s**2 > 1)
|
||||
|
||||
# TODO maybe simplify the inequalities? when the simplification
|
||||
# allows for generators instead of symbols this will work
|
||||
assert laplace_transform(besselj(a, x), x, s)[1:] == \
|
||||
(0, (re(a) > -2) & (re(a) > -1))
|
||||
|
||||
# NOTE s < 0 can be done, but argument reduction is not good enough yet
|
||||
ans = fourier_transform(besselj(1, x)/x, x, s, noconds=False)
|
||||
assert (ans[0].factor(deep=True).expand(), ans[1]) == \
|
||||
(Piecewise((0, (s > 1/(2*pi)) | (s < -1/(2*pi))),
|
||||
(2*sqrt(-4*pi**2*s**2 + 1), True)), s > 0)
|
||||
# TODO FT(besselj(0,x)) - conditions are messy (but for acceptable reasons)
|
||||
# - folding could be better
|
||||
|
||||
assert integrate(E1(x)*besselj(0, x), (x, 0, oo), meijerg=True) == \
|
||||
log(1 + sqrt(2))
|
||||
assert integrate(E1(x)*besselj(1, x), (x, 0, oo), meijerg=True) == \
|
||||
log(S.Half + sqrt(2)/2)
|
||||
|
||||
assert integrate(1/x/sqrt(1 - x**2), x, meijerg=True) == \
|
||||
Piecewise((-acosh(1/x), abs(x**(-2)) > 1), (I*asin(1/x), True))
|
||||
|
||||
|
||||
def test_issue_6122():
|
||||
assert integrate(exp(-I*x**2), (x, -oo, oo), meijerg=True) == \
|
||||
-I*sqrt(pi)*exp(I*pi/4)
|
||||
|
||||
|
||||
def test_issue_6252():
|
||||
expr = 1/x/(a + b*x)**Rational(1, 3)
|
||||
anti = integrate(expr, x, meijerg=True)
|
||||
assert not anti.has(hyper)
|
||||
# XXX the expression is a mess, but actually upon differentiation and
|
||||
# putting in numerical values seems to work...
|
||||
|
||||
|
||||
def test_issue_6348():
|
||||
assert integrate(exp(I*x)/(1 + x**2), (x, -oo, oo)).simplify().rewrite(exp) \
|
||||
== pi*exp(-1)
|
||||
|
||||
|
||||
def test_fresnel():
|
||||
from sympy.functions.special.error_functions import (fresnelc, fresnels)
|
||||
|
||||
assert expand_func(integrate(sin(pi*x**2/2), x)) == fresnels(x)
|
||||
assert expand_func(integrate(cos(pi*x**2/2), x)) == fresnelc(x)
|
||||
|
||||
|
||||
def test_issue_6860():
|
||||
assert meijerint_indefinite(x**x**x, x) is None
|
||||
|
||||
|
||||
def test_issue_7337():
|
||||
f = meijerint_indefinite(x*sqrt(2*x + 3), x).together()
|
||||
assert f == sqrt(2*x + 3)*(2*x**2 + x - 3)/5
|
||||
assert f._eval_interval(x, S.NegativeOne, S.One) == Rational(2, 5)
|
||||
|
||||
|
||||
def test_issue_8368():
|
||||
assert meijerint_indefinite(cosh(x)*exp(-x*t), x) == (
|
||||
(-t - 1)*exp(x) + (-t + 1)*exp(-x))*exp(-t*x)/2/(t**2 - 1)
|
||||
|
||||
|
||||
def test_issue_10211():
|
||||
from sympy.abc import h, w
|
||||
assert integrate((1/sqrt((y-x)**2 + h**2)**3), (x,0,w), (y,0,w)) == \
|
||||
2*sqrt(1 + w**2/h**2)/h - 2/h
|
||||
|
||||
|
||||
def test_issue_11806():
|
||||
from sympy.core.symbol import symbols
|
||||
y, L = symbols('y L', positive=True)
|
||||
assert integrate(1/sqrt(x**2 + y**2)**3, (x, -L, L)) == \
|
||||
2*L/(y**2*sqrt(L**2 + y**2))
|
||||
|
||||
def test_issue_10681():
|
||||
from sympy.polys.domains.realfield import RR
|
||||
from sympy.abc import R, r
|
||||
f = integrate(r**2*(R**2-r**2)**0.5, r, meijerg=True)
|
||||
g = (1.0/3)*R**1.0*r**3*hyper((-0.5, Rational(3, 2)), (Rational(5, 2),),
|
||||
r**2*exp_polar(2*I*pi)/R**2)
|
||||
assert RR.almosteq((f/g).n(), 1.0, 1e-12)
|
||||
|
||||
def test_issue_13536():
|
||||
from sympy.core.symbol import Symbol
|
||||
a = Symbol('a', positive=True)
|
||||
assert integrate(1/x**2, (x, oo, a)) == -1/a
|
||||
|
||||
|
||||
def test_issue_6462():
|
||||
from sympy.core.symbol import Symbol
|
||||
x = Symbol('x')
|
||||
n = Symbol('n')
|
||||
# Not the actual issue, still wrong answer for n = 1, but that there is no
|
||||
# exception
|
||||
assert integrate(cos(x**n)/x**n, x, meijerg=True).subs(n, 2).equals(
|
||||
integrate(cos(x**2)/x**2, x, meijerg=True))
|
||||
|
||||
|
||||
def test_indefinite_1_bug():
|
||||
assert integrate((b + t)**(-a), t, meijerg=True) == -b*(1 + t/b)**(1 - a)/(a*b**a - b**a)
|
||||
|
||||
|
||||
def test_pr_23583():
|
||||
# This result is wrong. Check whether new result is correct when this test fail.
|
||||
assert integrate(1/sqrt((x - I)**2-1), meijerg=True) == \
|
||||
Piecewise((acosh(x - I), Abs((x - I)**2) > 1), (-I*asin(x - I), True))
|
||||
|
||||
|
||||
# 25786
|
||||
def test_integrate_function_of_square_over_negatives():
|
||||
assert integrate(exp(-x**2), (x,-5,0), meijerg=True) == sqrt(pi)/2 * erf(5)
|
||||
|
||||
|
||||
def test_issue_25949():
|
||||
from sympy.core.symbol import symbols
|
||||
y = symbols("y", nonzero=True)
|
||||
assert integrate(cosh(y*(x + 1)), (x, -1, -0.25), meijerg=True) == sinh(0.75*y)/y
|
||||
@@ -0,0 +1,322 @@
|
||||
"""Most of these tests come from the examples in Bronstein's book."""
|
||||
from sympy.integrals.risch import DifferentialExtension, derivation
|
||||
from sympy.integrals.prde import (prde_normal_denom, prde_special_denom,
|
||||
prde_linear_constraints, constant_system, prde_spde, prde_no_cancel_b_large,
|
||||
prde_no_cancel_b_small, limited_integrate_reduce, limited_integrate,
|
||||
is_deriv_k, is_log_deriv_k_t_radical, parametric_log_deriv_heu,
|
||||
is_log_deriv_k_t_radical_in_field, param_poly_rischDE, param_rischDE,
|
||||
prde_cancel_liouvillian)
|
||||
|
||||
from sympy.polys.polymatrix import PolyMatrix as Matrix
|
||||
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.polys.domains.rationalfield import QQ
|
||||
from sympy.polys.polytools import Poly
|
||||
from sympy.abc import x, t, n
|
||||
|
||||
t0, t1, t2, t3, k = symbols('t:4 k')
|
||||
|
||||
|
||||
def test_prde_normal_denom():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t**2, t)]})
|
||||
fa = Poly(1, t)
|
||||
fd = Poly(x, t)
|
||||
G = [(Poly(t, t), Poly(1 + t**2, t)), (Poly(1, t), Poly(x + x*t**2, t))]
|
||||
assert prde_normal_denom(fa, fd, G, DE) == \
|
||||
(Poly(x, t, domain='ZZ(x)'), (Poly(1, t, domain='ZZ(x)'), Poly(1, t,
|
||||
domain='ZZ(x)')), [(Poly(x*t, t, domain='ZZ(x)'),
|
||||
Poly(t**2 + 1, t, domain='ZZ(x)')), (Poly(1, t, domain='ZZ(x)'),
|
||||
Poly(t**2 + 1, t, domain='ZZ(x)'))], Poly(1, t, domain='ZZ(x)'))
|
||||
G = [(Poly(t, t), Poly(t**2 + 2*t + 1, t)), (Poly(x*t, t),
|
||||
Poly(t**2 + 2*t + 1, t)), (Poly(x*t**2, t), Poly(t**2 + 2*t + 1, t))]
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert prde_normal_denom(Poly(x, t), Poly(1, t), G, DE) == \
|
||||
(Poly(t + 1, t), (Poly((-1 + x)*t + x, t), Poly(1, t, domain='ZZ[x]')), [(Poly(t, t),
|
||||
Poly(1, t)), (Poly(x*t, t), Poly(1, t, domain='ZZ[x]')), (Poly(x*t**2, t),
|
||||
Poly(1, t, domain='ZZ[x]'))], Poly(t + 1, t))
|
||||
|
||||
|
||||
def test_prde_special_denom():
|
||||
a = Poly(t + 1, t)
|
||||
ba = Poly(t**2, t)
|
||||
bd = Poly(1, t)
|
||||
G = [(Poly(t, t), Poly(1, t)), (Poly(t**2, t), Poly(1, t)), (Poly(t**3, t), Poly(1, t))]
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert prde_special_denom(a, ba, bd, G, DE) == \
|
||||
(Poly(t + 1, t), Poly(t**2, t), [(Poly(t, t), Poly(1, t)),
|
||||
(Poly(t**2, t), Poly(1, t)), (Poly(t**3, t), Poly(1, t))], Poly(1, t))
|
||||
G = [(Poly(t, t), Poly(1, t)), (Poly(1, t), Poly(t, t))]
|
||||
assert prde_special_denom(Poly(1, t), Poly(t**2, t), Poly(1, t), G, DE) == \
|
||||
(Poly(1, t), Poly(t**2 - 1, t), [(Poly(t**2, t), Poly(1, t)),
|
||||
(Poly(1, t), Poly(1, t))], Poly(t, t))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-2*x*t0, t0)]})
|
||||
DE.decrement_level()
|
||||
G = [(Poly(t, t), Poly(t**2, t)), (Poly(2*t, t), Poly(t, t))]
|
||||
assert prde_special_denom(Poly(5*x*t + 1, t), Poly(t**2 + 2*x**3*t, t), Poly(t**3 + 2, t), G, DE) == \
|
||||
(Poly(5*x*t + 1, t), Poly(0, t, domain='ZZ[x]'), [(Poly(t, t), Poly(t**2, t)),
|
||||
(Poly(2*t, t), Poly(t, t))], Poly(1, x))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly((t**2 + 1)*2*x, t)]})
|
||||
G = [(Poly(t + x, t), Poly(t*x, t)), (Poly(2*t, t), Poly(x**2, x))]
|
||||
assert prde_special_denom(Poly(5*x*t + 1, t), Poly(t**2 + 2*x**3*t, t), Poly(t**3, t), G, DE) == \
|
||||
(Poly(5*x*t + 1, t), Poly(0, t, domain='ZZ[x]'), [(Poly(t + x, t), Poly(x*t, t)),
|
||||
(Poly(2*t, t, x), Poly(x**2, t, x))], Poly(1, t))
|
||||
assert prde_special_denom(Poly(t + 1, t), Poly(t**2, t), Poly(t**3, t), G, DE) == \
|
||||
(Poly(t + 1, t), Poly(0, t, domain='ZZ[x]'), [(Poly(t + x, t), Poly(x*t, t)), (Poly(2*t, t, x),
|
||||
Poly(x**2, t, x))], Poly(1, t))
|
||||
|
||||
|
||||
def test_prde_linear_constraints():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
G = [(Poly(2*x**3 + 3*x + 1, x), Poly(x**2 - 1, x)), (Poly(1, x), Poly(x - 1, x)),
|
||||
(Poly(1, x), Poly(x + 1, x))]
|
||||
assert prde_linear_constraints(Poly(1, x), Poly(0, x), G, DE) == \
|
||||
((Poly(2*x, x, domain='QQ'), Poly(0, x, domain='QQ'), Poly(0, x, domain='QQ')),
|
||||
Matrix([[1, 1, -1], [5, 1, 1]], x))
|
||||
G = [(Poly(t, t), Poly(1, t)), (Poly(t**2, t), Poly(1, t)), (Poly(t**3, t), Poly(1, t))]
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert prde_linear_constraints(Poly(t + 1, t), Poly(t**2, t), G, DE) == \
|
||||
((Poly(t, t, domain='QQ'), Poly(t**2, t, domain='QQ'), Poly(t**3, t, domain='QQ')),
|
||||
Matrix(0, 3, [], t))
|
||||
G = [(Poly(2*x, t), Poly(t, t)), (Poly(-x, t), Poly(t, t))]
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
assert prde_linear_constraints(Poly(1, t), Poly(0, t), G, DE) == \
|
||||
((Poly(0, t, domain='QQ[x]'), Poly(0, t, domain='QQ[x]')), Matrix([[2*x, -x]], t))
|
||||
|
||||
|
||||
def test_constant_system():
|
||||
A = Matrix([[-(x + 3)/(x - 1), (x + 1)/(x - 1), 1],
|
||||
[-x - 3, x + 1, x - 1],
|
||||
[2*(x + 3)/(x - 1), 0, 0]], t)
|
||||
u = Matrix([[(x + 1)/(x - 1)], [x + 1], [0]], t)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
R = QQ.frac_field(x)[t]
|
||||
assert constant_system(A, u, DE) == \
|
||||
(Matrix([[1, 0, 0],
|
||||
[0, 1, 0],
|
||||
[0, 0, 0],
|
||||
[0, 0, 1]], ring=R), Matrix([0, 1, 0, 0], ring=R))
|
||||
|
||||
|
||||
def test_prde_spde():
|
||||
D = [Poly(x, t), Poly(-x*t, t)]
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
# TODO: when bound_degree() can handle this, test degree bound from that too
|
||||
assert prde_spde(Poly(t, t), Poly(-1/x, t), D, n, DE) == \
|
||||
(Poly(t, t), Poly(0, t, domain='ZZ(x)'),
|
||||
[Poly(2*x, t, domain='ZZ(x)'), Poly(-x, t, domain='ZZ(x)')],
|
||||
[Poly(-x**2, t, domain='ZZ(x)'), Poly(0, t, domain='ZZ(x)')], n - 1)
|
||||
|
||||
|
||||
def test_prde_no_cancel():
|
||||
# b large
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
assert prde_no_cancel_b_large(Poly(1, x), [Poly(x**2, x), Poly(1, x)], 2, DE) == \
|
||||
([Poly(x**2 - 2*x + 2, x), Poly(1, x)], Matrix([[1, 0, -1, 0],
|
||||
[0, 1, 0, -1]], x))
|
||||
assert prde_no_cancel_b_large(Poly(1, x), [Poly(x**3, x), Poly(1, x)], 3, DE) == \
|
||||
([Poly(x**3 - 3*x**2 + 6*x - 6, x), Poly(1, x)], Matrix([[1, 0, -1, 0],
|
||||
[0, 1, 0, -1]], x))
|
||||
assert prde_no_cancel_b_large(Poly(x, x), [Poly(x**2, x), Poly(1, x)], 1, DE) == \
|
||||
([Poly(x, x, domain='ZZ'), Poly(0, x, domain='ZZ')], Matrix([[1, -1, 0, 0],
|
||||
[1, 0, -1, 0],
|
||||
[0, 1, 0, -1]], x))
|
||||
# b small
|
||||
# XXX: Is there a better example of a monomial with D.degree() > 2?
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**3 + 1, t)]})
|
||||
|
||||
# My original q was t**4 + t + 1, but this solution implies q == t**4
|
||||
# (c1 = 4), with some of the ci for the original q equal to 0.
|
||||
G = [Poly(t**6, t), Poly(x*t**5, t), Poly(t**3, t), Poly(x*t**2, t), Poly(1 + x, t)]
|
||||
R = QQ.frac_field(x)[t]
|
||||
assert prde_no_cancel_b_small(Poly(x*t, t), G, 4, DE) == \
|
||||
([Poly(t**4/4 - x/12*t**3 + x**2/24*t**2 + (Rational(-11, 12) - x**3/24)*t + x/24, t),
|
||||
Poly(x/3*t**3 - x**2/6*t**2 + (Rational(-1, 3) + x**3/6)*t - x/6, t), Poly(t, t),
|
||||
Poly(0, t), Poly(0, t)], Matrix([[1, 0, -1, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, Rational(-1, 4), 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
|
||||
[1, 0, 0, 0, 0, -1, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0, 0, -1, 0, 0, 0],
|
||||
[0, 0, 1, 0, 0, 0, 0, -1, 0, 0],
|
||||
[0, 0, 0, 1, 0, 0, 0, 0, -1, 0],
|
||||
[0, 0, 0, 0, 1, 0, 0, 0, 0, -1]], ring=R))
|
||||
|
||||
# TODO: Add test for deg(b) <= 0 with b small
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t**2, t)]})
|
||||
b = Poly(-1/x**2, t, field=True) # deg(b) == 0
|
||||
q = [Poly(x**i*t**j, t, field=True) for i in range(2) for j in range(3)]
|
||||
h, A = prde_no_cancel_b_small(b, q, 3, DE)
|
||||
V = A.nullspace()
|
||||
R = QQ.frac_field(x)[t]
|
||||
assert len(V) == 1
|
||||
assert V[0] == Matrix([Rational(-1, 2), 0, 0, 1, 0, 0]*3, ring=R)
|
||||
assert (Matrix([h])*V[0][6:, :])[0] == Poly(x**2/2, t, domain='QQ(x)')
|
||||
assert (Matrix([q])*V[0][:6, :])[0] == Poly(x - S.Half, t, domain='QQ(x)')
|
||||
|
||||
|
||||
def test_prde_cancel_liouvillian():
|
||||
### 1. case == 'primitive'
|
||||
# used when integrating f = log(x) - log(x - 1)
|
||||
# Not taken from 'the' book
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
p0 = Poly(0, t, field=True)
|
||||
p1 = Poly((x - 1)*t, t, domain='ZZ(x)')
|
||||
p2 = Poly(x - 1, t, domain='ZZ(x)')
|
||||
p3 = Poly(-x**2 + x, t, domain='ZZ(x)')
|
||||
h, A = prde_cancel_liouvillian(Poly(-1/(x - 1), t), [Poly(-x + 1, t), Poly(1, t)], 1, DE)
|
||||
V = A.nullspace()
|
||||
assert h == [p0, p0, p1, p0, p0, p0, p0, p0, p0, p0, p2, p3, p0, p0, p0, p0]
|
||||
assert A.rank() == 16
|
||||
assert (Matrix([h])*V[0][:16, :]) == Matrix([[Poly(0, t, domain='QQ(x)')]])
|
||||
|
||||
### 2. case == 'exp'
|
||||
# used when integrating log(x/exp(x) + 1)
|
||||
# Not taken from book
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-t, t)]})
|
||||
assert prde_cancel_liouvillian(Poly(0, t, domain='QQ[x]'), [Poly(1, t, domain='QQ(x)')], 0, DE) == \
|
||||
([Poly(1, t, domain='QQ'), Poly(x, t, domain='ZZ(x)')], Matrix([[-1, 0, 1]], DE.t))
|
||||
|
||||
|
||||
def test_param_poly_rischDE():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
a = Poly(x**2 - x, x, field=True)
|
||||
b = Poly(1, x, field=True)
|
||||
q = [Poly(x, x, field=True), Poly(x**2, x, field=True)]
|
||||
h, A = param_poly_rischDE(a, b, q, 3, DE)
|
||||
|
||||
assert A.nullspace() == [Matrix([0, 1, 1, 1], DE.t)] # c1, c2, d1, d2
|
||||
# Solution of a*Dp + b*p = c1*q1 + c2*q2 = q2 = x**2
|
||||
# is d1*h1 + d2*h2 = h1 + h2 = x.
|
||||
assert h[0] + h[1] == Poly(x, x, domain='QQ')
|
||||
# a*Dp + b*p = q1 = x has no solution.
|
||||
|
||||
a = Poly(x**2 - x, x, field=True)
|
||||
b = Poly(x**2 - 5*x + 3, x, field=True)
|
||||
q = [Poly(1, x, field=True), Poly(x, x, field=True),
|
||||
Poly(x**2, x, field=True)]
|
||||
h, A = param_poly_rischDE(a, b, q, 3, DE)
|
||||
|
||||
assert A.nullspace() == [Matrix([3, -5, 1, -5, 1, 1], DE.t)]
|
||||
p = -Poly(5, DE.t)*h[0] + h[1] + h[2] # Poly(1, x)
|
||||
assert a*derivation(p, DE) + b*p == Poly(x**2 - 5*x + 3, x, domain='QQ')
|
||||
|
||||
|
||||
def test_param_rischDE():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
p1, px = Poly(1, x, field=True), Poly(x, x, field=True)
|
||||
G = [(p1, px), (p1, p1), (px, p1)] # [1/x, 1, x]
|
||||
h, A = param_rischDE(-p1, Poly(x**2, x, field=True), G, DE)
|
||||
assert len(h) == 3
|
||||
p = [hi[0].as_expr()/hi[1].as_expr() for hi in h]
|
||||
V = A.nullspace()
|
||||
assert len(V) == 2
|
||||
assert V[0] == Matrix([-1, 1, 0, -1, 1, 0], DE.t)
|
||||
y = -p[0] + p[1] + 0*p[2] # x
|
||||
assert y.diff(x) - y/x**2 == 1 - 1/x # Dy + f*y == -G0 + G1 + 0*G2
|
||||
|
||||
# the below test computation takes place while computing the integral
|
||||
# of 'f = log(log(x + exp(x)))'
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
G = [(Poly(t + x, t, domain='ZZ(x)'), Poly(1, t, domain='QQ')), (Poly(0, t, domain='QQ'), Poly(1, t, domain='QQ'))]
|
||||
h, A = param_rischDE(Poly(-t - 1, t, field=True), Poly(t + x, t, field=True), G, DE)
|
||||
assert len(h) == 5
|
||||
p = [hi[0].as_expr()/hi[1].as_expr() for hi in h]
|
||||
V = A.nullspace()
|
||||
assert len(V) == 3
|
||||
assert V[0] == Matrix([0, 0, 0, 0, 1, 0, 0], DE.t)
|
||||
y = 0*p[0] + 0*p[1] + 1*p[2] + 0*p[3] + 0*p[4]
|
||||
assert y.diff(t) - y/(t + x) == 0 # Dy + f*y = 0*G0 + 0*G1
|
||||
|
||||
|
||||
def test_limited_integrate_reduce():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
assert limited_integrate_reduce(Poly(x, t), Poly(t**2, t), [(Poly(x, t),
|
||||
Poly(t, t))], DE) == \
|
||||
(Poly(t, t), Poly(-1/x, t), Poly(t, t), 1, (Poly(x, t), Poly(1, t, domain='ZZ[x]')),
|
||||
[(Poly(-x*t, t), Poly(1, t, domain='ZZ[x]'))])
|
||||
|
||||
|
||||
def test_limited_integrate():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
G = [(Poly(x, x), Poly(x + 1, x))]
|
||||
assert limited_integrate(Poly(-(1 + x + 5*x**2 - 3*x**3), x),
|
||||
Poly(1 - x - x**2 + x**3, x), G, DE) == \
|
||||
((Poly(x**2 - x + 2, x), Poly(x - 1, x, domain='QQ')), [2])
|
||||
G = [(Poly(1, x), Poly(x, x))]
|
||||
assert limited_integrate(Poly(5*x**2, x), Poly(3, x), G, DE) == \
|
||||
((Poly(5*x**3/9, x), Poly(1, x, domain='QQ')), [0])
|
||||
|
||||
|
||||
def test_is_log_deriv_k_t_radical():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)], 'exts': [None],
|
||||
'extargs': [None]})
|
||||
assert is_log_deriv_k_t_radical(Poly(2*x, x), Poly(1, x), DE) is None
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(2*t1, t1), Poly(1/x, t2)],
|
||||
'exts': [None, 'exp', 'log'], 'extargs': [None, 2*x, x]})
|
||||
assert is_log_deriv_k_t_radical(Poly(x + t2/2, t2), Poly(1, t2), DE) == \
|
||||
([(t1, 1), (x, 1)], t1*x, 2, 0)
|
||||
# TODO: Add more tests
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t0, t0), Poly(1/x, t)],
|
||||
'exts': [None, 'exp', 'log'], 'extargs': [None, x, x]})
|
||||
assert is_log_deriv_k_t_radical(Poly(x + t/2 + 3, t), Poly(1, t), DE) == \
|
||||
([(t0, 2), (x, 1)], x*t0**2, 2, 3)
|
||||
|
||||
|
||||
def test_is_deriv_k():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t1), Poly(1/(x + 1), t2)],
|
||||
'exts': [None, 'log', 'log'], 'extargs': [None, x, x + 1]})
|
||||
assert is_deriv_k(Poly(2*x**2 + 2*x, t2), Poly(1, t2), DE) == \
|
||||
([(t1, 1), (t2, 1)], t1 + t2, 2)
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t1), Poly(t2, t2)],
|
||||
'exts': [None, 'log', 'exp'], 'extargs': [None, x, x]})
|
||||
assert is_deriv_k(Poly(x**2*t2**3, t2), Poly(1, t2), DE) == \
|
||||
([(x, 3), (t1, 2)], 2*t1 + 3*x, 1)
|
||||
# TODO: Add more tests, including ones with exponentials
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(2/x, t1)],
|
||||
'exts': [None, 'log'], 'extargs': [None, x**2]})
|
||||
assert is_deriv_k(Poly(x, t1), Poly(1, t1), DE) == \
|
||||
([(t1, S.Half)], t1/2, 1)
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(2/(1 + x), t0)],
|
||||
'exts': [None, 'log'], 'extargs': [None, x**2 + 2*x + 1]})
|
||||
assert is_deriv_k(Poly(1 + x, t0), Poly(1, t0), DE) == \
|
||||
([(t0, S.Half)], t0/2, 1)
|
||||
|
||||
# Issue 10798
|
||||
# DE = DifferentialExtension(log(1/x), x)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-1/x, t)],
|
||||
'exts': [None, 'log'], 'extargs': [None, 1/x]})
|
||||
assert is_deriv_k(Poly(1, t), Poly(x, t), DE) == ([(t, 1)], t, 1)
|
||||
|
||||
|
||||
def test_is_log_deriv_k_t_radical_in_field():
|
||||
# NOTE: any potential constant factor in the second element of the result
|
||||
# doesn't matter, because it cancels in Da/a.
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
assert is_log_deriv_k_t_radical_in_field(Poly(5*t + 1, t), Poly(2*t*x, t), DE) == \
|
||||
(2, t*x**5)
|
||||
assert is_log_deriv_k_t_radical_in_field(Poly(2 + 3*t, t), Poly(5*x*t, t), DE) == \
|
||||
(5, x**3*t**2)
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-t/x**2, t)]})
|
||||
assert is_log_deriv_k_t_radical_in_field(Poly(-(1 + 2*t), t),
|
||||
Poly(2*x**2 + 2*x**2*t, t), DE) == \
|
||||
(2, t + t**2)
|
||||
assert is_log_deriv_k_t_radical_in_field(Poly(-1, t), Poly(x**2, t), DE) == \
|
||||
(1, t)
|
||||
assert is_log_deriv_k_t_radical_in_field(Poly(1, t), Poly(2*x**2, t), DE) == \
|
||||
(2, 1/t)
|
||||
|
||||
|
||||
def test_parametric_log_deriv():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
assert parametric_log_deriv_heu(Poly(5*t**2 + t - 6, t), Poly(2*x*t**2, t),
|
||||
Poly(-1, t), Poly(x*t**2, t), DE) == \
|
||||
(2, 6, t*x**5)
|
||||
@@ -0,0 +1,601 @@
|
||||
from sympy.core import S, Rational
|
||||
from sympy.integrals.quadrature import (gauss_legendre, gauss_laguerre,
|
||||
gauss_hermite, gauss_gen_laguerre,
|
||||
gauss_chebyshev_t, gauss_chebyshev_u,
|
||||
gauss_jacobi, gauss_lobatto)
|
||||
|
||||
|
||||
def test_legendre():
|
||||
x, w = gauss_legendre(1, 17)
|
||||
assert [str(r) for r in x] == ['0']
|
||||
assert [str(r) for r in w] == ['2.0000000000000000']
|
||||
|
||||
x, w = gauss_legendre(2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.57735026918962576',
|
||||
'0.57735026918962576']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.0000000000000000',
|
||||
'1.0000000000000000']
|
||||
|
||||
x, w = gauss_legendre(3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.77459666924148338',
|
||||
'0',
|
||||
'0.77459666924148338']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.55555555555555556',
|
||||
'0.88888888888888889',
|
||||
'0.55555555555555556']
|
||||
|
||||
x, w = gauss_legendre(4, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.86113631159405258',
|
||||
'-0.33998104358485626',
|
||||
'0.33998104358485626',
|
||||
'0.86113631159405258']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.34785484513745386',
|
||||
'0.65214515486254614',
|
||||
'0.65214515486254614',
|
||||
'0.34785484513745386']
|
||||
|
||||
|
||||
def test_legendre_precise():
|
||||
x, w = gauss_legendre(3, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.7745966692414833770358530799564799221666',
|
||||
'0',
|
||||
'0.7745966692414833770358530799564799221666']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.5555555555555555555555555555555555555556',
|
||||
'0.8888888888888888888888888888888888888889',
|
||||
'0.5555555555555555555555555555555555555556']
|
||||
|
||||
|
||||
def test_laguerre():
|
||||
x, w = gauss_laguerre(1, 17)
|
||||
assert [str(r) for r in x] == ['1.0000000000000000']
|
||||
assert [str(r) for r in w] == ['1.0000000000000000']
|
||||
|
||||
x, w = gauss_laguerre(2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.58578643762690495',
|
||||
'3.4142135623730950']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.85355339059327376',
|
||||
'0.14644660940672624']
|
||||
|
||||
x, w = gauss_laguerre(3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.41577455678347908',
|
||||
'2.2942803602790417',
|
||||
'6.2899450829374792',
|
||||
]
|
||||
assert [str(r) for r in w] == [
|
||||
'0.71109300992917302',
|
||||
'0.27851773356924085',
|
||||
'0.010389256501586136',
|
||||
]
|
||||
|
||||
x, w = gauss_laguerre(4, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.32254768961939231',
|
||||
'1.7457611011583466',
|
||||
'4.5366202969211280',
|
||||
'9.3950709123011331']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.60315410434163360',
|
||||
'0.35741869243779969',
|
||||
'0.038887908515005384',
|
||||
'0.00053929470556132745']
|
||||
|
||||
x, w = gauss_laguerre(5, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.26356031971814091',
|
||||
'1.4134030591065168',
|
||||
'3.5964257710407221',
|
||||
'7.0858100058588376',
|
||||
'12.640800844275783']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.52175561058280865',
|
||||
'0.39866681108317593',
|
||||
'0.075942449681707595',
|
||||
'0.0036117586799220485',
|
||||
'2.3369972385776228e-5']
|
||||
|
||||
|
||||
def test_laguerre_precise():
|
||||
x, w = gauss_laguerre(3, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.4157745567834790833115338731282744735466',
|
||||
'2.294280360279041719822050361359593868960',
|
||||
'6.289945082937479196866415765512131657493']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.7110930099291730154495901911425944313094',
|
||||
'0.2785177335692408488014448884567264810349',
|
||||
'0.01038925650158613574896492040067908765572']
|
||||
|
||||
|
||||
def test_hermite():
|
||||
x, w = gauss_hermite(1, 17)
|
||||
assert [str(r) for r in x] == ['0']
|
||||
assert [str(r) for r in w] == ['1.7724538509055160']
|
||||
|
||||
x, w = gauss_hermite(2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.70710678118654752',
|
||||
'0.70710678118654752']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.88622692545275801',
|
||||
'0.88622692545275801']
|
||||
|
||||
x, w = gauss_hermite(3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-1.2247448713915890',
|
||||
'0',
|
||||
'1.2247448713915890']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.29540897515091934',
|
||||
'1.1816359006036774',
|
||||
'0.29540897515091934']
|
||||
|
||||
x, w = gauss_hermite(4, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-1.6506801238857846',
|
||||
'-0.52464762327529032',
|
||||
'0.52464762327529032',
|
||||
'1.6506801238857846']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.081312835447245177',
|
||||
'0.80491409000551284',
|
||||
'0.80491409000551284',
|
||||
'0.081312835447245177']
|
||||
|
||||
x, w = gauss_hermite(5, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-2.0201828704560856',
|
||||
'-0.95857246461381851',
|
||||
'0',
|
||||
'0.95857246461381851',
|
||||
'2.0201828704560856']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.019953242059045913',
|
||||
'0.39361932315224116',
|
||||
'0.94530872048294188',
|
||||
'0.39361932315224116',
|
||||
'0.019953242059045913']
|
||||
|
||||
|
||||
def test_hermite_precise():
|
||||
x, w = gauss_hermite(3, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'-1.224744871391589049098642037352945695983',
|
||||
'0',
|
||||
'1.224744871391589049098642037352945695983']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.2954089751509193378830279138901908637996',
|
||||
'1.181635900603677351532111655560763455198',
|
||||
'0.2954089751509193378830279138901908637996']
|
||||
|
||||
|
||||
def test_gen_laguerre():
|
||||
x, w = gauss_gen_laguerre(1, Rational(-1, 2), 17)
|
||||
assert [str(r) for r in x] == ['0.50000000000000000']
|
||||
assert [str(r) for r in w] == ['1.7724538509055160']
|
||||
|
||||
x, w = gauss_gen_laguerre(2, Rational(-1, 2), 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.27525512860841095',
|
||||
'2.7247448713915890']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.6098281800110257',
|
||||
'0.16262567089449035']
|
||||
|
||||
x, w = gauss_gen_laguerre(3, Rational(-1, 2), 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.19016350919348813',
|
||||
'1.7844927485432516',
|
||||
'5.5253437422632603']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.4492591904487850',
|
||||
'0.31413464064571329',
|
||||
'0.0090600198110176913']
|
||||
|
||||
x, w = gauss_gen_laguerre(4, Rational(-1, 2), 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.14530352150331709',
|
||||
'1.3390972881263614',
|
||||
'3.9269635013582872',
|
||||
'8.5886356890120343']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.3222940251164826',
|
||||
'0.41560465162978376',
|
||||
'0.034155966014826951',
|
||||
'0.00039920814442273524']
|
||||
|
||||
x, w = gauss_gen_laguerre(5, Rational(-1, 2), 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.11758132021177814',
|
||||
'1.0745620124369040',
|
||||
'3.0859374437175500',
|
||||
'6.4147297336620305',
|
||||
'11.807189489971737']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.2217252674706516',
|
||||
'0.48027722216462937',
|
||||
'0.067748788910962126',
|
||||
'0.0026872914935624654',
|
||||
'1.5280865710465241e-5']
|
||||
|
||||
x, w = gauss_gen_laguerre(1, 2, 17)
|
||||
assert [str(r) for r in x] == ['3.0000000000000000']
|
||||
assert [str(r) for r in w] == ['2.0000000000000000']
|
||||
|
||||
x, w = gauss_gen_laguerre(2, 2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'2.0000000000000000',
|
||||
'6.0000000000000000']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.5000000000000000',
|
||||
'0.50000000000000000']
|
||||
|
||||
x, w = gauss_gen_laguerre(3, 2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'1.5173870806774125',
|
||||
'4.3115831337195203',
|
||||
'9.1710297856030672']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.0374949614904253',
|
||||
'0.90575000470306537',
|
||||
'0.056755033806509347']
|
||||
|
||||
x, w = gauss_gen_laguerre(4, 2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'1.2267632635003021',
|
||||
'3.4125073586969460',
|
||||
'6.9026926058516134',
|
||||
'12.458036771951139']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.72552499769865438',
|
||||
'1.0634242919791946',
|
||||
'0.20669613102835355',
|
||||
'0.0043545792937974889']
|
||||
|
||||
x, w = gauss_gen_laguerre(5, 2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'1.0311091440933816',
|
||||
'2.8372128239538217',
|
||||
'5.6202942725987079',
|
||||
'9.6829098376640271',
|
||||
'15.828473921690062']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.52091739683509184',
|
||||
'1.0667059331592211',
|
||||
'0.38354972366693113',
|
||||
'0.028564233532974658',
|
||||
'0.00026271280578124935']
|
||||
|
||||
|
||||
def test_gen_laguerre_precise():
|
||||
x, w = gauss_gen_laguerre(3, Rational(-1, 2), 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.1901635091934881328718554276203028970878',
|
||||
'1.784492748543251591186722461957367638500',
|
||||
'5.525343742263260275941422110422329464413']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.449259190448785048183829411195134343108',
|
||||
'0.3141346406457132878326231270167565378246',
|
||||
'0.009060019811017691281714945129254301865020']
|
||||
|
||||
x, w = gauss_gen_laguerre(3, 2, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'1.517387080677412495020323111016672547482',
|
||||
'4.311583133719520302881184669723530562299',
|
||||
'9.171029785603067202098492219259796890218']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.037494961490425285817554606541269153041',
|
||||
'0.9057500047030653669269785048806009945254',
|
||||
'0.05675503380650934725546688857812985243312']
|
||||
|
||||
|
||||
def test_chebyshev_t():
|
||||
x, w = gauss_chebyshev_t(1, 17)
|
||||
assert [str(r) for r in x] == ['0']
|
||||
assert [str(r) for r in w] == ['3.1415926535897932']
|
||||
|
||||
x, w = gauss_chebyshev_t(2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.70710678118654752',
|
||||
'-0.70710678118654752']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.5707963267948966',
|
||||
'1.5707963267948966']
|
||||
|
||||
x, w = gauss_chebyshev_t(3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.86602540378443865',
|
||||
'0',
|
||||
'-0.86602540378443865']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.0471975511965977',
|
||||
'1.0471975511965977',
|
||||
'1.0471975511965977']
|
||||
|
||||
x, w = gauss_chebyshev_t(4, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.92387953251128676',
|
||||
'0.38268343236508977',
|
||||
'-0.38268343236508977',
|
||||
'-0.92387953251128676']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.78539816339744831',
|
||||
'0.78539816339744831',
|
||||
'0.78539816339744831',
|
||||
'0.78539816339744831']
|
||||
|
||||
x, w = gauss_chebyshev_t(5, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.95105651629515357',
|
||||
'0.58778525229247313',
|
||||
'0',
|
||||
'-0.58778525229247313',
|
||||
'-0.95105651629515357']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.62831853071795865',
|
||||
'0.62831853071795865',
|
||||
'0.62831853071795865',
|
||||
'0.62831853071795865',
|
||||
'0.62831853071795865']
|
||||
|
||||
|
||||
def test_chebyshev_t_precise():
|
||||
x, w = gauss_chebyshev_t(3, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.8660254037844386467637231707529361834714',
|
||||
'0',
|
||||
'-0.8660254037844386467637231707529361834714']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.047197551196597746154214461093167628066',
|
||||
'1.047197551196597746154214461093167628066',
|
||||
'1.047197551196597746154214461093167628066']
|
||||
|
||||
|
||||
def test_chebyshev_u():
|
||||
x, w = gauss_chebyshev_u(1, 17)
|
||||
assert [str(r) for r in x] == ['0']
|
||||
assert [str(r) for r in w] == ['1.5707963267948966']
|
||||
|
||||
x, w = gauss_chebyshev_u(2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.50000000000000000',
|
||||
'-0.50000000000000000']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.78539816339744831',
|
||||
'0.78539816339744831']
|
||||
|
||||
x, w = gauss_chebyshev_u(3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.70710678118654752',
|
||||
'0',
|
||||
'-0.70710678118654752']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.39269908169872415',
|
||||
'0.78539816339744831',
|
||||
'0.39269908169872415']
|
||||
|
||||
x, w = gauss_chebyshev_u(4, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.80901699437494742',
|
||||
'0.30901699437494742',
|
||||
'-0.30901699437494742',
|
||||
'-0.80901699437494742']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.21707871342270599',
|
||||
'0.56831944997474231',
|
||||
'0.56831944997474231',
|
||||
'0.21707871342270599']
|
||||
|
||||
x, w = gauss_chebyshev_u(5, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.86602540378443865',
|
||||
'0.50000000000000000',
|
||||
'0',
|
||||
'-0.50000000000000000',
|
||||
'-0.86602540378443865']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.13089969389957472',
|
||||
'0.39269908169872415',
|
||||
'0.52359877559829887',
|
||||
'0.39269908169872415',
|
||||
'0.13089969389957472']
|
||||
|
||||
|
||||
def test_chebyshev_u_precise():
|
||||
x, w = gauss_chebyshev_u(3, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'0.7071067811865475244008443621048490392848',
|
||||
'0',
|
||||
'-0.7071067811865475244008443621048490392848']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.3926990816987241548078304229099378605246',
|
||||
'0.7853981633974483096156608458198757210493',
|
||||
'0.3926990816987241548078304229099378605246']
|
||||
|
||||
|
||||
def test_jacobi():
|
||||
x, w = gauss_jacobi(1, Rational(-1, 2), S.Half, 17)
|
||||
assert [str(r) for r in x] == ['0.50000000000000000']
|
||||
assert [str(r) for r in w] == ['3.1415926535897932']
|
||||
|
||||
x, w = gauss_jacobi(2, Rational(-1, 2), S.Half, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.30901699437494742',
|
||||
'0.80901699437494742']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.86831485369082398',
|
||||
'2.2732777998989693']
|
||||
|
||||
x, w = gauss_jacobi(3, Rational(-1, 2), S.Half, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.62348980185873353',
|
||||
'0.22252093395631440',
|
||||
'0.90096886790241913']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.33795476356635433',
|
||||
'1.0973322242791115',
|
||||
'1.7063056657443274']
|
||||
|
||||
x, w = gauss_jacobi(4, Rational(-1, 2), S.Half, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.76604444311897804',
|
||||
'-0.17364817766693035',
|
||||
'0.50000000000000000',
|
||||
'0.93969262078590838']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.16333179083642836',
|
||||
'0.57690240318269103',
|
||||
'1.0471975511965977',
|
||||
'1.3541609083740761']
|
||||
|
||||
x, w = gauss_jacobi(5, Rational(-1, 2), S.Half, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.84125353283118117',
|
||||
'-0.41541501300188643',
|
||||
'0.14231483827328514',
|
||||
'0.65486073394528506',
|
||||
'0.95949297361449739']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.090675770007435372',
|
||||
'0.33391416373675607',
|
||||
'0.65248870981926643',
|
||||
'0.94525424081394926',
|
||||
'1.1192597692123861']
|
||||
|
||||
x, w = gauss_jacobi(1, 2, 3, 17)
|
||||
assert [str(r) for r in x] == ['0.14285714285714286']
|
||||
assert [str(r) for r in w] == ['1.0666666666666667']
|
||||
|
||||
x, w = gauss_jacobi(2, 2, 3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.24025307335204215',
|
||||
'0.46247529557426437']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.48514624517838660',
|
||||
'0.58152042148828007']
|
||||
|
||||
x, w = gauss_jacobi(3, 2, 3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.46115870378089762',
|
||||
'0.10438533038323902',
|
||||
'0.62950064612493132']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.17937613502213266',
|
||||
'0.61595640991147154',
|
||||
'0.27133412173306246']
|
||||
|
||||
x, w = gauss_jacobi(4, 2, 3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.59903470850824782',
|
||||
'-0.14761105199952565',
|
||||
'0.32554377081188859',
|
||||
'0.72879429738819258']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.067809641836772187',
|
||||
'0.38956404952032481',
|
||||
'0.47995970868024150',
|
||||
'0.12933326662932816']
|
||||
|
||||
x, w = gauss_jacobi(5, 2, 3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.69045775012676106',
|
||||
'-0.32651993134900065',
|
||||
'0.082337849552034905',
|
||||
'0.47517887061283164',
|
||||
'0.79279429464422850']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.027410178066337099',
|
||||
'0.21291786060364828',
|
||||
'0.43908437944395081',
|
||||
'0.32220656547221822',
|
||||
'0.065047683080512268']
|
||||
|
||||
|
||||
def test_jacobi_precise():
|
||||
x, w = gauss_jacobi(3, Rational(-1, 2), S.Half, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.6234898018587335305250048840042398106323',
|
||||
'0.2225209339563144042889025644967947594664',
|
||||
'0.9009688679024191262361023195074450511659']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.3379547635663543330553835737094171534907',
|
||||
'1.097332224279111467485302294320899710461',
|
||||
'1.706305665744327437921957515249186020246']
|
||||
|
||||
x, w = gauss_jacobi(3, 2, 3, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'-0.4611587037808976179121958105554375981274',
|
||||
'0.1043853303832390210914918407615869143233',
|
||||
'0.6295006461249313240934312425211234110769']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.1793761350221326596137764371503859752628',
|
||||
'0.6159564099114715430909548532229749439714',
|
||||
'0.2713341217330624639619353762933057474325']
|
||||
|
||||
|
||||
def test_lobatto():
|
||||
x, w = gauss_lobatto(2, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-1',
|
||||
'1']
|
||||
assert [str(r) for r in w] == [
|
||||
'1.0000000000000000',
|
||||
'1.0000000000000000']
|
||||
|
||||
x, w = gauss_lobatto(3, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-1',
|
||||
'0',
|
||||
'1']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.33333333333333333',
|
||||
'1.3333333333333333',
|
||||
'0.33333333333333333']
|
||||
|
||||
x, w = gauss_lobatto(4, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-1',
|
||||
'-0.44721359549995794',
|
||||
'0.44721359549995794',
|
||||
'1']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.16666666666666667',
|
||||
'0.83333333333333333',
|
||||
'0.83333333333333333',
|
||||
'0.16666666666666667']
|
||||
|
||||
x, w = gauss_lobatto(5, 17)
|
||||
assert [str(r) for r in x] == [
|
||||
'-1',
|
||||
'-0.65465367070797714',
|
||||
'0',
|
||||
'0.65465367070797714',
|
||||
'1']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.10000000000000000',
|
||||
'0.54444444444444444',
|
||||
'0.71111111111111111',
|
||||
'0.54444444444444444',
|
||||
'0.10000000000000000']
|
||||
|
||||
|
||||
def test_lobatto_precise():
|
||||
x, w = gauss_lobatto(3, 40)
|
||||
assert [str(r) for r in x] == [
|
||||
'-1',
|
||||
'0',
|
||||
'1']
|
||||
assert [str(r) for r in w] == [
|
||||
'0.3333333333333333333333333333333333333333',
|
||||
'1.333333333333333333333333333333333333333',
|
||||
'0.3333333333333333333333333333333333333333']
|
||||
@@ -0,0 +1,183 @@
|
||||
from sympy.core.numbers import (I, Rational)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Dummy, symbols)
|
||||
from sympy.functions.elementary.exponential import log
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import atan
|
||||
from sympy.integrals.integrals import integrate
|
||||
from sympy.polys.polytools import Poly
|
||||
from sympy.simplify.simplify import simplify
|
||||
|
||||
from sympy.integrals.rationaltools import ratint, ratint_logpart, log_to_atan
|
||||
|
||||
from sympy.abc import a, b, x, t
|
||||
|
||||
half = S.Half
|
||||
|
||||
|
||||
def test_ratint():
|
||||
assert ratint(S.Zero, x) == 0
|
||||
assert ratint(S(7), x) == 7*x
|
||||
|
||||
assert ratint(x, x) == x**2/2
|
||||
assert ratint(2*x, x) == x**2
|
||||
assert ratint(-2*x, x) == -x**2
|
||||
|
||||
assert ratint(8*x**7 + 2*x + 1, x) == x**8 + x**2 + x
|
||||
|
||||
f = S.One
|
||||
g = x + 1
|
||||
|
||||
assert ratint(f / g, x) == log(x + 1)
|
||||
assert ratint((f, g), x) == log(x + 1)
|
||||
|
||||
f = x**3 - x
|
||||
g = x - 1
|
||||
|
||||
assert ratint(f/g, x) == x**3/3 + x**2/2
|
||||
|
||||
f = x
|
||||
g = (x - a)*(x + a)
|
||||
|
||||
assert ratint(f/g, x) == log(x**2 - a**2)/2
|
||||
|
||||
f = S.One
|
||||
g = x**2 + 1
|
||||
|
||||
assert ratint(f/g, x, real=None) == atan(x)
|
||||
assert ratint(f/g, x, real=True) == atan(x)
|
||||
|
||||
assert ratint(f/g, x, real=False) == I*log(x + I)/2 - I*log(x - I)/2
|
||||
|
||||
f = S(36)
|
||||
g = x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2
|
||||
|
||||
assert ratint(f/g, x) == \
|
||||
-4*log(x + 1) + 4*log(x - 2) + (12*x + 6)/(x**2 - 1)
|
||||
|
||||
f = x**4 - 3*x**2 + 6
|
||||
g = x**6 - 5*x**4 + 5*x**2 + 4
|
||||
|
||||
assert ratint(f/g, x) == \
|
||||
atan(x) + atan(x**3) + atan(x/2 - Rational(3, 2)*x**3 + S.Half*x**5)
|
||||
|
||||
f = x**7 - 24*x**4 - 4*x**2 + 8*x - 8
|
||||
g = x**8 + 6*x**6 + 12*x**4 + 8*x**2
|
||||
|
||||
assert ratint(f/g, x) == \
|
||||
(4 + 6*x + 8*x**2 + 3*x**3)/(4*x + 4*x**3 + x**5) + log(x)
|
||||
|
||||
assert ratint((x**3*f)/(x*g), x) == \
|
||||
-(12 - 16*x + 6*x**2 - 14*x**3)/(4 + 4*x**2 + x**4) - \
|
||||
5*sqrt(2)*atan(x*sqrt(2)/2) + S.Half*x**2 - 3*log(2 + x**2)
|
||||
|
||||
f = x**5 - x**4 + 4*x**3 + x**2 - x + 5
|
||||
g = x**4 - 2*x**3 + 5*x**2 - 4*x + 4
|
||||
|
||||
assert ratint(f/g, x) == \
|
||||
x + S.Half*x**2 + S.Half*log(2 - x + x**2) + (9 - 4*x)/(7*x**2 - 7*x + 14) + \
|
||||
13*sqrt(7)*atan(Rational(-1, 7)*sqrt(7) + 2*x*sqrt(7)/7)/49
|
||||
|
||||
assert ratint(1/(x**2 + x + 1), x) == \
|
||||
2*sqrt(3)*atan(sqrt(3)/3 + 2*x*sqrt(3)/3)/3
|
||||
|
||||
assert ratint(1/(x**3 + 1), x) == \
|
||||
-log(1 - x + x**2)/6 + log(1 + x)/3 + sqrt(3)*atan(-sqrt(3)
|
||||
/3 + 2*x*sqrt(3)/3)/3
|
||||
|
||||
assert ratint(1/(x**2 + x + 1), x, real=False) == \
|
||||
-I*3**half*log(half + x - half*I*3**half)/3 + \
|
||||
I*3**half*log(half + x + half*I*3**half)/3
|
||||
|
||||
assert ratint(1/(x**3 + 1), x, real=False) == log(1 + x)/3 + \
|
||||
(Rational(-1, 6) + I*3**half/6)*log(-half + x + I*3**half/2) + \
|
||||
(Rational(-1, 6) - I*3**half/6)*log(-half + x - I*3**half/2)
|
||||
|
||||
# issue 4991
|
||||
assert ratint(1/(x*(a + b*x)**3), x) == \
|
||||
(3*a + 2*b*x)/(2*a**4 + 4*a**3*b*x + 2*a**2*b**2*x**2) + (
|
||||
log(x) - log(a/b + x))/a**3
|
||||
|
||||
assert ratint(x/(1 - x**2), x) == -log(x**2 - 1)/2
|
||||
assert ratint(-x/(1 - x**2), x) == log(x**2 - 1)/2
|
||||
|
||||
assert ratint((x/4 - 4/(1 - x)).diff(x), x) == x/4 + 4/(x - 1)
|
||||
|
||||
ans = atan(x)
|
||||
assert ratint(1/(x**2 + 1), x, symbol=x) == ans
|
||||
assert ratint(1/(x**2 + 1), x, symbol='x') == ans
|
||||
assert ratint(1/(x**2 + 1), x, symbol=a) == ans
|
||||
# this asserts that as_dummy must return a unique symbol
|
||||
# even if the symbol is already a Dummy
|
||||
d = Dummy()
|
||||
assert ratint(1/(d**2 + 1), d, symbol=d) == atan(d)
|
||||
|
||||
|
||||
def test_ratint_logpart():
|
||||
assert ratint_logpart(x, x**2 - 9, x, t) == \
|
||||
[(Poly(x**2 - 9, x), Poly(-2*t + 1, t))]
|
||||
assert ratint_logpart(x**2, x**3 - 5, x, t) == \
|
||||
[(Poly(x**3 - 5, x), Poly(-3*t + 1, t))]
|
||||
|
||||
|
||||
def test_issue_5414():
|
||||
assert ratint(1/(x**2 + 16), x) == atan(x/4)/4
|
||||
|
||||
|
||||
def test_issue_5249():
|
||||
assert ratint(
|
||||
1/(x**2 + a**2), x) == (-I*log(-I*a + x)/2 + I*log(I*a + x)/2)/a
|
||||
|
||||
|
||||
def test_issue_5817():
|
||||
a, b, c = symbols('a,b,c', positive=True)
|
||||
|
||||
assert simplify(ratint(a/(b*c*x**2 + a**2 + b*a), x)) == \
|
||||
sqrt(a)*atan(sqrt(
|
||||
b)*sqrt(c)*x/(sqrt(a)*sqrt(a + b)))/(sqrt(b)*sqrt(c)*sqrt(a + b))
|
||||
|
||||
|
||||
def test_issue_5981():
|
||||
u = symbols('u')
|
||||
assert integrate(1/(u**2 + 1)) == atan(u)
|
||||
|
||||
def test_issue_10488():
|
||||
a,b,c,x = symbols('a b c x', positive=True)
|
||||
assert integrate(x/(a*x+b),x) == x/a - b*log(a*x + b)/a**2
|
||||
|
||||
|
||||
def test_issues_8246_12050_13501_14080():
|
||||
a = symbols('a', nonzero=True)
|
||||
assert integrate(a/(x**2 + a**2), x) == atan(x/a)
|
||||
assert integrate(1/(x**2 + a**2), x) == atan(x/a)/a
|
||||
assert integrate(1/(1 + a**2*x**2), x) == atan(a*x)/a
|
||||
|
||||
|
||||
def test_issue_6308():
|
||||
k, a0 = symbols('k a0', real=True)
|
||||
assert integrate((x**2 + 1 - k**2)/(x**2 + 1 + a0**2), x) == \
|
||||
x - (a0**2 + k**2)*atan(x/sqrt(a0**2 + 1))/sqrt(a0**2 + 1)
|
||||
|
||||
|
||||
def test_issue_5907():
|
||||
a = symbols('a', nonzero=True)
|
||||
assert integrate(1/(x**2 + a**2)**2, x) == \
|
||||
x/(2*a**4 + 2*a**2*x**2) + atan(x/a)/(2*a**3)
|
||||
|
||||
|
||||
def test_log_to_atan():
|
||||
f, g = (Poly(x + S.Half, x, domain='QQ'), Poly(sqrt(3)/2, x, domain='EX'))
|
||||
fg_ans = 2*atan(2*sqrt(3)*x/3 + sqrt(3)/3)
|
||||
assert log_to_atan(f, g) == fg_ans
|
||||
assert log_to_atan(g, f) == -fg_ans
|
||||
|
||||
|
||||
def test_issue_25896():
|
||||
# for both tests, C = 0 in log_to_real
|
||||
# but this only has a log result
|
||||
e = (2*x + 1)/(x**2 + x + 1) + 1/x
|
||||
assert ratint(e, x) == log(x**3 + x**2 + x)
|
||||
# while this has more
|
||||
assert ratint((4*x + 7)/(x**2 + 4*x + 6) + 2/x, x) == (
|
||||
2*log(x) + 2*log(x**2 + 4*x + 6) - sqrt(2)*atan(
|
||||
sqrt(2)*x/2 + sqrt(2))/2)
|
||||
@@ -0,0 +1,202 @@
|
||||
"""Most of these tests come from the examples in Bronstein's book."""
|
||||
from sympy.core.numbers import (I, Rational, oo)
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.polys.polytools import Poly
|
||||
from sympy.integrals.risch import (DifferentialExtension,
|
||||
NonElementaryIntegralException)
|
||||
from sympy.integrals.rde import (order_at, order_at_oo, weak_normalizer,
|
||||
normal_denom, special_denom, bound_degree, spde, solve_poly_rde,
|
||||
no_cancel_equal, cancel_primitive, cancel_exp, rischDE)
|
||||
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.abc import x, t, z, n
|
||||
|
||||
t0, t1, t2, k = symbols('t:3 k')
|
||||
|
||||
|
||||
def test_order_at():
|
||||
a = Poly(t**4, t)
|
||||
b = Poly((t**2 + 1)**3*t, t)
|
||||
c = Poly((t**2 + 1)**6*t, t)
|
||||
d = Poly((t**2 + 1)**10*t**10, t)
|
||||
e = Poly((t**2 + 1)**100*t**37, t)
|
||||
p1 = Poly(t, t)
|
||||
p2 = Poly(1 + t**2, t)
|
||||
assert order_at(a, p1, t) == 4
|
||||
assert order_at(b, p1, t) == 1
|
||||
assert order_at(c, p1, t) == 1
|
||||
assert order_at(d, p1, t) == 10
|
||||
assert order_at(e, p1, t) == 37
|
||||
assert order_at(a, p2, t) == 0
|
||||
assert order_at(b, p2, t) == 3
|
||||
assert order_at(c, p2, t) == 6
|
||||
assert order_at(d, p1, t) == 10
|
||||
assert order_at(e, p2, t) == 100
|
||||
assert order_at(Poly(0, t), Poly(t, t), t) is oo
|
||||
assert order_at_oo(Poly(t**2 - 1, t), Poly(t + 1), t) == \
|
||||
order_at_oo(Poly(t - 1, t), Poly(1, t), t) == -1
|
||||
assert order_at_oo(Poly(0, t), Poly(1, t), t) is oo
|
||||
|
||||
def test_weak_normalizer():
|
||||
a = Poly((1 + x)*t**5 + 4*t**4 + (-1 - 3*x)*t**3 - 4*t**2 + (-2 + 2*x)*t, t)
|
||||
d = Poly(t**4 - 3*t**2 + 2, t)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
r = weak_normalizer(a, d, DE, z)
|
||||
assert r == (Poly(t**5 - t**4 - 4*t**3 + 4*t**2 + 4*t - 4, t, domain='ZZ[x]'),
|
||||
(Poly((1 + x)*t**2 + x*t, t, domain='ZZ[x]'),
|
||||
Poly(t + 1, t, domain='ZZ[x]')))
|
||||
assert weak_normalizer(r[1][0], r[1][1], DE) == (Poly(1, t), r[1])
|
||||
r = weak_normalizer(Poly(1 + t**2), Poly(t**2 - 1, t), DE, z)
|
||||
assert r == (Poly(t**4 - 2*t**2 + 1, t), (Poly(-3*t**2 + 1, t), Poly(t**2 - 1, t)))
|
||||
assert weak_normalizer(r[1][0], r[1][1], DE, z) == (Poly(1, t), r[1])
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t**2)]})
|
||||
r = weak_normalizer(Poly(1 + t**2), Poly(t, t), DE, z)
|
||||
assert r == (Poly(t, t), (Poly(0, t), Poly(1, t)))
|
||||
assert weak_normalizer(r[1][0], r[1][1], DE, z) == (Poly(1, t), r[1])
|
||||
|
||||
|
||||
def test_normal_denom():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
raises(NonElementaryIntegralException, lambda: normal_denom(Poly(1, x), Poly(1, x),
|
||||
Poly(1, x), Poly(x, x), DE))
|
||||
fa, fd = Poly(t**2 + 1, t), Poly(1, t)
|
||||
ga, gd = Poly(1, t), Poly(t**2, t)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
assert normal_denom(fa, fd, ga, gd, DE) == \
|
||||
(Poly(t, t), (Poly(t**3 - t**2 + t - 1, t), Poly(1, t)), (Poly(1, t),
|
||||
Poly(1, t)), Poly(t, t))
|
||||
|
||||
|
||||
def test_special_denom():
|
||||
# TODO: add more tests here
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert special_denom(Poly(1, t), Poly(t**2, t), Poly(1, t), Poly(t**2 - 1, t),
|
||||
Poly(t, t), DE) == \
|
||||
(Poly(1, t), Poly(t**2 - 1, t), Poly(t**2 - 1, t), Poly(t, t))
|
||||
# assert special_denom(Poly(1, t), Poly(2*x, t), Poly((1 + 2*x)*t, t), DE) == 1
|
||||
|
||||
# issue 3940
|
||||
# Note, this isn't a very good test, because the denominator is just 1,
|
||||
# but at least it tests the exp cancellation case
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-2*x*t0, t0),
|
||||
Poly(I*k*t1, t1)]})
|
||||
DE.decrement_level()
|
||||
assert special_denom(Poly(1, t0), Poly(I*k, t0), Poly(1, t0), Poly(t0, t0),
|
||||
Poly(1, t0), DE) == \
|
||||
(Poly(1, t0, domain='ZZ'), Poly(I*k, t0, domain='ZZ_I[k,x]'),
|
||||
Poly(t0, t0, domain='ZZ'), Poly(1, t0, domain='ZZ'))
|
||||
|
||||
|
||||
assert special_denom(Poly(1, t), Poly(t**2, t), Poly(1, t), Poly(t**2 - 1, t),
|
||||
Poly(t, t), DE, case='tan') == \
|
||||
(Poly(1, t, t0, domain='ZZ'), Poly(t**2, t0, t, domain='ZZ[x]'),
|
||||
Poly(t, t, t0, domain='ZZ'), Poly(1, t0, domain='ZZ'))
|
||||
|
||||
raises(ValueError, lambda: special_denom(Poly(1, t), Poly(t**2, t), Poly(1, t), Poly(t**2 - 1, t),
|
||||
Poly(t, t), DE, case='unrecognized_case'))
|
||||
|
||||
|
||||
def test_bound_degree_fail():
|
||||
# Primitive
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x),
|
||||
Poly(t0/x**2, t0), Poly(1/x, t)]})
|
||||
assert bound_degree(Poly(t**2, t), Poly(-(1/x**2*t**2 + 1/x), t),
|
||||
Poly((2*x - 1)*t**4 + (t0 + x)/x*t**3 - (t0 + 4*x**2)/2*x*t**2 + x*t,
|
||||
t), DE) == 3
|
||||
|
||||
|
||||
def test_bound_degree():
|
||||
# Base
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
assert bound_degree(Poly(1, x), Poly(-2*x, x), Poly(1, x), DE) == 0
|
||||
|
||||
# Primitive (see above test_bound_degree_fail)
|
||||
# TODO: Add test for when the degree bound becomes larger after limited_integrate
|
||||
# TODO: Add test for db == da - 1 case
|
||||
|
||||
# Exp
|
||||
# TODO: Add tests
|
||||
# TODO: Add test for when the degree becomes larger after parametric_log_deriv()
|
||||
|
||||
# Nonlinear
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
assert bound_degree(Poly(t, t), Poly((t - 1)*(t**2 + 1), t), Poly(1, t), DE) == 0
|
||||
|
||||
|
||||
def test_spde():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
raises(NonElementaryIntegralException, lambda: spde(Poly(t, t), Poly((t - 1)*(t**2 + 1), t), Poly(1, t), 0, DE))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert spde(Poly(t**2 + x*t*2 + x**2, t), Poly(t**2/x**2 + (2/x - 1)*t, t),
|
||||
Poly(t**2/x**2 + (2/x - 1)*t, t), 0, DE) == \
|
||||
(Poly(0, t), Poly(0, t), 0, Poly(0, t), Poly(1, t, domain='ZZ(x)'))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t0/x**2, t0), Poly(1/x, t)]})
|
||||
assert spde(Poly(t**2, t), Poly(-t**2/x**2 - 1/x, t),
|
||||
Poly((2*x - 1)*t**4 + (t0 + x)/x*t**3 - (t0 + 4*x**2)/(2*x)*t**2 + x*t, t), 3, DE) == \
|
||||
(Poly(0, t), Poly(0, t), 0, Poly(0, t),
|
||||
Poly(t0*t**2/2 + x**2*t**2 - x**2*t, t, domain='ZZ(x,t0)'))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
assert spde(Poly(x**2 + x + 1, x), Poly(-2*x - 1, x), Poly(x**5/2 +
|
||||
3*x**4/4 + x**3 - x**2 + 1, x), 4, DE) == \
|
||||
(Poly(0, x, domain='QQ'), Poly(x/2 - Rational(1, 4), x), 2, Poly(x**2 + x + 1, x), Poly(x*Rational(5, 4), x))
|
||||
assert spde(Poly(x**2 + x + 1, x), Poly(-2*x - 1, x), Poly(x**5/2 +
|
||||
3*x**4/4 + x**3 - x**2 + 1, x), n, DE) == \
|
||||
(Poly(0, x, domain='QQ'), Poly(x/2 - Rational(1, 4), x), -2 + n, Poly(x**2 + x + 1, x), Poly(x*Rational(5, 4), x))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1, t)]})
|
||||
raises(NonElementaryIntegralException, lambda: spde(Poly((t - 1)*(t**2 + 1)**2, t), Poly((t - 1)*(t**2 + 1), t), Poly(1, t), 0, DE))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
assert spde(Poly(x**2 - x, x), Poly(1, x), Poly(9*x**4 - 10*x**3 + 2*x**2, x), 4, DE) == \
|
||||
(Poly(0, x, domain='ZZ'), Poly(0, x), 0, Poly(0, x), Poly(3*x**3 - 2*x**2, x, domain='QQ'))
|
||||
assert spde(Poly(x**2 - x, x), Poly(x**2 - 5*x + 3, x), Poly(x**7 - x**6 - 2*x**4 + 3*x**3 - x**2, x), 5, DE) == \
|
||||
(Poly(1, x, domain='QQ'), Poly(x + 1, x, domain='QQ'), 1, Poly(x**4 - x**3, x), Poly(x**3 - x**2, x, domain='QQ'))
|
||||
|
||||
def test_solve_poly_rde_no_cancel():
|
||||
# deg(b) large
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t**2, t)]})
|
||||
assert solve_poly_rde(Poly(t**2 + 1, t), Poly(t**3 + (x + 1)*t**2 + t + x + 2, t),
|
||||
oo, DE) == Poly(t + x, t)
|
||||
# deg(b) small
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
assert solve_poly_rde(Poly(0, x), Poly(x/2 - Rational(1, 4), x), oo, DE) == \
|
||||
Poly(x**2/4 - x/4, x)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
assert solve_poly_rde(Poly(2, t), Poly(t**2 + 2*t + 3, t), 1, DE) == \
|
||||
Poly(t + 1, t, x)
|
||||
# deg(b) == deg(D) - 1
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
assert no_cancel_equal(Poly(1 - t, t),
|
||||
Poly(t**3 + t**2 - 2*x*t - 2*x, t), oo, DE) == \
|
||||
(Poly(t**2, t), 1, Poly((-2 - 2*x)*t - 2*x, t))
|
||||
|
||||
|
||||
def test_solve_poly_rde_cancel():
|
||||
# exp
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert cancel_exp(Poly(2*x, t), Poly(2*x, t), 0, DE) == \
|
||||
Poly(1, t)
|
||||
assert cancel_exp(Poly(2*x, t), Poly((1 + 2*x)*t, t), 1, DE) == \
|
||||
Poly(t, t)
|
||||
# TODO: Add more exp tests, including tests that require is_deriv_in_field()
|
||||
|
||||
# primitive
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
|
||||
# If the DecrementLevel context manager is working correctly, this shouldn't
|
||||
# cause any problems with the further tests.
|
||||
raises(NonElementaryIntegralException, lambda: cancel_primitive(Poly(1, t), Poly(t, t), oo, DE))
|
||||
|
||||
assert cancel_primitive(Poly(1, t), Poly(t + 1/x, t), 2, DE) == \
|
||||
Poly(t, t)
|
||||
assert cancel_primitive(Poly(4*x, t), Poly(4*x*t**2 + 2*t/x, t), 3, DE) == \
|
||||
Poly(t**2, t)
|
||||
|
||||
# TODO: Add more primitive tests, including tests that require is_deriv_in_field()
|
||||
|
||||
|
||||
def test_rischDE():
|
||||
# TODO: Add more tests for rischDE, including ones from the text
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
DE.decrement_level()
|
||||
assert rischDE(Poly(-2*x, x), Poly(1, x), Poly(1 - 2*x - 2*x**2, x),
|
||||
Poly(1, x), DE) == \
|
||||
(Poly(x + 1, x), Poly(1, x))
|
||||
@@ -0,0 +1,763 @@
|
||||
"""Most of these tests come from the examples in Bronstein's book."""
|
||||
from sympy.core.function import (Function, Lambda, diff, expand_log)
|
||||
from sympy.core.numbers import (I, Rational, pi)
|
||||
from sympy.core.relational import Ne
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.elementary.exponential import (exp, log)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.piecewise import Piecewise
|
||||
from sympy.functions.elementary.trigonometric import (atan, sin, tan)
|
||||
from sympy.polys.polytools import (Poly, cancel, factor)
|
||||
from sympy.integrals.risch import (gcdex_diophantine, frac_in, as_poly_1t,
|
||||
derivation, splitfactor, splitfactor_sqf, canonical_representation,
|
||||
hermite_reduce, polynomial_reduce, residue_reduce, residue_reduce_to_basic,
|
||||
integrate_primitive, integrate_hyperexponential_polynomial,
|
||||
integrate_hyperexponential, integrate_hypertangent_polynomial,
|
||||
integrate_nonlinear_no_specials, integer_powers, DifferentialExtension,
|
||||
risch_integrate, DecrementLevel, NonElementaryIntegral, recognize_log_derivative,
|
||||
recognize_derivative, laurent_series)
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
from sympy.abc import x, t, nu, z, a, y
|
||||
t0, t1, t2 = symbols('t:3')
|
||||
i = Symbol('i')
|
||||
|
||||
def test_gcdex_diophantine():
|
||||
assert gcdex_diophantine(Poly(x**4 - 2*x**3 - 6*x**2 + 12*x + 15),
|
||||
Poly(x**3 + x**2 - 4*x - 4), Poly(x**2 - 1)) == \
|
||||
(Poly((-x**2 + 4*x - 3)/5), Poly((x**3 - 7*x**2 + 16*x - 10)/5))
|
||||
assert gcdex_diophantine(Poly(x**3 + 6*x + 7), Poly(x**2 + 3*x + 2), Poly(x + 1)) == \
|
||||
(Poly(1/13, x, domain='QQ'), Poly(-1/13*x + 3/13, x, domain='QQ'))
|
||||
|
||||
|
||||
def test_frac_in():
|
||||
assert frac_in(Poly((x + 1)/x*t, t), x) == \
|
||||
(Poly(t*x + t, x), Poly(x, x))
|
||||
assert frac_in((x + 1)/x*t, x) == \
|
||||
(Poly(t*x + t, x), Poly(x, x))
|
||||
assert frac_in((Poly((x + 1)/x*t, t), Poly(t + 1, t)), x) == \
|
||||
(Poly(t*x + t, x), Poly((1 + t)*x, x))
|
||||
raises(ValueError, lambda: frac_in((x + 1)/log(x)*t, x))
|
||||
assert frac_in(Poly((2 + 2*x + x*(1 + x))/(1 + x)**2, t), x, cancel=True) == \
|
||||
(Poly(x + 2, x), Poly(x + 1, x))
|
||||
|
||||
|
||||
def test_as_poly_1t():
|
||||
assert as_poly_1t(2/t + t, t, z) in [
|
||||
Poly(t + 2*z, t, z), Poly(t + 2*z, z, t)]
|
||||
assert as_poly_1t(2/t + 3/t**2, t, z) in [
|
||||
Poly(2*z + 3*z**2, t, z), Poly(2*z + 3*z**2, z, t)]
|
||||
assert as_poly_1t(2/((exp(2) + 1)*t), t, z) in [
|
||||
Poly(2/(exp(2) + 1)*z, t, z), Poly(2/(exp(2) + 1)*z, z, t)]
|
||||
assert as_poly_1t(2/((exp(2) + 1)*t) + t, t, z) in [
|
||||
Poly(t + 2/(exp(2) + 1)*z, t, z), Poly(t + 2/(exp(2) + 1)*z, z, t)]
|
||||
assert as_poly_1t(S.Zero, t, z) == Poly(0, t, z)
|
||||
|
||||
|
||||
def test_derivation():
|
||||
p = Poly(4*x**4*t**5 + (-4*x**3 - 4*x**4)*t**4 + (-3*x**2 + 2*x**3)*t**3 +
|
||||
(2*x + 7*x**2 + 2*x**3)*t**2 + (1 - 4*x - 4*x**2)*t - 1 + 2*x, t)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-t**2 - 3/(2*x)*t + 1/(2*x), t)]})
|
||||
assert derivation(p, DE) == Poly(-20*x**4*t**6 + (2*x**3 + 16*x**4)*t**5 +
|
||||
(21*x**2 + 12*x**3)*t**4 + (x*Rational(7, 2) - 25*x**2 - 12*x**3)*t**3 +
|
||||
(-5 - x*Rational(15, 2) + 7*x**2)*t**2 - (3 - 8*x - 10*x**2 - 4*x**3)/(2*x)*t +
|
||||
(1 - 4*x**2)/(2*x), t)
|
||||
assert derivation(Poly(1, t), DE) == Poly(0, t)
|
||||
assert derivation(Poly(t, t), DE) == DE.d
|
||||
assert derivation(Poly(t**2 + 1/x*t + (1 - 2*x)/(4*x**2), t), DE) == \
|
||||
Poly(-2*t**3 - 4/x*t**2 - (5 - 2*x)/(2*x**2)*t - (1 - 2*x)/(2*x**3), t, domain='ZZ(x)')
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t1), Poly(t, t)]})
|
||||
assert derivation(Poly(x*t*t1, t), DE) == Poly(t*t1 + x*t*t1 + t, t)
|
||||
assert derivation(Poly(x*t*t1, t), DE, coefficientD=True) == \
|
||||
Poly((1 + t1)*t, t)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
assert derivation(Poly(x, x), DE) == Poly(1, x)
|
||||
# Test basic option
|
||||
assert derivation((x + 1)/(x - 1), DE, basic=True) == -2/(1 - 2*x + x**2)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert derivation((t + 1)/(t - 1), DE, basic=True) == -2*t/(1 - 2*t + t**2)
|
||||
assert derivation(t + 1, DE, basic=True) == t
|
||||
|
||||
|
||||
def test_splitfactor():
|
||||
p = Poly(4*x**4*t**5 + (-4*x**3 - 4*x**4)*t**4 + (-3*x**2 + 2*x**3)*t**3 +
|
||||
(2*x + 7*x**2 + 2*x**3)*t**2 + (1 - 4*x - 4*x**2)*t - 1 + 2*x, t, field=True)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-t**2 - 3/(2*x)*t + 1/(2*x), t)]})
|
||||
assert splitfactor(p, DE) == (Poly(4*x**4*t**3 + (-8*x**3 - 4*x**4)*t**2 +
|
||||
(4*x**2 + 8*x**3)*t - 4*x**2, t, domain='ZZ(x)'),
|
||||
Poly(t**2 + 1/x*t + (1 - 2*x)/(4*x**2), t, domain='ZZ(x)'))
|
||||
assert splitfactor(Poly(x, t), DE) == (Poly(x, t), Poly(1, t))
|
||||
r = Poly(-4*x**4*z**2 + 4*x**6*z**2 - z*x**3 - 4*x**5*z**3 + 4*x**3*z**3 + x**4 + z*x**5 - x**6, t)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
assert splitfactor(r, DE, coefficientD=True) == \
|
||||
(Poly(x*z - x**2 - z*x**3 + x**4, t), Poly(-x**2 + 4*x**2*z**2, t))
|
||||
assert splitfactor_sqf(r, DE, coefficientD=True) == \
|
||||
(((Poly(x*z - x**2 - z*x**3 + x**4, t), 1),), ((Poly(-x**2 + 4*x**2*z**2, t), 1),))
|
||||
assert splitfactor(Poly(0, t), DE) == (Poly(0, t), Poly(1, t))
|
||||
assert splitfactor_sqf(Poly(0, t), DE) == (((Poly(0, t), 1),), ())
|
||||
|
||||
|
||||
def test_canonical_representation():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t**2, t)]})
|
||||
assert canonical_representation(Poly(x - t, t), Poly(t**2, t), DE) == \
|
||||
(Poly(0, t, domain='ZZ[x]'), (Poly(0, t, domain='QQ[x]'),
|
||||
Poly(1, t, domain='ZZ')), (Poly(-t + x, t, domain='QQ[x]'),
|
||||
Poly(t**2, t)))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
assert canonical_representation(Poly(t**5 + t**3 + x**2*t + 1, t),
|
||||
Poly((t**2 + 1)**3, t), DE) == \
|
||||
(Poly(0, t, domain='ZZ[x]'), (Poly(t**5 + t**3 + x**2*t + 1, t, domain='QQ[x]'),
|
||||
Poly(t**6 + 3*t**4 + 3*t**2 + 1, t, domain='QQ')),
|
||||
(Poly(0, t, domain='QQ[x]'), Poly(1, t, domain='QQ')))
|
||||
|
||||
|
||||
def test_hermite_reduce():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
|
||||
assert hermite_reduce(Poly(x - t, t), Poly(t**2, t), DE) == \
|
||||
((Poly(-x, t, domain='QQ[x]'), Poly(t, t, domain='QQ[x]')),
|
||||
(Poly(0, t, domain='QQ[x]'), Poly(1, t, domain='QQ[x]')),
|
||||
(Poly(-x, t, domain='QQ[x]'), Poly(1, t, domain='QQ[x]')))
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-t**2 - t/x - (1 - nu**2/x**2), t)]})
|
||||
|
||||
assert hermite_reduce(
|
||||
Poly(x**2*t**5 + x*t**4 - nu**2*t**3 - x*(x**2 + 1)*t**2 - (x**2 - nu**2)*t - x**5/4, t),
|
||||
Poly(x**2*t**4 + x**2*(x**2 + 2)*t**2 + x**2 + x**4 + x**6/4, t), DE) == \
|
||||
((Poly(-x**2 - 4, t, domain='ZZ(x,nu)'), Poly(4*t**2 + 2*x**2 + 4, t, domain='ZZ(x,nu)')),
|
||||
(Poly((-2*nu**2 - x**4)*t - (2*x**3 + 2*x), t, domain='ZZ(x,nu)'),
|
||||
Poly(2*x**2*t**2 + x**4 + 2*x**2, t, domain='ZZ(x,nu)')),
|
||||
(Poly(x*t + 1, t, domain='ZZ(x,nu)'), Poly(x, t, domain='ZZ(x,nu)')))
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
|
||||
a = Poly((-2 + 3*x)*t**3 + (-1 + x)*t**2 + (-4*x + 2*x**2)*t + x**2, t)
|
||||
d = Poly(x*t**6 - 4*x**2*t**5 + 6*x**3*t**4 - 4*x**4*t**3 + x**5*t**2, t)
|
||||
|
||||
assert hermite_reduce(a, d, DE) == \
|
||||
((Poly(3*t**2 + t + 3*x, t, domain='ZZ(x)'),
|
||||
Poly(3*t**4 - 9*x*t**3 + 9*x**2*t**2 - 3*x**3*t, t, domain='ZZ(x)')),
|
||||
(Poly(0, t, domain='ZZ(x)'), Poly(1, t, domain='ZZ(x)')),
|
||||
(Poly(0, t, domain='ZZ(x)'), Poly(1, t, domain='ZZ(x)')))
|
||||
|
||||
assert hermite_reduce(
|
||||
Poly(-t**2 + 2*t + 2, t, domain='ZZ(x)'),
|
||||
Poly(-x*t**2 + 2*x*t - x, t, domain='ZZ(x)'), DE) == \
|
||||
((Poly(3, t, domain='ZZ(x)'), Poly(t - 1, t, domain='ZZ(x)')),
|
||||
(Poly(0, t, domain='ZZ(x)'), Poly(1, t, domain='ZZ(x)')),
|
||||
(Poly(1, t, domain='ZZ(x)'), Poly(x, t, domain='ZZ(x)')))
|
||||
|
||||
assert hermite_reduce(
|
||||
Poly(-x**2*t**6 + (-1 - 2*x**3 + x**4)*t**3 + (-3 - 3*x**4)*t**2 -
|
||||
2*x*t - x - 3*x**2, t, domain='ZZ(x)'),
|
||||
Poly(x**4*t**6 - 2*x**2*t**3 + 1, t, domain='ZZ(x)'), DE) == \
|
||||
((Poly(x**3*t + x**4 + 1, t, domain='ZZ(x)'), Poly(x**3*t**3 - x, t, domain='ZZ(x)')),
|
||||
(Poly(0, t, domain='ZZ(x)'), Poly(1, t, domain='ZZ(x)')),
|
||||
(Poly(-1, t, domain='ZZ(x)'), Poly(x**2, t, domain='ZZ(x)')))
|
||||
|
||||
assert hermite_reduce(
|
||||
Poly((-2 + 3*x)*t**3 + (-1 + x)*t**2 + (-4*x + 2*x**2)*t + x**2, t),
|
||||
Poly(x*t**6 - 4*x**2*t**5 + 6*x**3*t**4 - 4*x**4*t**3 + x**5*t**2, t), DE) == \
|
||||
((Poly(3*t**2 + t + 3*x, t, domain='ZZ(x)'),
|
||||
Poly(3*t**4 - 9*x*t**3 + 9*x**2*t**2 - 3*x**3*t, t, domain='ZZ(x)')),
|
||||
(Poly(0, t, domain='ZZ(x)'), Poly(1, t, domain='ZZ(x)')),
|
||||
(Poly(0, t, domain='ZZ(x)'), Poly(1, t, domain='ZZ(x)')))
|
||||
|
||||
|
||||
def test_polynomial_reduce():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t**2, t)]})
|
||||
assert polynomial_reduce(Poly(1 + x*t + t**2, t), DE) == \
|
||||
(Poly(t, t), Poly(x*t, t))
|
||||
assert polynomial_reduce(Poly(0, t), DE) == \
|
||||
(Poly(0, t), Poly(0, t))
|
||||
|
||||
|
||||
def test_laurent_series():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1, t)]})
|
||||
a = Poly(36, t)
|
||||
d = Poly((t - 2)*(t**2 - 1)**2, t)
|
||||
F = Poly(t**2 - 1, t)
|
||||
n = 2
|
||||
assert laurent_series(a, d, F, n, DE) == \
|
||||
(Poly(-3*t**3 + 3*t**2 - 6*t - 8, t), Poly(t**5 + t**4 - 2*t**3 - 2*t**2 + t + 1, t),
|
||||
[Poly(-3*t**3 - 6*t**2, t, domain='QQ'), Poly(2*t**6 + 6*t**5 - 8*t**3, t, domain='QQ')])
|
||||
|
||||
|
||||
def test_recognize_derivative():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, t)]})
|
||||
a = Poly(36, t)
|
||||
d = Poly((t - 2)*(t**2 - 1)**2, t)
|
||||
assert recognize_derivative(a, d, DE) == False
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
a = Poly(2, t)
|
||||
d = Poly(t**2 - 1, t)
|
||||
assert recognize_derivative(a, d, DE) == False
|
||||
assert recognize_derivative(Poly(x*t, t), Poly(1, t), DE) == True
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
assert recognize_derivative(Poly(t, t), Poly(1, t), DE) == True
|
||||
|
||||
|
||||
def test_recognize_log_derivative():
|
||||
|
||||
a = Poly(2*x**2 + 4*x*t - 2*t - x**2*t, t)
|
||||
d = Poly((2*x + t)*(t + x**2), t)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert recognize_log_derivative(a, d, DE, z) == True
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)]})
|
||||
assert recognize_log_derivative(Poly(t + 1, t), Poly(t + x, t), DE) == True
|
||||
assert recognize_log_derivative(Poly(2, t), Poly(t**2 - 1, t), DE) == True
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x)]})
|
||||
assert recognize_log_derivative(Poly(1, x), Poly(x**2 - 2, x), DE) == False
|
||||
assert recognize_log_derivative(Poly(1, x), Poly(x**2 + x, x), DE) == True
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
assert recognize_log_derivative(Poly(1, t), Poly(t**2 - 2, t), DE) == False
|
||||
assert recognize_log_derivative(Poly(1, t), Poly(t**2 + t, t), DE) == False
|
||||
|
||||
|
||||
def test_residue_reduce():
|
||||
a = Poly(2*t**2 - t - x**2, t)
|
||||
d = Poly(t**3 - x**2*t, t)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)], 'Tfuncs': [log]})
|
||||
assert residue_reduce(a, d, DE, z, invert=False) == \
|
||||
([(Poly(z**2 - Rational(1, 4), z, domain='ZZ(x)'),
|
||||
Poly((1 + 3*x*z - 6*z**2 - 2*x**2 + 4*x**2*z**2)*t - x*z + x**2 +
|
||||
2*x**2*z**2 - 2*z*x**3, t, domain='ZZ(z, x)'))], False)
|
||||
assert residue_reduce(a, d, DE, z, invert=True) == \
|
||||
([(Poly(z**2 - Rational(1, 4), z, domain='ZZ(x)'), Poly(t + 2*x*z, t))], False)
|
||||
assert residue_reduce(Poly(-2/x, t), Poly(t**2 - 1, t,), DE, z, invert=False) == \
|
||||
([(Poly(z**2 - 1, z, domain='QQ'), Poly(-2*z*t/x - 2/x, t, domain='ZZ(z,x)'))], True)
|
||||
ans = residue_reduce(Poly(-2/x, t), Poly(t**2 - 1, t), DE, z, invert=True)
|
||||
assert ans == ([(Poly(z**2 - 1, z, domain='QQ'), Poly(t + z, t))], True)
|
||||
assert residue_reduce_to_basic(ans[0], DE, z) == -log(-1 + log(x)) + log(1 + log(x))
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(-t**2 - t/x - (1 - nu**2/x**2), t)]})
|
||||
# TODO: Skip or make faster
|
||||
assert residue_reduce(Poly((-2*nu**2 - x**4)/(2*x**2)*t - (1 + x**2)/x, t),
|
||||
Poly(t**2 + 1 + x**2/2, t), DE, z) == \
|
||||
([(Poly(z + S.Half, z, domain='QQ'), Poly(t**2 + 1 + x**2/2, t,
|
||||
domain='ZZ(x,nu)'))], True)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1 + t**2, t)]})
|
||||
assert residue_reduce(Poly(-2*x*t + 1 - x**2, t),
|
||||
Poly(t**2 + 2*x*t + 1 + x**2, t), DE, z) == \
|
||||
([(Poly(z**2 + Rational(1, 4), z), Poly(t + x + 2*z, t))], True)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert residue_reduce(Poly(t, t), Poly(t + sqrt(2), t), DE, z) == \
|
||||
([(Poly(z - 1, z, domain='QQ'), Poly(t + sqrt(2), t))], True)
|
||||
|
||||
|
||||
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_integrate_hyperexponential_polynomial():
|
||||
# Without proper cancellation within integrate_hyperexponential_polynomial(),
|
||||
# this will take a long time to complete, and will return a complicated
|
||||
# expression
|
||||
p = Poly((-28*x**11*t0 - 6*x**8*t0 + 6*x**9*t0 - 15*x**8*t0**2 +
|
||||
15*x**7*t0**2 + 84*x**10*t0**2 - 140*x**9*t0**3 - 20*x**6*t0**3 +
|
||||
20*x**7*t0**3 - 15*x**6*t0**4 + 15*x**5*t0**4 + 140*x**8*t0**4 -
|
||||
84*x**7*t0**5 - 6*x**4*t0**5 + 6*x**5*t0**5 + x**3*t0**6 - x**4*t0**6 +
|
||||
28*x**6*t0**6 - 4*x**5*t0**7 + x**9 - x**10 + 4*x**12)/(-8*x**11*t0 +
|
||||
28*x**10*t0**2 - 56*x**9*t0**3 + 70*x**8*t0**4 - 56*x**7*t0**5 +
|
||||
28*x**6*t0**6 - 8*x**5*t0**7 + x**4*t0**8 + x**12)*t1**2 +
|
||||
(-28*x**11*t0 - 12*x**8*t0 + 12*x**9*t0 - 30*x**8*t0**2 +
|
||||
30*x**7*t0**2 + 84*x**10*t0**2 - 140*x**9*t0**3 - 40*x**6*t0**3 +
|
||||
40*x**7*t0**3 - 30*x**6*t0**4 + 30*x**5*t0**4 + 140*x**8*t0**4 -
|
||||
84*x**7*t0**5 - 12*x**4*t0**5 + 12*x**5*t0**5 - 2*x**4*t0**6 +
|
||||
2*x**3*t0**6 + 28*x**6*t0**6 - 4*x**5*t0**7 + 2*x**9 - 2*x**10 +
|
||||
4*x**12)/(-8*x**11*t0 + 28*x**10*t0**2 - 56*x**9*t0**3 +
|
||||
70*x**8*t0**4 - 56*x**7*t0**5 + 28*x**6*t0**6 - 8*x**5*t0**7 +
|
||||
x**4*t0**8 + x**12)*t1 + (-2*x**2*t0 + 2*x**3*t0 + x*t0**2 -
|
||||
x**2*t0**2 + x**3 - x**4)/(-4*x**5*t0 + 6*x**4*t0**2 - 4*x**3*t0**3 +
|
||||
x**2*t0**4 + x**6), t1, z, expand=False)
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t0), Poly(2*x*t1, t1)]})
|
||||
assert integrate_hyperexponential_polynomial(p, DE, z) == (
|
||||
Poly((x - t0)*t1**2 + (-2*t0 + 2*x)*t1, t1), Poly(-2*x*t0 + x**2 +
|
||||
t0**2, t1), True)
|
||||
|
||||
DE = DifferentialExtension(extension={'D':[Poly(1, x), Poly(t0, t0)]})
|
||||
assert integrate_hyperexponential_polynomial(Poly(0, t0), DE, z) == (
|
||||
Poly(0, t0), Poly(1, t0), True)
|
||||
|
||||
|
||||
def test_integrate_hyperexponential_returns_piecewise():
|
||||
a, b = symbols('a b')
|
||||
DE = DifferentialExtension(a**x, x)
|
||||
assert integrate_hyperexponential(DE.fa, DE.fd, DE) == (Piecewise(
|
||||
(exp(x*log(a))/log(a), Ne(log(a), 0)), (x, True)), 0, True)
|
||||
DE = DifferentialExtension(a**(b*x), x)
|
||||
assert integrate_hyperexponential(DE.fa, DE.fd, DE) == (Piecewise(
|
||||
(exp(b*x*log(a))/(b*log(a)), Ne(b*log(a), 0)), (x, True)), 0, True)
|
||||
DE = DifferentialExtension(exp(a*x), x)
|
||||
assert integrate_hyperexponential(DE.fa, DE.fd, DE) == (Piecewise(
|
||||
(exp(a*x)/a, Ne(a, 0)), (x, True)), 0, True)
|
||||
DE = DifferentialExtension(x*exp(a*x), x)
|
||||
assert integrate_hyperexponential(DE.fa, DE.fd, DE) == (Piecewise(
|
||||
((a*x - 1)*exp(a*x)/a**2, Ne(a**2, 0)), (x**2/2, True)), 0, True)
|
||||
DE = DifferentialExtension(x**2*exp(a*x), x)
|
||||
assert integrate_hyperexponential(DE.fa, DE.fd, DE) == (Piecewise(
|
||||
((x**2*a**2 - 2*a*x + 2)*exp(a*x)/a**3, Ne(a**3, 0)),
|
||||
(x**3/3, True)), 0, True)
|
||||
DE = DifferentialExtension(x**y + z, y)
|
||||
assert integrate_hyperexponential(DE.fa, DE.fd, DE) == (Piecewise(
|
||||
(exp(log(x)*y)/log(x), Ne(log(x), 0)), (y, True)), z, True)
|
||||
DE = DifferentialExtension(x**y + z + x**(2*y), y)
|
||||
assert integrate_hyperexponential(DE.fa, DE.fd, DE) == (Piecewise(
|
||||
((exp(2*log(x)*y)*log(x) +
|
||||
2*exp(log(x)*y)*log(x))/(2*log(x)**2), Ne(2*log(x)**2, 0)),
|
||||
(2*y, True),
|
||||
), z, True)
|
||||
# TODO: Add a test where two different parts of the extension use a
|
||||
# Piecewise, like y**x + z**x.
|
||||
|
||||
|
||||
def test_issue_13947():
|
||||
a, t, s = symbols('a t s')
|
||||
assert risch_integrate(2**(-pi)/(2**t + 1), t) == \
|
||||
2**(-pi)*t - 2**(-pi)*log(2**t + 1)/log(2)
|
||||
assert risch_integrate(a**(t - s)/(a**t + 1), t) == \
|
||||
exp(-s*log(a))*log(a**t + 1)/log(a)
|
||||
|
||||
|
||||
def test_integrate_primitive():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t)],
|
||||
'Tfuncs': [log]})
|
||||
assert integrate_primitive(Poly(t, t), Poly(1, t), DE) == (x*log(x), -1, True)
|
||||
assert integrate_primitive(Poly(x, t), Poly(t, t), DE) == (0, NonElementaryIntegral(x/log(x), x), False)
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t1), Poly(1/(x + 1), t2)],
|
||||
'Tfuncs': [log, Lambda(i, log(i + 1))]})
|
||||
assert integrate_primitive(Poly(t1, t2), Poly(t2, t2), DE) == \
|
||||
(0, NonElementaryIntegral(log(x)/log(1 + x), x), False)
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t1), Poly(1/(x*t1), t2)],
|
||||
'Tfuncs': [log, Lambda(i, log(log(i)))]})
|
||||
assert integrate_primitive(Poly(t2, t2), Poly(t1, t2), DE) == \
|
||||
(0, NonElementaryIntegral(log(log(x))/log(x), x), False)
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(1/x, t0)],
|
||||
'Tfuncs': [log]})
|
||||
assert integrate_primitive(Poly(x**2*t0**3 + (3*x**2 + x)*t0**2 + (3*x**2
|
||||
+ 2*x)*t0 + x**2 + x, t0), Poly(x**2*t0**4 + 4*x**2*t0**3 + 6*x**2*t0**2 +
|
||||
4*x**2*t0 + x**2, t0), DE) == \
|
||||
(-1/(log(x) + 1), NonElementaryIntegral(1/(log(x) + 1), x), False)
|
||||
|
||||
def test_integrate_hypertangent_polynomial():
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t**2 + 1, t)]})
|
||||
assert integrate_hypertangent_polynomial(Poly(t**2 + x*t + 1, t), DE) == \
|
||||
(Poly(t, t), Poly(x/2, t))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(a*(t**2 + 1), t)]})
|
||||
assert integrate_hypertangent_polynomial(Poly(t**5, t), DE) == \
|
||||
(Poly(1/(4*a)*t**4 - 1/(2*a)*t**2, t), Poly(1/(2*a), t))
|
||||
|
||||
|
||||
def test_integrate_nonlinear_no_specials():
|
||||
a, d, = Poly(x**2*t**5 + x*t**4 - nu**2*t**3 - x*(x**2 + 1)*t**2 - (x**2 -
|
||||
nu**2)*t - x**5/4, t), Poly(x**2*t**4 + x**2*(x**2 + 2)*t**2 + x**2 + x**4 + x**6/4, t)
|
||||
# f(x) == phi_nu(x), the logarithmic derivative of J_v, the Bessel function,
|
||||
# which has no specials (see Chapter 5, note 4 of Bronstein's book).
|
||||
f = Function('phi_nu')
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x),
|
||||
Poly(-t**2 - t/x - (1 - nu**2/x**2), t)], 'Tfuncs': [f]})
|
||||
assert integrate_nonlinear_no_specials(a, d, DE) == \
|
||||
(-log(1 + f(x)**2 + x**2/2)/2 + (- 4 - x**2)/(4 + 2*x**2 + 4*f(x)**2), True)
|
||||
assert integrate_nonlinear_no_specials(Poly(t, t), Poly(1, t), DE) == \
|
||||
(0, False)
|
||||
|
||||
|
||||
def test_integer_powers():
|
||||
assert integer_powers([x, x/2, x**2 + 1, x*Rational(2, 3)]) == [
|
||||
(x/6, [(x, 6), (x/2, 3), (x*Rational(2, 3), 4)]),
|
||||
(1 + x**2, [(1 + x**2, 1)])]
|
||||
|
||||
|
||||
def test_DifferentialExtension_exp():
|
||||
assert DifferentialExtension(exp(x) + exp(x**2), x)._important_attrs == \
|
||||
(Poly(t1 + t0, t1), Poly(1, t1), [Poly(1, x,), Poly(t0, t0),
|
||||
Poly(2*x*t1, t1)], [x, t0, t1], [Lambda(i, exp(i)),
|
||||
Lambda(i, exp(i**2))], [], [None, 'exp', 'exp'], [None, x, x**2])
|
||||
assert DifferentialExtension(exp(x) + exp(2*x), x)._important_attrs == \
|
||||
(Poly(t0**2 + t0, t0), Poly(1, t0), [Poly(1, x), Poly(t0, t0)], [x, t0],
|
||||
[Lambda(i, exp(i))], [], [None, 'exp'], [None, x])
|
||||
assert DifferentialExtension(exp(x) + exp(x/2), x)._important_attrs == \
|
||||
(Poly(t0**2 + t0, t0), Poly(1, t0), [Poly(1, x), Poly(t0/2, t0)],
|
||||
[x, t0], [Lambda(i, exp(i/2))], [], [None, 'exp'], [None, x/2])
|
||||
assert DifferentialExtension(exp(x) + exp(x**2) + exp(x + x**2), x)._important_attrs == \
|
||||
(Poly((1 + t0)*t1 + t0, t1), Poly(1, t1), [Poly(1, x), Poly(t0, t0),
|
||||
Poly(2*x*t1, t1)], [x, t0, t1], [Lambda(i, exp(i)),
|
||||
Lambda(i, exp(i**2))], [], [None, 'exp', 'exp'], [None, x, x**2])
|
||||
assert DifferentialExtension(exp(x) + exp(x**2) + exp(x + x**2 + 1), x)._important_attrs == \
|
||||
(Poly((1 + S.Exp1*t0)*t1 + t0, t1), Poly(1, t1), [Poly(1, x),
|
||||
Poly(t0, t0), Poly(2*x*t1, t1)], [x, t0, t1], [Lambda(i, exp(i)),
|
||||
Lambda(i, exp(i**2))], [], [None, 'exp', 'exp'], [None, x, x**2])
|
||||
assert DifferentialExtension(exp(x) + exp(x**2) + exp(x/2 + x**2), x)._important_attrs == \
|
||||
(Poly((t0 + 1)*t1 + t0**2, t1), Poly(1, t1), [Poly(1, x),
|
||||
Poly(t0/2, t0), Poly(2*x*t1, t1)], [x, t0, t1],
|
||||
[Lambda(i, exp(i/2)), Lambda(i, exp(i**2))],
|
||||
[(exp(x/2), sqrt(exp(x)))], [None, 'exp', 'exp'], [None, x/2, x**2])
|
||||
assert DifferentialExtension(exp(x) + exp(x**2) + exp(x/2 + x**2 + 3), x)._important_attrs == \
|
||||
(Poly((t0*exp(3) + 1)*t1 + t0**2, t1), Poly(1, t1), [Poly(1, x),
|
||||
Poly(t0/2, t0), Poly(2*x*t1, t1)], [x, t0, t1], [Lambda(i, exp(i/2)),
|
||||
Lambda(i, exp(i**2))], [(exp(x/2), sqrt(exp(x)))], [None, 'exp', 'exp'],
|
||||
[None, x/2, x**2])
|
||||
assert DifferentialExtension(sqrt(exp(x)), x)._important_attrs == \
|
||||
(Poly(t0, t0), Poly(1, t0), [Poly(1, x), Poly(t0/2, t0)], [x, t0],
|
||||
[Lambda(i, exp(i/2))], [(exp(x/2), sqrt(exp(x)))], [None, 'exp'], [None, x/2])
|
||||
|
||||
assert DifferentialExtension(exp(x/2), x)._important_attrs == \
|
||||
(Poly(t0, t0), Poly(1, t0), [Poly(1, x), Poly(t0/2, t0)], [x, t0],
|
||||
[Lambda(i, exp(i/2))], [], [None, 'exp'], [None, x/2])
|
||||
|
||||
|
||||
def test_DifferentialExtension_log():
|
||||
assert DifferentialExtension(log(x)*log(x + 1)*log(2*x**2 + 2*x), x)._important_attrs == \
|
||||
(Poly(t0*t1**2 + (t0*log(2) + t0**2)*t1, t1), Poly(1, t1),
|
||||
[Poly(1, x), Poly(1/x, t0),
|
||||
Poly(1/(x + 1), t1, expand=False)], [x, t0, t1],
|
||||
[Lambda(i, log(i)), Lambda(i, log(i + 1))], [], [None, 'log', 'log'],
|
||||
[None, x, x + 1])
|
||||
assert DifferentialExtension(x**x*log(x), x)._important_attrs == \
|
||||
(Poly(t0*t1, t1), Poly(1, t1), [Poly(1, x), Poly(1/x, t0),
|
||||
Poly((1 + t0)*t1, t1)], [x, t0, t1], [Lambda(i, log(i)),
|
||||
Lambda(i, exp(t0*i))], [(exp(x*log(x)), x**x)], [None, 'log', 'exp'],
|
||||
[None, x, t0*x])
|
||||
|
||||
|
||||
def test_DifferentialExtension_symlog():
|
||||
# See comment on test_risch_integrate below
|
||||
assert DifferentialExtension(log(x**x), x)._important_attrs == \
|
||||
(Poly(t0*x, t1), Poly(1, t1), [Poly(1, x), Poly(1/x, t0), Poly((t0 +
|
||||
1)*t1, t1)], [x, t0, t1], [Lambda(i, log(i)), Lambda(i, exp(i*t0))],
|
||||
[(exp(x*log(x)), x**x)], [None, 'log', 'exp'], [None, x, t0*x])
|
||||
assert DifferentialExtension(log(x**y), x)._important_attrs == \
|
||||
(Poly(y*t0, t0), Poly(1, t0), [Poly(1, x), Poly(1/x, t0)], [x, t0],
|
||||
[Lambda(i, log(i))], [(y*log(x), log(x**y))], [None, 'log'],
|
||||
[None, x])
|
||||
assert DifferentialExtension(log(sqrt(x)), x)._important_attrs == \
|
||||
(Poly(t0, t0), Poly(2, t0), [Poly(1, x), Poly(1/x, t0)], [x, t0],
|
||||
[Lambda(i, log(i))], [(log(x)/2, log(sqrt(x)))], [None, 'log'],
|
||||
[None, x])
|
||||
|
||||
|
||||
def test_DifferentialExtension_handle_first():
|
||||
assert DifferentialExtension(exp(x)*log(x), x, handle_first='log')._important_attrs == \
|
||||
(Poly(t0*t1, t1), Poly(1, t1), [Poly(1, x), Poly(1/x, t0),
|
||||
Poly(t1, t1)], [x, t0, t1], [Lambda(i, log(i)), Lambda(i, exp(i))],
|
||||
[], [None, 'log', 'exp'], [None, x, x])
|
||||
assert DifferentialExtension(exp(x)*log(x), x, handle_first='exp')._important_attrs == \
|
||||
(Poly(t0*t1, t1), Poly(1, t1), [Poly(1, x), Poly(t0, t0),
|
||||
Poly(1/x, t1)], [x, t0, t1], [Lambda(i, exp(i)), Lambda(i, log(i))],
|
||||
[], [None, 'exp', 'log'], [None, x, x])
|
||||
|
||||
# This one must have the log first, regardless of what we set it to
|
||||
# (because the log is inside of the exponential: x**x == exp(x*log(x)))
|
||||
assert DifferentialExtension(-x**x*log(x)**2 + x**x - x**x/x, x,
|
||||
handle_first='exp')._important_attrs == \
|
||||
DifferentialExtension(-x**x*log(x)**2 + x**x - x**x/x, x,
|
||||
handle_first='log')._important_attrs == \
|
||||
(Poly((-1 + x - x*t0**2)*t1, t1), Poly(x, t1),
|
||||
[Poly(1, x), Poly(1/x, t0), Poly((1 + t0)*t1, t1)], [x, t0, t1],
|
||||
[Lambda(i, log(i)), Lambda(i, exp(t0*i))], [(exp(x*log(x)), x**x)],
|
||||
[None, 'log', 'exp'], [None, x, t0*x])
|
||||
|
||||
|
||||
def test_DifferentialExtension_all_attrs():
|
||||
# Test 'unimportant' attributes
|
||||
DE = DifferentialExtension(exp(x)*log(x), x, handle_first='exp')
|
||||
assert DE.f == exp(x)*log(x)
|
||||
assert DE.newf == t0*t1
|
||||
assert DE.x == x
|
||||
assert DE.cases == ['base', 'exp', 'primitive']
|
||||
assert DE.case == 'primitive'
|
||||
|
||||
assert DE.level == -1
|
||||
assert DE.t == t1 == DE.T[DE.level]
|
||||
assert DE.d == Poly(1/x, t1) == DE.D[DE.level]
|
||||
raises(ValueError, lambda: DE.increment_level())
|
||||
DE.decrement_level()
|
||||
assert DE.level == -2
|
||||
assert DE.t == t0 == DE.T[DE.level]
|
||||
assert DE.d == Poly(t0, t0) == DE.D[DE.level]
|
||||
assert DE.case == 'exp'
|
||||
DE.decrement_level()
|
||||
assert DE.level == -3
|
||||
assert DE.t == x == DE.T[DE.level] == DE.x
|
||||
assert DE.d == Poly(1, x) == DE.D[DE.level]
|
||||
assert DE.case == 'base'
|
||||
raises(ValueError, lambda: DE.decrement_level())
|
||||
DE.increment_level()
|
||||
DE.increment_level()
|
||||
assert DE.level == -1
|
||||
assert DE.t == t1 == DE.T[DE.level]
|
||||
assert DE.d == Poly(1/x, t1) == DE.D[DE.level]
|
||||
assert DE.case == 'primitive'
|
||||
|
||||
# Test methods
|
||||
assert DE.indices('log') == [2]
|
||||
assert DE.indices('exp') == [1]
|
||||
|
||||
|
||||
def test_DifferentialExtension_extension_flag():
|
||||
raises(ValueError, lambda: DifferentialExtension(extension={'T': [x, t]}))
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)]})
|
||||
assert DE._important_attrs == (None, None, [Poly(1, x), Poly(t, t)], [x, t],
|
||||
None, None, None, None)
|
||||
assert DE.d == Poly(t, t)
|
||||
assert DE.t == t
|
||||
assert DE.level == -1
|
||||
assert DE.cases == ['base', 'exp']
|
||||
assert DE.x == x
|
||||
assert DE.case == 'exp'
|
||||
|
||||
DE = DifferentialExtension(extension={'D': [Poly(1, x), Poly(t, t)],
|
||||
'exts': [None, 'exp'], 'extargs': [None, x]})
|
||||
assert DE._important_attrs == (None, None, [Poly(1, x), Poly(t, t)], [x, t],
|
||||
None, None, [None, 'exp'], [None, x])
|
||||
raises(ValueError, lambda: DifferentialExtension())
|
||||
|
||||
|
||||
def test_DifferentialExtension_misc():
|
||||
# Odd ends
|
||||
assert DifferentialExtension(sin(y)*exp(x), x)._important_attrs == \
|
||||
(Poly(sin(y)*t0, t0, domain='ZZ[sin(y)]'), Poly(1, t0, domain='ZZ'),
|
||||
[Poly(1, x, domain='ZZ'), Poly(t0, t0, domain='ZZ')], [x, t0],
|
||||
[Lambda(i, exp(i))], [], [None, 'exp'], [None, x])
|
||||
raises(NotImplementedError, lambda: DifferentialExtension(sin(x), x))
|
||||
assert DifferentialExtension(10**x, x)._important_attrs == \
|
||||
(Poly(t0, t0), Poly(1, t0), [Poly(1, x), Poly(log(10)*t0, t0)], [x, t0],
|
||||
[Lambda(i, exp(i*log(10)))], [(exp(x*log(10)), 10**x)], [None, 'exp'],
|
||||
[None, x*log(10)])
|
||||
assert DifferentialExtension(log(x) + log(x**2), x)._important_attrs in [
|
||||
(Poly(3*t0, t0), Poly(2, t0), [Poly(1, x), Poly(2/x, t0)], [x, t0],
|
||||
[Lambda(i, log(i**2))], [], [None, ], [], [1], [x**2]),
|
||||
(Poly(3*t0, t0), Poly(1, t0), [Poly(1, x), Poly(1/x, t0)], [x, t0],
|
||||
[Lambda(i, log(i))], [], [None, 'log'], [None, x])]
|
||||
assert DifferentialExtension(S.Zero, x)._important_attrs == \
|
||||
(Poly(0, x), Poly(1, x), [Poly(1, x)], [x], [], [], [None], [None])
|
||||
assert DifferentialExtension(tan(atan(x).rewrite(log)), x)._important_attrs == \
|
||||
(Poly(x, x), Poly(1, x), [Poly(1, x)], [x], [], [], [None], [None])
|
||||
|
||||
|
||||
def test_DifferentialExtension_Rothstein():
|
||||
# Rothstein's integral
|
||||
f = (2581284541*exp(x) + 1757211400)/(39916800*exp(3*x) +
|
||||
119750400*exp(x)**2 + 119750400*exp(x) + 39916800)*exp(1/(exp(x) + 1) - 10*x)
|
||||
assert DifferentialExtension(f, x)._important_attrs == \
|
||||
(Poly((1757211400 + 2581284541*t0)*t1, t1), Poly(39916800 +
|
||||
119750400*t0 + 119750400*t0**2 + 39916800*t0**3, t1),
|
||||
[Poly(1, x), Poly(t0, t0), Poly(-(10 + 21*t0 + 10*t0**2)/(1 + 2*t0 +
|
||||
t0**2)*t1, t1, domain='ZZ(t0)')], [x, t0, t1],
|
||||
[Lambda(i, exp(i)), Lambda(i, exp(1/(t0 + 1) - 10*i))], [],
|
||||
[None, 'exp', 'exp'], [None, x, 1/(t0 + 1) - 10*x])
|
||||
|
||||
|
||||
class _TestingException(Exception):
|
||||
"""Dummy Exception class for testing."""
|
||||
pass
|
||||
|
||||
|
||||
def test_DecrementLevel():
|
||||
DE = DifferentialExtension(x*log(exp(x) + 1), x)
|
||||
assert DE.level == -1
|
||||
assert DE.t == t1
|
||||
assert DE.d == Poly(t0/(t0 + 1), t1)
|
||||
assert DE.case == 'primitive'
|
||||
|
||||
with DecrementLevel(DE):
|
||||
assert DE.level == -2
|
||||
assert DE.t == t0
|
||||
assert DE.d == Poly(t0, t0)
|
||||
assert DE.case == 'exp'
|
||||
|
||||
with DecrementLevel(DE):
|
||||
assert DE.level == -3
|
||||
assert DE.t == x
|
||||
assert DE.d == Poly(1, x)
|
||||
assert DE.case == 'base'
|
||||
|
||||
assert DE.level == -2
|
||||
assert DE.t == t0
|
||||
assert DE.d == Poly(t0, t0)
|
||||
assert DE.case == 'exp'
|
||||
|
||||
assert DE.level == -1
|
||||
assert DE.t == t1
|
||||
assert DE.d == Poly(t0/(t0 + 1), t1)
|
||||
assert DE.case == 'primitive'
|
||||
|
||||
# Test that __exit__ is called after an exception correctly
|
||||
try:
|
||||
with DecrementLevel(DE):
|
||||
raise _TestingException
|
||||
except _TestingException:
|
||||
pass
|
||||
else:
|
||||
raise AssertionError("Did not raise.")
|
||||
|
||||
assert DE.level == -1
|
||||
assert DE.t == t1
|
||||
assert DE.d == Poly(t0/(t0 + 1), t1)
|
||||
assert DE.case == 'primitive'
|
||||
|
||||
|
||||
def test_risch_integrate():
|
||||
assert risch_integrate(t0*exp(x), x) == t0*exp(x)
|
||||
assert risch_integrate(sin(x), x, rewrite_complex=True) == -exp(I*x)/2 - exp(-I*x)/2
|
||||
|
||||
# From my GSoC writeup
|
||||
assert risch_integrate((1 + 2*x**2 + x**4 + 2*x**3*exp(2*x**2))/
|
||||
(x**4*exp(x**2) + 2*x**2*exp(x**2) + exp(x**2)), x) == \
|
||||
NonElementaryIntegral(exp(-x**2), x) + exp(x**2)/(1 + x**2)
|
||||
|
||||
|
||||
assert risch_integrate(0, x) == 0
|
||||
|
||||
# also tests prde_cancel()
|
||||
e1 = log(x/exp(x) + 1)
|
||||
ans1 = risch_integrate(e1, x)
|
||||
assert ans1 == (x*log(x*exp(-x) + 1) + NonElementaryIntegral((x**2 - x)/(x + exp(x)), x))
|
||||
assert cancel(diff(ans1, x) - e1) == 0
|
||||
|
||||
# also tests issue #10798
|
||||
e2 = (log(-1/y)/2 - log(1/y)/2)/y - (log(1 - 1/y)/2 - log(1 + 1/y)/2)/y
|
||||
ans2 = risch_integrate(e2, y)
|
||||
assert ans2 == log(1/y)*log(1 - 1/y)/2 - log(1/y)*log(1 + 1/y)/2 + \
|
||||
NonElementaryIntegral((I*pi*y**2 - 2*y*log(1/y) - I*pi)/(2*y**3 - 2*y), y)
|
||||
assert expand_log(cancel(diff(ans2, y) - e2), force=True) == 0
|
||||
|
||||
# These are tested here in addition to in test_DifferentialExtension above
|
||||
# (symlogs) to test that backsubs works correctly. The integrals should be
|
||||
# written in terms of the original logarithms in the integrands.
|
||||
|
||||
# XXX: Unfortunately, making backsubs work on this one is a little
|
||||
# trickier, because x**x is converted to exp(x*log(x)), and so log(x**x)
|
||||
# is converted to x*log(x). (x**2*log(x)).subs(x*log(x), log(x**x)) is
|
||||
# smart enough, the issue is that these splits happen at different places
|
||||
# in the algorithm. Maybe a heuristic is in order
|
||||
assert risch_integrate(log(x**x), x) == x**2*log(x)/2 - x**2/4
|
||||
|
||||
assert risch_integrate(log(x**y), x) == x*log(x**y) - x*y
|
||||
assert risch_integrate(log(sqrt(x)), x) == x*log(sqrt(x)) - x/2
|
||||
|
||||
|
||||
def test_risch_integrate_float():
|
||||
assert risch_integrate((-60*exp(x) - 19.2*exp(4*x))*exp(4*x), x) == -2.4*exp(8*x) - 12.0*exp(5*x)
|
||||
|
||||
|
||||
def test_NonElementaryIntegral():
|
||||
assert isinstance(risch_integrate(exp(x**2), x), NonElementaryIntegral)
|
||||
assert isinstance(risch_integrate(x**x*log(x), x), NonElementaryIntegral)
|
||||
# Make sure methods of Integral still give back a NonElementaryIntegral
|
||||
assert isinstance(NonElementaryIntegral(x**x*t0, x).subs(t0, log(x)), NonElementaryIntegral)
|
||||
|
||||
|
||||
def test_xtothex():
|
||||
a = risch_integrate(x**x, x)
|
||||
assert a == NonElementaryIntegral(x**x, x)
|
||||
assert isinstance(a, NonElementaryIntegral)
|
||||
|
||||
|
||||
def test_DifferentialExtension_equality():
|
||||
DE1 = DE2 = DifferentialExtension(log(x), x)
|
||||
assert DE1 == DE2
|
||||
|
||||
|
||||
def test_DifferentialExtension_printing():
|
||||
DE = DifferentialExtension(exp(2*x**2) + log(exp(x**2) + 1), x)
|
||||
assert repr(DE) == ("DifferentialExtension(dict([('f', exp(2*x**2) + log(exp(x**2) + 1)), "
|
||||
"('x', x), ('T', [x, t0, t1]), ('D', [Poly(1, x, domain='ZZ'), Poly(2*x*t0, t0, domain='ZZ[x]'), "
|
||||
"Poly(2*t0*x/(t0 + 1), t1, domain='ZZ(x,t0)')]), ('fa', Poly(t1 + t0**2, t1, domain='ZZ[t0]')), "
|
||||
"('fd', Poly(1, t1, domain='ZZ')), ('Tfuncs', [Lambda(i, exp(i**2)), Lambda(i, log(t0 + 1))]), "
|
||||
"('backsubs', []), ('exts', [None, 'exp', 'log']), ('extargs', [None, x**2, t0 + 1]), "
|
||||
"('cases', ['base', 'exp', 'primitive']), ('case', 'primitive'), ('t', t1), "
|
||||
"('d', Poly(2*t0*x/(t0 + 1), t1, domain='ZZ(x,t0)')), ('newf', t0**2 + t1), ('level', -1), "
|
||||
"('dummy', False)]))")
|
||||
|
||||
assert str(DE) == ("DifferentialExtension({fa=Poly(t1 + t0**2, t1, domain='ZZ[t0]'), "
|
||||
"fd=Poly(1, t1, domain='ZZ'), D=[Poly(1, x, domain='ZZ'), Poly(2*x*t0, t0, domain='ZZ[x]'), "
|
||||
"Poly(2*t0*x/(t0 + 1), t1, domain='ZZ(x,t0)')]})")
|
||||
|
||||
|
||||
def test_issue_23948():
|
||||
f = (
|
||||
( (-2*x**5 + 28*x**4 - 144*x**3 + 324*x**2 - 270*x)*log(x)**2
|
||||
+(-4*x**6 + 56*x**5 - 288*x**4 + 648*x**3 - 540*x**2)*log(x)
|
||||
+(2*x**5 - 28*x**4 + 144*x**3 - 324*x**2 + 270*x)*exp(x)
|
||||
+(2*x**5 - 28*x**4 + 144*x**3 - 324*x**2 + 270*x)*log(5)
|
||||
-2*x**7 + 26*x**6 - 116*x**5 + 180*x**4 + 54*x**3 - 270*x**2
|
||||
)*log(-log(x)**2 - 2*x*log(x) + exp(x) + log(5) - x**2 - x)**2
|
||||
+( (4*x**5 - 44*x**4 + 168*x**3 - 216*x**2 - 108*x + 324)*log(x)
|
||||
+(-2*x**5 + 24*x**4 - 108*x**3 + 216*x**2 - 162*x)*exp(x)
|
||||
+4*x**6 - 42*x**5 + 144*x**4 - 108*x**3 - 324*x**2 + 486*x
|
||||
)*log(-log(x)**2 - 2*x*log(x) + exp(x) + log(5) - x**2 - x)
|
||||
)/(x*exp(x)**2*log(x)**2 + 2*x**2*exp(x)**2*log(x) - x*exp(x)**3
|
||||
+(-x*log(5) + x**3 + x**2)*exp(x)**2)
|
||||
|
||||
F = ((x**4 - 12*x**3 + 54*x**2 - 108*x + 81)*exp(-2*x)
|
||||
*log(-x**2 - 2*x*log(x) - x + exp(x) - log(x)**2 + log(5))**2)
|
||||
|
||||
assert risch_integrate(f, x) == F
|
||||
@@ -0,0 +1,22 @@
|
||||
from sympy.integrals.singularityfunctions import singularityintegrate
|
||||
from sympy.core.function import Function
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.special.singularity_functions import SingularityFunction
|
||||
|
||||
x, a, n, y = symbols('x a n y')
|
||||
f = Function('f')
|
||||
|
||||
|
||||
def test_singularityintegrate():
|
||||
assert singularityintegrate(x, x) is None
|
||||
assert singularityintegrate(x + SingularityFunction(x, 9, 1), x) is None
|
||||
|
||||
assert 4*singularityintegrate(SingularityFunction(x, a, 3), x) == 4*SingularityFunction(x, a, 4)/4
|
||||
assert singularityintegrate(5*SingularityFunction(x, 5, -2), x) == 5*SingularityFunction(x, 5, -1)
|
||||
assert singularityintegrate(6*SingularityFunction(x, 5, -1), x) == 6*SingularityFunction(x, 5, 0)
|
||||
assert singularityintegrate(x*SingularityFunction(x, 0, -1), x) == 0
|
||||
assert singularityintegrate((x - 5)*SingularityFunction(x, 5, -1), x) == 0
|
||||
assert singularityintegrate(SingularityFunction(x, 0, -1) * f(x), x) == f(0) * SingularityFunction(x, 0, 0)
|
||||
assert singularityintegrate(SingularityFunction(x, 1, -1) * f(x), x) == f(1) * SingularityFunction(x, 1, 0)
|
||||
assert singularityintegrate(y*SingularityFunction(x, 0, -1)**2, x) == \
|
||||
y*SingularityFunction(0, 0, -1)*SingularityFunction(x, 0, 0)
|
||||
@@ -0,0 +1,637 @@
|
||||
from sympy.integrals.transforms import (
|
||||
mellin_transform, inverse_mellin_transform,
|
||||
fourier_transform, inverse_fourier_transform,
|
||||
sine_transform, inverse_sine_transform,
|
||||
cosine_transform, inverse_cosine_transform,
|
||||
hankel_transform, inverse_hankel_transform,
|
||||
FourierTransform, SineTransform, CosineTransform, InverseFourierTransform,
|
||||
InverseSineTransform, InverseCosineTransform, IntegralTransformError)
|
||||
from sympy.integrals.laplace import (
|
||||
laplace_transform, inverse_laplace_transform)
|
||||
from sympy.core.function import Function, expand_mul
|
||||
from sympy.core import EulerGamma
|
||||
from sympy.core.numbers import I, Rational, oo, pi
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import Symbol, symbols
|
||||
from sympy.functions.combinatorial.factorials import factorial
|
||||
from sympy.functions.elementary.complexes import re, unpolarify
|
||||
from sympy.functions.elementary.exponential import exp, exp_polar, log
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import atan, cos, sin, tan
|
||||
from sympy.functions.special.bessel import besseli, besselj, besselk, bessely
|
||||
from sympy.functions.special.delta_functions import Heaviside
|
||||
from sympy.functions.special.error_functions import erf, expint
|
||||
from sympy.functions.special.gamma_functions import gamma
|
||||
from sympy.functions.special.hyper import meijerg
|
||||
from sympy.simplify.gammasimp import gammasimp
|
||||
from sympy.simplify.hyperexpand import hyperexpand
|
||||
from sympy.simplify.trigsimp import trigsimp
|
||||
from sympy.testing.pytest import XFAIL, slow, skip, raises
|
||||
from sympy.abc import x, s, a, b, c, d
|
||||
|
||||
|
||||
nu, beta, rho = symbols('nu beta rho')
|
||||
|
||||
|
||||
def test_undefined_function():
|
||||
from sympy.integrals.transforms import MellinTransform
|
||||
f = Function('f')
|
||||
assert mellin_transform(f(x), x, s) == MellinTransform(f(x), x, s)
|
||||
assert mellin_transform(f(x) + exp(-x), x, s) == \
|
||||
(MellinTransform(f(x), x, s) + gamma(s + 1)/s, (0, oo), True)
|
||||
|
||||
|
||||
def test_free_symbols():
|
||||
f = Function('f')
|
||||
assert mellin_transform(f(x), x, s).free_symbols == {s}
|
||||
assert mellin_transform(f(x)*a, x, s).free_symbols == {s, a}
|
||||
|
||||
|
||||
def test_as_integral():
|
||||
from sympy.integrals.integrals import Integral
|
||||
f = Function('f')
|
||||
assert mellin_transform(f(x), x, s).rewrite('Integral') == \
|
||||
Integral(x**(s - 1)*f(x), (x, 0, oo))
|
||||
assert fourier_transform(f(x), x, s).rewrite('Integral') == \
|
||||
Integral(f(x)*exp(-2*I*pi*s*x), (x, -oo, oo))
|
||||
assert laplace_transform(f(x), x, s, noconds=True).rewrite('Integral') == \
|
||||
Integral(f(x)*exp(-s*x), (x, 0, oo))
|
||||
assert str(2*pi*I*inverse_mellin_transform(f(s), s, x, (a, b)).rewrite('Integral')) \
|
||||
== "Integral(f(s)/x**s, (s, _c - oo*I, _c + oo*I))"
|
||||
assert str(2*pi*I*inverse_laplace_transform(f(s), s, x).rewrite('Integral')) == \
|
||||
"Integral(f(s)*exp(s*x), (s, _c - oo*I, _c + oo*I))"
|
||||
assert inverse_fourier_transform(f(s), s, x).rewrite('Integral') == \
|
||||
Integral(f(s)*exp(2*I*pi*s*x), (s, -oo, oo))
|
||||
|
||||
# NOTE this is stuck in risch because meijerint cannot handle it
|
||||
|
||||
|
||||
@slow
|
||||
@XFAIL
|
||||
def test_mellin_transform_fail():
|
||||
skip("Risch takes forever.")
|
||||
|
||||
MT = mellin_transform
|
||||
|
||||
bpos = symbols('b', positive=True)
|
||||
# bneg = symbols('b', negative=True)
|
||||
|
||||
expr = (sqrt(x + b**2) + b)**a/sqrt(x + b**2)
|
||||
# TODO does not work with bneg, argument wrong. Needs changes to matching.
|
||||
assert MT(expr.subs(b, -bpos), x, s) == \
|
||||
((-1)**(a + 1)*2**(a + 2*s)*bpos**(a + 2*s - 1)*gamma(a + s)
|
||||
*gamma(1 - a - 2*s)/gamma(1 - s),
|
||||
(-re(a), -re(a)/2 + S.Half), True)
|
||||
|
||||
expr = (sqrt(x + b**2) + b)**a
|
||||
assert MT(expr.subs(b, -bpos), x, s) == \
|
||||
(
|
||||
2**(a + 2*s)*a*bpos**(a + 2*s)*gamma(-a - 2*
|
||||
s)*gamma(a + s)/gamma(-s + 1),
|
||||
(-re(a), -re(a)/2), True)
|
||||
|
||||
# Test exponent 1:
|
||||
assert MT(expr.subs({b: -bpos, a: 1}), x, s) == \
|
||||
(-bpos**(2*s + 1)*gamma(s)*gamma(-s - S.Half)/(2*sqrt(pi)),
|
||||
(-1, Rational(-1, 2)), True)
|
||||
|
||||
|
||||
def test_mellin_transform():
|
||||
from sympy.functions.elementary.miscellaneous import (Max, Min)
|
||||
MT = mellin_transform
|
||||
|
||||
bpos = symbols('b', positive=True)
|
||||
|
||||
# 8.4.2
|
||||
assert MT(x**nu*Heaviside(x - 1), x, s) == \
|
||||
(-1/(nu + s), (-oo, -re(nu)), True)
|
||||
assert MT(x**nu*Heaviside(1 - x), x, s) == \
|
||||
(1/(nu + s), (-re(nu), oo), True)
|
||||
|
||||
assert MT((1 - x)**(beta - 1)*Heaviside(1 - x), x, s) == \
|
||||
(gamma(beta)*gamma(s)/gamma(beta + s), (0, oo), re(beta) > 0)
|
||||
assert MT((x - 1)**(beta - 1)*Heaviside(x - 1), x, s) == \
|
||||
(gamma(beta)*gamma(1 - beta - s)/gamma(1 - s),
|
||||
(-oo, 1 - re(beta)), re(beta) > 0)
|
||||
|
||||
assert MT((1 + x)**(-rho), x, s) == \
|
||||
(gamma(s)*gamma(rho - s)/gamma(rho), (0, re(rho)), True)
|
||||
|
||||
assert MT(abs(1 - x)**(-rho), x, s) == (
|
||||
2*sin(pi*rho/2)*gamma(1 - rho)*
|
||||
cos(pi*(s - rho/2))*gamma(s)*gamma(rho-s)/pi,
|
||||
(0, re(rho)), re(rho) < 1)
|
||||
mt = MT((1 - x)**(beta - 1)*Heaviside(1 - x)
|
||||
+ a*(x - 1)**(beta - 1)*Heaviside(x - 1), x, s)
|
||||
assert mt[1], mt[2] == ((0, -re(beta) + 1), re(beta) > 0)
|
||||
|
||||
assert MT((x**a - b**a)/(x - b), x, s)[0] == \
|
||||
pi*b**(a + s - 1)*sin(pi*a)/(sin(pi*s)*sin(pi*(a + s)))
|
||||
assert MT((x**a - bpos**a)/(x - bpos), x, s) == \
|
||||
(pi*bpos**(a + s - 1)*sin(pi*a)/(sin(pi*s)*sin(pi*(a + s))),
|
||||
(Max(0, -re(a)), Min(1, 1 - re(a))), True)
|
||||
|
||||
expr = (sqrt(x + b**2) + b)**a
|
||||
assert MT(expr.subs(b, bpos), x, s) == \
|
||||
(-a*(2*bpos)**(a + 2*s)*gamma(s)*gamma(-a - 2*s)/gamma(-a - s + 1),
|
||||
(0, -re(a)/2), True)
|
||||
|
||||
expr = (sqrt(x + b**2) + b)**a/sqrt(x + b**2)
|
||||
assert MT(expr.subs(b, bpos), x, s) == \
|
||||
(2**(a + 2*s)*bpos**(a + 2*s - 1)*gamma(s)
|
||||
*gamma(1 - a - 2*s)/gamma(1 - a - s),
|
||||
(0, -re(a)/2 + S.Half), True)
|
||||
|
||||
# 8.4.2
|
||||
assert MT(exp(-x), x, s) == (gamma(s), (0, oo), True)
|
||||
assert MT(exp(-1/x), x, s) == (gamma(-s), (-oo, 0), True)
|
||||
|
||||
# 8.4.5
|
||||
assert MT(log(x)**4*Heaviside(1 - x), x, s) == (24/s**5, (0, oo), True)
|
||||
assert MT(log(x)**3*Heaviside(x - 1), x, s) == (6/s**4, (-oo, 0), True)
|
||||
assert MT(log(x + 1), x, s) == (pi/(s*sin(pi*s)), (-1, 0), True)
|
||||
assert MT(log(1/x + 1), x, s) == (pi/(s*sin(pi*s)), (0, 1), True)
|
||||
assert MT(log(abs(1 - x)), x, s) == (pi/(s*tan(pi*s)), (-1, 0), True)
|
||||
assert MT(log(abs(1 - 1/x)), x, s) == (pi/(s*tan(pi*s)), (0, 1), True)
|
||||
|
||||
# 8.4.14
|
||||
assert MT(erf(sqrt(x)), x, s) == \
|
||||
(-gamma(s + S.Half)/(sqrt(pi)*s), (Rational(-1, 2), 0), True)
|
||||
|
||||
|
||||
def test_mellin_transform2():
|
||||
MT = mellin_transform
|
||||
# TODO we cannot currently do these (needs summation of 3F2(-1))
|
||||
# this also implies that they cannot be written as a single g-function
|
||||
# (although this is possible)
|
||||
mt = MT(log(x)/(x + 1), x, s)
|
||||
assert mt[1:] == ((0, 1), True)
|
||||
assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg)
|
||||
mt = MT(log(x)**2/(x + 1), x, s)
|
||||
assert mt[1:] == ((0, 1), True)
|
||||
assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg)
|
||||
mt = MT(log(x)/(x + 1)**2, x, s)
|
||||
assert mt[1:] == ((0, 2), True)
|
||||
assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg)
|
||||
|
||||
|
||||
@slow
|
||||
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)
|
||||
# TODO exp(x/2)*besselk(a, x/2) [etc] cannot currently be done
|
||||
# TODO various strange products of special orders
|
||||
|
||||
|
||||
@slow
|
||||
def test_expint():
|
||||
from sympy.functions.elementary.miscellaneous import Max
|
||||
from sympy.functions.special.error_functions import Ci, E1, Si
|
||||
from sympy.simplify.simplify import simplify
|
||||
|
||||
aneg = Symbol('a', negative=True)
|
||||
u = Symbol('u', polar=True)
|
||||
|
||||
assert mellin_transform(E1(x), x, s) == (gamma(s)/s, (0, oo), True)
|
||||
assert inverse_mellin_transform(gamma(s)/s, s, x,
|
||||
(0, oo)).rewrite(expint).expand() == E1(x)
|
||||
assert mellin_transform(expint(a, x), x, s) == \
|
||||
(gamma(s)/(a + s - 1), (Max(1 - re(a), 0), oo), True)
|
||||
# XXX IMT has hickups with complicated strips ...
|
||||
assert simplify(unpolarify(
|
||||
inverse_mellin_transform(gamma(s)/(aneg + s - 1), s, x,
|
||||
(1 - aneg, oo)).rewrite(expint).expand(func=True))) == \
|
||||
expint(aneg, x)
|
||||
|
||||
assert mellin_transform(Si(x), x, s) == \
|
||||
(-2**s*sqrt(pi)*gamma(s/2 + S.Half)/(
|
||||
2*s*gamma(-s/2 + 1)), (-1, 0), True)
|
||||
assert inverse_mellin_transform(-2**s*sqrt(pi)*gamma((s + 1)/2)
|
||||
/(2*s*gamma(-s/2 + 1)), s, x, (-1, 0)) \
|
||||
== Si(x)
|
||||
|
||||
assert mellin_transform(Ci(sqrt(x)), x, s) == \
|
||||
(-2**(2*s - 1)*sqrt(pi)*gamma(s)/(s*gamma(-s + S.Half)), (0, 1), True)
|
||||
assert inverse_mellin_transform(
|
||||
-4**s*sqrt(pi)*gamma(s)/(2*s*gamma(-s + S.Half)),
|
||||
s, u, (0, 1)).expand() == Ci(sqrt(u))
|
||||
|
||||
|
||||
@slow
|
||||
def test_inverse_mellin_transform():
|
||||
from sympy.core.function import expand
|
||||
from sympy.functions.elementary.miscellaneous import (Max, Min)
|
||||
from sympy.functions.elementary.trigonometric import cot
|
||||
from sympy.simplify.powsimp import powsimp
|
||||
from sympy.simplify.simplify import simplify
|
||||
IMT = inverse_mellin_transform
|
||||
|
||||
assert IMT(gamma(s), s, x, (0, oo)) == exp(-x)
|
||||
assert IMT(gamma(-s), s, x, (-oo, 0)) == exp(-1/x)
|
||||
assert simplify(IMT(s/(2*s**2 - 2), s, x, (2, oo))) == \
|
||||
(x**2 + 1)*Heaviside(1 - x)/(4*x)
|
||||
|
||||
# test passing "None"
|
||||
assert IMT(1/(s**2 - 1), s, x, (-1, None)) == \
|
||||
-x*Heaviside(-x + 1)/2 - Heaviside(x - 1)/(2*x)
|
||||
assert IMT(1/(s**2 - 1), s, x, (None, 1)) == \
|
||||
-x*Heaviside(-x + 1)/2 - Heaviside(x - 1)/(2*x)
|
||||
|
||||
# test expansion of sums
|
||||
assert IMT(gamma(s) + gamma(s - 1), s, x, (1, oo)) == (x + 1)*exp(-x)/x
|
||||
|
||||
# test factorisation of polys
|
||||
r = symbols('r', real=True)
|
||||
assert IMT(1/(s**2 + 1), s, exp(-x), (None, oo)
|
||||
).subs(x, r).rewrite(sin).simplify() \
|
||||
== sin(r)*Heaviside(1 - exp(-r))
|
||||
|
||||
# test multiplicative substitution
|
||||
_a, _b = symbols('a b', positive=True)
|
||||
assert IMT(_b**(-s/_a)*factorial(s/_a)/s, s, x, (0, oo)) == exp(-_b*x**_a)
|
||||
assert IMT(factorial(_a/_b + s/_b)/(_a + s), s, x, (-_a, oo)) == x**_a*exp(-x**_b)
|
||||
|
||||
def simp_pows(expr):
|
||||
return simplify(powsimp(expand_mul(expr, deep=False), force=True)).replace(exp_polar, exp)
|
||||
|
||||
# Now test the inverses of all direct transforms tested above
|
||||
|
||||
# Section 8.4.2
|
||||
nu = symbols('nu', real=True)
|
||||
assert IMT(-1/(nu + s), s, x, (-oo, None)) == x**nu*Heaviside(x - 1)
|
||||
assert IMT(1/(nu + s), s, x, (None, oo)) == x**nu*Heaviside(1 - x)
|
||||
assert simp_pows(IMT(gamma(beta)*gamma(s)/gamma(s + beta), s, x, (0, oo))) \
|
||||
== (1 - x)**(beta - 1)*Heaviside(1 - x)
|
||||
assert simp_pows(IMT(gamma(beta)*gamma(1 - beta - s)/gamma(1 - s),
|
||||
s, x, (-oo, None))) \
|
||||
== (x - 1)**(beta - 1)*Heaviside(x - 1)
|
||||
assert simp_pows(IMT(gamma(s)*gamma(rho - s)/gamma(rho), s, x, (0, None))) \
|
||||
== (1/(x + 1))**rho
|
||||
expr = IMT(d**c*d**(s - 1)*sin(pi*c)
|
||||
*gamma(s)*gamma(s + c)*gamma(1 - s)*gamma(1 - s - c)/pi,
|
||||
s, x, (Max(-re(c), 0), Min(1 - re(c), 1)))
|
||||
assert powsimp(expand_mul(expr, deep=False)).replace(exp_polar, exp).simplify() \
|
||||
== (-d**c + x**c)/(-d + x)
|
||||
|
||||
assert simplify(IMT(1/sqrt(pi)*(-c/2)*gamma(s)*gamma((1 - c)/2 - s)
|
||||
*gamma(-c/2 - s)/gamma(1 - c - s),
|
||||
s, x, (0, -re(c)/2))) == \
|
||||
(1 + sqrt(x + 1))**c
|
||||
assert simplify(IMT(2**(a + 2*s)*b**(a + 2*s - 1)*gamma(s)*gamma(1 - a - 2*s)
|
||||
/gamma(1 - a - s), s, x, (0, (-re(a) + 1)/2))) == \
|
||||
b**(a - 1)*(b**2*(sqrt(1 + x/b**2) + 1)**a + x*(sqrt(1 + x/b**2) + 1
|
||||
)**(a - 1))/(b**2 + x)
|
||||
assert simplify(IMT(-2**(c + 2*s)*c*b**(c + 2*s)*gamma(s)*gamma(-c - 2*s)
|
||||
/ gamma(-c - s + 1), s, x, (0, -re(c)/2))) == \
|
||||
b**c*(sqrt(1 + x/b**2) + 1)**c
|
||||
|
||||
# Section 8.4.5
|
||||
assert IMT(24/s**5, s, x, (0, oo)) == log(x)**4*Heaviside(1 - x)
|
||||
assert expand(IMT(6/s**4, s, x, (-oo, 0)), force=True) == \
|
||||
log(x)**3*Heaviside(x - 1)
|
||||
assert IMT(pi/(s*sin(pi*s)), s, x, (-1, 0)) == log(x + 1)
|
||||
assert IMT(pi/(s*sin(pi*s/2)), s, x, (-2, 0)) == log(x**2 + 1)
|
||||
assert IMT(pi/(s*sin(2*pi*s)), s, x, (Rational(-1, 2), 0)) == log(sqrt(x) + 1)
|
||||
assert IMT(pi/(s*sin(pi*s)), s, x, (0, 1)) == log(1 + 1/x)
|
||||
|
||||
# TODO
|
||||
def mysimp(expr):
|
||||
from sympy.core.function import expand
|
||||
from sympy.simplify.powsimp import powsimp
|
||||
from sympy.simplify.simplify import logcombine
|
||||
return expand(
|
||||
powsimp(logcombine(expr, force=True), force=True, deep=True),
|
||||
force=True).replace(exp_polar, exp)
|
||||
|
||||
assert mysimp(mysimp(IMT(pi/(s*tan(pi*s)), s, x, (-1, 0)))) in [
|
||||
log(1 - x)*Heaviside(1 - x) + log(x - 1)*Heaviside(x - 1),
|
||||
log(x)*Heaviside(x - 1) + log(1 - 1/x)*Heaviside(x - 1) + log(-x +
|
||||
1)*Heaviside(-x + 1)]
|
||||
# test passing cot
|
||||
assert mysimp(IMT(pi*cot(pi*s)/s, s, x, (0, 1))) in [
|
||||
log(1/x - 1)*Heaviside(1 - x) + log(1 - 1/x)*Heaviside(x - 1),
|
||||
-log(x)*Heaviside(-x + 1) + log(1 - 1/x)*Heaviside(x - 1) + log(-x +
|
||||
1)*Heaviside(-x + 1), ]
|
||||
|
||||
# 8.4.14
|
||||
assert IMT(-gamma(s + S.Half)/(sqrt(pi)*s), s, x, (Rational(-1, 2), 0)) == \
|
||||
erf(sqrt(x))
|
||||
|
||||
# 8.4.19
|
||||
assert simplify(IMT(gamma(a/2 + s)/gamma(a/2 - s + 1), s, x, (-re(a)/2, Rational(3, 4)))) \
|
||||
== besselj(a, 2*sqrt(x))
|
||||
assert simplify(IMT(2**a*gamma(S.Half - 2*s)*gamma(s + (a + 1)/2)
|
||||
/ (gamma(1 - s - a/2)*gamma(1 - 2*s + a)),
|
||||
s, x, (-(re(a) + 1)/2, Rational(1, 4)))) == \
|
||||
sin(sqrt(x))*besselj(a, sqrt(x))
|
||||
assert simplify(IMT(2**a*gamma(a/2 + s)*gamma(S.Half - 2*s)
|
||||
/ (gamma(S.Half - s - a/2)*gamma(1 - 2*s + a)),
|
||||
s, x, (-re(a)/2, Rational(1, 4)))) == \
|
||||
cos(sqrt(x))*besselj(a, sqrt(x))
|
||||
# TODO this comes out as an amazing mess, but simplifies nicely
|
||||
assert simplify(IMT(gamma(a + s)*gamma(S.Half - s)
|
||||
/ (sqrt(pi)*gamma(1 - s)*gamma(1 + a - s)),
|
||||
s, x, (-re(a), S.Half))) == \
|
||||
besselj(a, sqrt(x))**2
|
||||
assert simplify(IMT(gamma(s)*gamma(S.Half - s)
|
||||
/ (sqrt(pi)*gamma(1 - s - a)*gamma(1 + a - s)),
|
||||
s, x, (0, S.Half))) == \
|
||||
besselj(-a, sqrt(x))*besselj(a, sqrt(x))
|
||||
assert simplify(IMT(4**s*gamma(-2*s + 1)*gamma(a/2 + b/2 + s)
|
||||
/ (gamma(-a/2 + b/2 - s + 1)*gamma(a/2 - b/2 - s + 1)
|
||||
*gamma(a/2 + b/2 - s + 1)),
|
||||
s, x, (-(re(a) + re(b))/2, S.Half))) == \
|
||||
besselj(a, sqrt(x))*besselj(b, sqrt(x))
|
||||
|
||||
# Section 8.4.20
|
||||
# TODO this can be further simplified!
|
||||
assert simplify(IMT(-2**(2*s)*cos(pi*a/2 - pi*b/2 + pi*s)*gamma(-2*s + 1) *
|
||||
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)),
|
||||
s, x,
|
||||
(Max(-re(a)/2 - re(b)/2, -re(a)/2 + re(b)/2), S.Half))) == \
|
||||
besselj(a, sqrt(x))*-(besselj(-b, sqrt(x)) -
|
||||
besselj(b, sqrt(x))*cos(pi*b))/sin(pi*b)
|
||||
# TODO more
|
||||
|
||||
# for coverage
|
||||
|
||||
assert IMT(pi/cos(pi*s), s, x, (0, S.Half)) == sqrt(x)/(x + 1)
|
||||
|
||||
|
||||
def test_fourier_transform():
|
||||
from sympy.core.function import (expand, expand_complex, expand_trig)
|
||||
from sympy.polys.polytools import factor
|
||||
from sympy.simplify.simplify import simplify
|
||||
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', 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)
|
||||
# TODO IFT (comes out as meijer G)
|
||||
|
||||
# TODO besselj(n, x), n an integer > 0 actually can be done...
|
||||
|
||||
# TODO are there other common transforms (no distributions!)?
|
||||
|
||||
|
||||
def test_sine_transform():
|
||||
t = symbols("t")
|
||||
w = symbols("w")
|
||||
a = symbols("a")
|
||||
f = Function("f")
|
||||
|
||||
# Test unevaluated form
|
||||
assert sine_transform(f(t), t, w) == SineTransform(f(t), t, w)
|
||||
assert inverse_sine_transform(
|
||||
f(w), w, t) == InverseSineTransform(f(w), w, t)
|
||||
|
||||
assert sine_transform(1/sqrt(t), t, w) == 1/sqrt(w)
|
||||
assert inverse_sine_transform(1/sqrt(w), w, t) == 1/sqrt(t)
|
||||
|
||||
assert sine_transform((1/sqrt(t))**3, t, w) == 2*sqrt(w)
|
||||
|
||||
assert sine_transform(t**(-a), t, w) == 2**(
|
||||
-a + S.Half)*w**(a - 1)*gamma(-a/2 + 1)/gamma((a + 1)/2)
|
||||
assert inverse_sine_transform(2**(-a + S(
|
||||
1)/2)*w**(a - 1)*gamma(-a/2 + 1)/gamma(a/2 + S.Half), w, t) == t**(-a)
|
||||
|
||||
assert sine_transform(
|
||||
exp(-a*t), t, w) == sqrt(2)*w/(sqrt(pi)*(a**2 + w**2))
|
||||
assert inverse_sine_transform(
|
||||
sqrt(2)*w/(sqrt(pi)*(a**2 + w**2)), w, t) == exp(-a*t)
|
||||
|
||||
assert sine_transform(
|
||||
log(t)/t, t, w) == sqrt(2)*sqrt(pi)*-(log(w**2) + 2*EulerGamma)/4
|
||||
|
||||
assert sine_transform(
|
||||
t*exp(-a*t**2), t, w) == sqrt(2)*w*exp(-w**2/(4*a))/(4*a**Rational(3, 2))
|
||||
assert inverse_sine_transform(
|
||||
sqrt(2)*w*exp(-w**2/(4*a))/(4*a**Rational(3, 2)), w, t) == t*exp(-a*t**2)
|
||||
|
||||
|
||||
def test_cosine_transform():
|
||||
from sympy.functions.special.error_functions import (Ci, Si)
|
||||
|
||||
t = symbols("t")
|
||||
w = symbols("w")
|
||||
a = symbols("a")
|
||||
f = Function("f")
|
||||
|
||||
# Test unevaluated form
|
||||
assert cosine_transform(f(t), t, w) == CosineTransform(f(t), t, w)
|
||||
assert inverse_cosine_transform(
|
||||
f(w), w, t) == InverseCosineTransform(f(w), w, t)
|
||||
|
||||
assert cosine_transform(1/sqrt(t), t, w) == 1/sqrt(w)
|
||||
assert inverse_cosine_transform(1/sqrt(w), w, t) == 1/sqrt(t)
|
||||
|
||||
assert cosine_transform(1/(
|
||||
a**2 + t**2), t, w) == sqrt(2)*sqrt(pi)*exp(-a*w)/(2*a)
|
||||
|
||||
assert cosine_transform(t**(
|
||||
-a), t, w) == 2**(-a + S.Half)*w**(a - 1)*gamma((-a + 1)/2)/gamma(a/2)
|
||||
assert inverse_cosine_transform(2**(-a + S(
|
||||
1)/2)*w**(a - 1)*gamma(-a/2 + S.Half)/gamma(a/2), w, t) == t**(-a)
|
||||
|
||||
assert cosine_transform(
|
||||
exp(-a*t), t, w) == sqrt(2)*a/(sqrt(pi)*(a**2 + w**2))
|
||||
assert inverse_cosine_transform(
|
||||
sqrt(2)*a/(sqrt(pi)*(a**2 + w**2)), w, t) == exp(-a*t)
|
||||
|
||||
assert cosine_transform(exp(-a*sqrt(t))*cos(a*sqrt(
|
||||
t)), t, w) == a*exp(-a**2/(2*w))/(2*w**Rational(3, 2))
|
||||
|
||||
assert cosine_transform(1/(a + t), t, w) == sqrt(2)*(
|
||||
(-2*Si(a*w) + pi)*sin(a*w)/2 - cos(a*w)*Ci(a*w))/sqrt(pi)
|
||||
assert inverse_cosine_transform(sqrt(2)*meijerg(((S.Half, 0), ()), (
|
||||
(S.Half, 0, 0), (S.Half,)), a**2*w**2/4)/(2*pi), w, t) == 1/(a + t)
|
||||
|
||||
assert cosine_transform(1/sqrt(a**2 + t**2), t, w) == sqrt(2)*meijerg(
|
||||
((S.Half,), ()), ((0, 0), (S.Half,)), a**2*w**2/4)/(2*sqrt(pi))
|
||||
assert inverse_cosine_transform(sqrt(2)*meijerg(((S.Half,), ()), ((0, 0), (S.Half,)), a**2*w**2/4)/(2*sqrt(pi)), w, t) == 1/(t*sqrt(a**2/t**2 + 1))
|
||||
|
||||
|
||||
def test_hankel_transform():
|
||||
r = Symbol("r")
|
||||
k = Symbol("k")
|
||||
nu = Symbol("nu")
|
||||
m = Symbol("m")
|
||||
a = symbols("a")
|
||||
|
||||
assert hankel_transform(1/r, r, k, 0) == 1/k
|
||||
assert inverse_hankel_transform(1/k, k, r, 0) == 1/r
|
||||
|
||||
assert hankel_transform(
|
||||
1/r**m, r, k, 0) == 2**(-m + 1)*k**(m - 2)*gamma(-m/2 + 1)/gamma(m/2)
|
||||
assert inverse_hankel_transform(
|
||||
2**(-m + 1)*k**(m - 2)*gamma(-m/2 + 1)/gamma(m/2), k, r, 0) == r**(-m)
|
||||
|
||||
assert hankel_transform(1/r**m, r, k, nu) == (
|
||||
2*2**(-m)*k**(m - 2)*gamma(-m/2 + nu/2 + 1)/gamma(m/2 + nu/2))
|
||||
assert inverse_hankel_transform(2**(-m + 1)*k**(
|
||||
m - 2)*gamma(-m/2 + nu/2 + 1)/gamma(m/2 + nu/2), k, r, nu) == r**(-m)
|
||||
|
||||
assert hankel_transform(r**nu*exp(-a*r), r, k, nu) == \
|
||||
2**(nu + 1)*a*k**(-nu - 3)*(a**2/k**2 + 1)**(-nu - S(
|
||||
3)/2)*gamma(nu + Rational(3, 2))/sqrt(pi)
|
||||
assert inverse_hankel_transform(
|
||||
2**(nu + 1)*a*k**(-nu - 3)*(a**2/k**2 + 1)**(-nu - Rational(3, 2))*gamma(
|
||||
nu + Rational(3, 2))/sqrt(pi), k, r, nu) == r**nu*exp(-a*r)
|
||||
|
||||
|
||||
def test_issue_7181():
|
||||
assert mellin_transform(1/(1 - x), x, s) != None
|
||||
|
||||
|
||||
def test_issue_8882():
|
||||
# This is the original test.
|
||||
# from sympy import diff, Integral, integrate
|
||||
# r = Symbol('r')
|
||||
# psi = 1/r*sin(r)*exp(-(a0*r))
|
||||
# h = -1/2*diff(psi, r, r) - 1/r*psi
|
||||
# f = 4*pi*psi*h*r**2
|
||||
# assert integrate(f, (r, -oo, 3), meijerg=True).has(Integral) == True
|
||||
|
||||
# To save time, only the critical part is included.
|
||||
F = -a**(-s + 1)*(4 + 1/a**2)**(-s/2)*sqrt(1/a**2)*exp(-s*I*pi)* \
|
||||
sin(s*atan(sqrt(1/a**2)/2))*gamma(s)
|
||||
raises(IntegralTransformError, lambda:
|
||||
inverse_mellin_transform(F, s, x, (-1, oo),
|
||||
**{'as_meijerg': True, 'needeval': True}))
|
||||
|
||||
|
||||
def test_issue_12591():
|
||||
x, y = symbols("x y", real=True)
|
||||
assert fourier_transform(exp(x), x, y) == FourierTransform(exp(x), x, y)
|
||||
@@ -0,0 +1,98 @@
|
||||
from sympy.core import Ne, Rational, Symbol
|
||||
from sympy.functions import sin, cos, tan, csc, sec, cot, log, Piecewise
|
||||
from sympy.integrals.trigonometry import trigintegrate
|
||||
|
||||
x = Symbol('x')
|
||||
|
||||
|
||||
def test_trigintegrate_odd():
|
||||
assert trigintegrate(Rational(1), x) == x
|
||||
assert trigintegrate(x, x) is None
|
||||
assert trigintegrate(x**2, x) is None
|
||||
|
||||
assert trigintegrate(sin(x), x) == -cos(x)
|
||||
assert trigintegrate(cos(x), x) == sin(x)
|
||||
|
||||
assert trigintegrate(sin(3*x), x) == -cos(3*x)/3
|
||||
assert trigintegrate(cos(3*x), x) == sin(3*x)/3
|
||||
|
||||
y = Symbol('y')
|
||||
assert trigintegrate(sin(y*x), x) == Piecewise(
|
||||
(-cos(y*x)/y, Ne(y, 0)), (0, True))
|
||||
assert trigintegrate(cos(y*x), x) == Piecewise(
|
||||
(sin(y*x)/y, Ne(y, 0)), (x, True))
|
||||
assert trigintegrate(sin(y*x)**2, x) == Piecewise(
|
||||
((x*y/2 - sin(x*y)*cos(x*y)/2)/y, Ne(y, 0)), (0, True))
|
||||
assert trigintegrate(sin(y*x)*cos(y*x), x) == Piecewise(
|
||||
(sin(x*y)**2/(2*y), Ne(y, 0)), (0, True))
|
||||
assert trigintegrate(cos(y*x)**2, x) == Piecewise(
|
||||
((x*y/2 + sin(x*y)*cos(x*y)/2)/y, Ne(y, 0)), (x, True))
|
||||
|
||||
y = Symbol('y', positive=True)
|
||||
# TODO: remove conds='none' below. For this to work we would have to rule
|
||||
# out (e.g. by trying solve) the condition y = 0, incompatible with
|
||||
# y.is_positive being True.
|
||||
assert trigintegrate(sin(y*x), x, conds='none') == -cos(y*x)/y
|
||||
assert trigintegrate(cos(y*x), x, conds='none') == sin(y*x)/y
|
||||
|
||||
assert trigintegrate(sin(x)*cos(x), x) == sin(x)**2/2
|
||||
assert trigintegrate(sin(x)*cos(x)**2, x) == -cos(x)**3/3
|
||||
assert trigintegrate(sin(x)**2*cos(x), x) == sin(x)**3/3
|
||||
|
||||
# check if it selects right function to substitute,
|
||||
# so the result is kept simple
|
||||
assert trigintegrate(sin(x)**7 * cos(x), x) == sin(x)**8/8
|
||||
assert trigintegrate(sin(x) * cos(x)**7, x) == -cos(x)**8/8
|
||||
|
||||
assert trigintegrate(sin(x)**7 * cos(x)**3, x) == \
|
||||
-sin(x)**10/10 + sin(x)**8/8
|
||||
assert trigintegrate(sin(x)**3 * cos(x)**7, x) == \
|
||||
cos(x)**10/10 - cos(x)**8/8
|
||||
|
||||
# both n, m are odd and -ve, and not necessarily equal
|
||||
assert trigintegrate(sin(x)**-1*cos(x)**-1, x) == \
|
||||
-log(sin(x)**2 - 1)/2 + log(sin(x))
|
||||
|
||||
|
||||
def test_trigintegrate_even():
|
||||
assert trigintegrate(sin(x)**2, x) == x/2 - cos(x)*sin(x)/2
|
||||
assert trigintegrate(cos(x)**2, x) == x/2 + cos(x)*sin(x)/2
|
||||
|
||||
assert trigintegrate(sin(3*x)**2, x) == x/2 - cos(3*x)*sin(3*x)/6
|
||||
assert trigintegrate(cos(3*x)**2, x) == x/2 + cos(3*x)*sin(3*x)/6
|
||||
assert trigintegrate(sin(x)**2 * cos(x)**2, x) == \
|
||||
x/8 - sin(2*x)*cos(2*x)/16
|
||||
|
||||
assert trigintegrate(sin(x)**4 * cos(x)**2, x) == \
|
||||
x/16 - sin(x) *cos(x)/16 - sin(x)**3*cos(x)/24 + \
|
||||
sin(x)**5*cos(x)/6
|
||||
|
||||
assert trigintegrate(sin(x)**2 * cos(x)**4, x) == \
|
||||
x/16 + cos(x) *sin(x)/16 + cos(x)**3*sin(x)/24 - \
|
||||
cos(x)**5*sin(x)/6
|
||||
|
||||
assert trigintegrate(sin(x)**(-4), x) == -2*cos(x)/(3*sin(x)) \
|
||||
- cos(x)/(3*sin(x)**3)
|
||||
|
||||
assert trigintegrate(cos(x)**(-6), x) == sin(x)/(5*cos(x)**5) \
|
||||
+ 4*sin(x)/(15*cos(x)**3) + 8*sin(x)/(15*cos(x))
|
||||
|
||||
|
||||
def test_trigintegrate_mixed():
|
||||
assert trigintegrate(sin(x)*sec(x), x) == -log(cos(x))
|
||||
assert trigintegrate(sin(x)*csc(x), x) == x
|
||||
assert trigintegrate(sin(x)*cot(x), x) == sin(x)
|
||||
|
||||
assert trigintegrate(cos(x)*sec(x), x) == x
|
||||
assert trigintegrate(cos(x)*csc(x), x) == log(sin(x))
|
||||
assert trigintegrate(cos(x)*tan(x), x) == -cos(x)
|
||||
assert trigintegrate(cos(x)*cot(x), x) == log(cos(x) - 1)/2 \
|
||||
- log(cos(x) + 1)/2 + cos(x)
|
||||
assert trigintegrate(cot(x)*cos(x)**2, x) == log(sin(x)) - sin(x)**2/2
|
||||
|
||||
|
||||
def test_trigintegrate_symbolic():
|
||||
n = Symbol('n', integer=True)
|
||||
assert trigintegrate(cos(x)**n, x) is None
|
||||
assert trigintegrate(sin(x)**n, x) is None
|
||||
assert trigintegrate(cot(x)**n, x) is None
|
||||
Reference in New Issue
Block a user