def test_trigsimp2(): x, y = symbols('x,y') assert trigsimp(cos(x)**2 * sin(y)**2 + cos(x)**2 * cos(y)**2 + sin(x)**2, recursive=True) == 1 assert trigsimp(sin(x)**2 * sin(y)**2 + sin(x)**2 * cos(y)**2 + cos(x)**2, recursive=True) == 1 assert trigsimp(Subs(x, x, sin(y)**2 + cos(y)**2)) == Subs(x, x, 1)
def test_complicated_derivative_with_Indexed(): x, y = symbols("x,y", cls=IndexedBase) sigma = symbols("sigma") i, j, k = symbols("i,j,k") m0, m1, m2, m3, m4, m5 = symbols("m0:6") f = Function("f") expr = f((x[i] - y[i])**2 / sigma) _xi_1 = symbols("xi_1", cls=Dummy) assert expr.diff(x[m0]).dummy_eq( (x[i] - y[i])*KroneckerDelta(i, m0)*\ 2*Subs( Derivative(f(_xi_1), _xi_1), (_xi_1,), ((x[i] - y[i])**2/sigma,) )/sigma ) assert expr.diff(x[m0]).diff(x[m1]).dummy_eq( 2*KroneckerDelta(i, m0)*\ KroneckerDelta(i, m1)*Subs( Derivative(f(_xi_1), _xi_1), (_xi_1,), ((x[i] - y[i])**2/sigma,) )/sigma + \ 4*(x[i] - y[i])**2*KroneckerDelta(i, m0)*KroneckerDelta(i, m1)*\ Subs( Derivative(f(_xi_1), _xi_1, _xi_1), (_xi_1,), ((x[i] - y[i])**2/sigma,) )/sigma**2 )
def test_issue_7068(): from sympy.abc import a, b f = Function('f') y1 = Dummy('y') y2 = Dummy('y') func1 = f(a + y1 * b) func2 = f(a + y2 * b) func1_y = func1.diff(y1) func2_y = func2.diff(y2) assert func1_y != func2_y z1 = Subs(f(a), a, y1) z2 = Subs(f(a), a, y2) assert z1 != z2
def test_Subs_subs(): assert Subs(x * y, x, x).subs(x, y) == Subs(x * y, x, y) assert Subs(x*y, x, x + 1).subs(x, y) == \ Subs(x*y, x, y + 1) assert Subs(x*y, y, x + 1).subs(x, y) == \ Subs(y**2, y, y + 1) a = Subs(x * y * z, (y, x, z), (x + 1, x + z, x)) b = Subs(x * y * z, (y, x, z), (x + 1, y + z, y)) assert a.subs(x, y) == b and \ a.doit().subs(x, y) == a.subs(x, y).doit() f = Function('f') g = Function('g') assert Subs(2 * f(x, y) + g(x), f(x, y), 1).subs(y, 2) == Subs(2 * f(x, y) + g(x), (f(x, y), y), (1, 2))
def test_issue_7231(): from sympy.abc import a ans1 = f(x).series(x, a) res = (f(a) + (-a + x)*Subs(Derivative(f(y), y), y, a) + (-a + x)**2*Subs(Derivative(f(y), y, y), y, a)/2 + (-a + x)**3*Subs(Derivative(f(y), y, y, y), y, a)/6 + (-a + x)**4*Subs(Derivative(f(y), y, y, y, y), y, a)/24 + (-a + x)**5*Subs(Derivative(f(y), y, y, y, y, y), y, a)/120 + O((-a + x)**6, (x, a))) assert res == ans1 ans2 = f(x).series(x, a) assert res == ans2
def test_issue_16160(): assert Derivative(x**3, (x, x)).subs(x, 2) == Subs(Derivative(x**3, (x, 2)), x, 2) assert Derivative(1 + x**3, (x, x)).subs(x, 0) == Derivative(1 + y**3, (y, 0)).subs(y, 0)
def test_diff_wrt(): fx = f(x) dfx = diff(f(x), x) ddfx = diff(f(x), x, x) assert diff(sin(fx) + fx**2, fx) == cos(fx) + 2*fx assert diff(sin(dfx) + dfx**2, dfx) == cos(dfx) + 2*dfx assert diff(sin(ddfx) + ddfx**2, ddfx) == cos(ddfx) + 2*ddfx assert diff(fx**2, dfx) == 0 assert diff(fx**2, ddfx) == 0 assert diff(dfx**2, fx) == 0 assert diff(dfx**2, ddfx) == 0 assert diff(ddfx**2, dfx) == 0 assert diff(fx*dfx*ddfx, fx) == dfx*ddfx assert diff(fx*dfx*ddfx, dfx) == fx*ddfx assert diff(fx*dfx*ddfx, ddfx) == fx*dfx assert diff(f(x), x).diff(f(x)) == 0 assert (sin(f(x)) - cos(diff(f(x), x))).diff(f(x)) == cos(f(x)) assert diff(sin(fx), fx, x) == diff(sin(fx), x, fx) # Chain rule cases assert f(g(x)).diff(x) == \ Derivative(g(x), x)*Derivative(f(g(x)), g(x)) assert diff(f(g(x), h(y)), x) == \ Derivative(g(x), x)*Derivative(f(g(x), h(y)), g(x)) assert diff(f(g(x), h(x)), x) == ( Derivative(f(g(x), h(x)), g(x))*Derivative(g(x), x) + Derivative(f(g(x), h(x)), h(x))*Derivative(h(x), x)) assert f( sin(x)).diff(x) == cos(x)*Subs(Derivative(f(x), x), x, sin(x)) assert diff(f(g(x)), g(x)) == Derivative(f(g(x)), g(x))
def test_issue_15084_13166(): eq = f(x, g(x)) assert eq.diff((g(x), y)) == Derivative(f(x, g(x)), (g(x), y)) # issue 13166 assert eq.diff(x, 2).doit() == ( (Derivative(f(x, g(x)), (g(x), 2))*Derivative(g(x), x) + Subs(Derivative(f(x, _xi_2), _xi_2, x), _xi_2, g(x)))*Derivative(g(x), x) + Derivative(f(x, g(x)), g(x))*Derivative(g(x), (x, 2)) + Derivative(g(x), x)*Subs(Derivative(f(_xi_1, g(x)), _xi_1, g(x)), _xi_1, x) + Subs(Derivative(f(_xi_1, g(x)), (_xi_1, 2)), _xi_1, x)) # issue 6681 assert diff(f(x, t, g(x, t)), x).doit() == ( Derivative(f(x, t, g(x, t)), g(x, t))*Derivative(g(x, t), x) + Subs(Derivative(f(_xi_1, t, g(x, t)), _xi_1), _xi_1, x)) # make sure the order doesn't matter when using diff assert eq.diff(x, g(x)) == eq.diff(g(x), x)
def test_simultaneous_subs(): reps = {x: 0, y: 0} assert (x / y).subs(reps) != (y / x).subs(reps) assert (x/y).subs(reps, simultaneous=True) == \ (y/x).subs(reps, simultaneous=True) reps = reps.items() assert (x / y).subs(reps) != (y / x).subs(reps) assert (x/y).subs(reps, simultaneous=True) == \ (y/x).subs(reps, simultaneous=True) assert Derivative(x, y, z).subs(reps, simultaneous=True) == \ Subs(Derivative(0, y, z), y, 0)
def _get_general_solution(self, *, simplify: bool = True): m, n = self.wilds_match() fx = self.ode_problem.func x = self.ode_problem.sym (C1,) = self.ode_problem.get_numbered_constants(num=1) y = Dummy('y') m = m.subs(fx, y) n = n.subs(fx, y) gen_sol = Eq(Subs(Integral(m, x) + Integral(n - Integral(m, x).diff(y), y), y, fx), C1) return gen_sol
def test_derivative_subs(): f = Function('f') g = Function('g') assert Derivative(f(x), x).subs(f(x), y) != 0 # need xreplace to put the function back, see #13803 assert Derivative(f(x), x).subs(f(x), y).xreplace({y: f(x)}) == \ Derivative(f(x), x) # issues 5085, 5037 assert cse(Derivative(f(x), x) + f(x))[1][0].has(Derivative) assert cse(Derivative(f(x, y), x) + Derivative(f(x, y), y))[1][0].has(Derivative) eq = Derivative(g(x), g(x)) assert eq.subs(g, f) == Derivative(f(x), f(x)) assert eq.subs(g(x), f(x)) == Derivative(f(x), f(x)) assert eq.subs(g, cos) == Subs(Derivative(y, y), y, cos(x))
def test_dont_cse_tuples(): from sympy.core.function import Subs f = Function("f") g = Function("g") name_val, (expr, ) = cse( Subs(f(x, y), (x, y), (0, 1)) + Subs(g(x, y), (x, y), (0, 1))) assert name_val == [] assert expr == (Subs(f(x, y), (x, y), (0, 1)) + Subs(g(x, y), (x, y), (0, 1))) name_val, (expr, ) = cse( Subs(f(x, y), (x, y), (0, x + y)) + Subs(g(x, y), (x, y), (0, x + y))) assert name_val == [(x0, x + y)] assert expr == Subs(f(x, y), (x, y), (0, x0)) + \ Subs(g(x, y), (x, y), (0, x0))
def test_issue_3978(): f = Function('f') assert f(x).series(x, 0, 3, dir='-') == \ f(0) + x*Subs(Derivative(f(x), x), x, 0) + \ x**2*Subs(Derivative(f(x), x, x), x, 0)/2 + O(x**3) assert f(x).series(x, 0, 3) == \ f(0) + x*Subs(Derivative(f(x), x), x, 0) + \ x**2*Subs(Derivative(f(x), x, x), x, 0)/2 + O(x**3) assert f(x**2).series(x, 0, 3) == \ f(0) + x**2*Subs(Derivative(f(x), x), x, 0) + O(x**3) assert f(x**2+1).series(x, 0, 3) == \ f(1) + x**2*Subs(Derivative(f(x), x), x, 1) + O(x**3) class TestF(Function): pass assert TestF(x).series(x, 0, 3) == TestF(0) + \ x*Subs(Derivative(TestF(x), x), x, 0) + \ x**2*Subs(Derivative(TestF(x), x, x), x, 0)/2 + O(x**3)
def test_issue_12005(): e1 = Subs(Derivative(f(x), x), x, x) assert e1.diff(x) == Derivative(f(x), x, x) e2 = Subs(Derivative(f(x), x), x, x**2 + 1) assert e2.diff(x) == 2*x*Subs(Derivative(f(x), x, x), x, x**2 + 1) e3 = Subs(Derivative(f(x) + y**2 - y, y), y, y**2) assert e3.diff(y) == 4*y e4 = Subs(Derivative(f(x + y), y), y, (x**2)) assert e4.diff(y) is S.Zero e5 = Subs(Derivative(f(x), x), (y, z), (y, z)) assert e5.diff(x) == Derivative(f(x), x, x) assert f(g(x)).diff(g(x), g(x)) == Derivative(f(g(x)), g(x), g(x))
def test_deriv1(): # These all require derivatives evaluated at a point (issue 4719) to work. # See issue 4624 assert f(2*x).diff(x) == 2*Subs(Derivative(f(x), x), x, 2*x) assert (f(x)**3).diff(x) == 3*f(x)**2*f(x).diff(x) assert (f(2*x)**3).diff(x) == 6*f(2*x)**2*Subs( Derivative(f(x), x), x, 2*x) assert f(2 + x).diff(x) == Subs(Derivative(f(x), x), x, x + 2) assert f(2 + 3*x).diff(x) == 3*Subs( Derivative(f(x), x), x, 3*x + 2) assert f(3*sin(x)).diff(x) == 3*cos(x)*Subs( Derivative(f(x), x), x, 3*sin(x)) # See issue 8510 assert f(x, x + z).diff(x) == ( Subs(Derivative(f(y, x + z), y), y, x) + Subs(Derivative(f(x, y), y), y, x + z)) assert f(x, x**2).diff(x) == ( 2*x*Subs(Derivative(f(x, y), y), y, x**2) + Subs(Derivative(f(y, x**2), y), y, x)) # but Subs is not always necessary assert f(x, g(y)).diff(g(y)) == Derivative(f(x, g(y)), g(y))
def test_dsolve_all_hint(): eq = f(x).diff(x) output = dsolve(eq, hint='all') # Match the Dummy variables: sol1 = output['separable_Integral'] _y = sol1.lhs.args[1][0] sol1 = output['1st_homogeneous_coeff_subs_dep_div_indep_Integral'] _u1 = sol1.rhs.args[1].args[1][0] expected = {'Bernoulli_Integral': Eq(f(x), C1 + Integral(0, x)), '1st_homogeneous_coeff_best': Eq(f(x), C1), 'Bernoulli': Eq(f(x), C1), 'nth_algebraic': Eq(f(x), C1), 'nth_linear_euler_eq_homogeneous': Eq(f(x), C1), 'nth_linear_constant_coeff_homogeneous': Eq(f(x), C1), 'separable': Eq(f(x), C1), '1st_homogeneous_coeff_subs_indep_div_dep': Eq(f(x), C1), 'nth_algebraic_Integral': Eq(f(x), C1), '1st_linear': Eq(f(x), C1), '1st_linear_Integral': Eq(f(x), C1 + Integral(0, x)), '1st_exact': Eq(f(x), C1), '1st_exact_Integral': Eq(Subs(Integral(0, x) + Integral(1, _y), _y, f(x)), C1), 'lie_group': Eq(f(x), C1), '1st_homogeneous_coeff_subs_dep_div_indep': Eq(f(x), C1), '1st_homogeneous_coeff_subs_dep_div_indep_Integral': Eq(log(x), C1 + Integral(-1/_u1, (_u1, f(x)/x))), '1st_power_series': Eq(f(x), C1), 'separable_Integral': Eq(Integral(1, (_y, f(x))), C1 + Integral(0, x)), '1st_homogeneous_coeff_subs_indep_div_dep_Integral': Eq(f(x), C1), 'best': Eq(f(x), C1), 'best_hint': 'nth_algebraic', 'default': 'nth_algebraic', 'order': 1} assert output == expected assert dsolve(eq, hint='best') == Eq(f(x), C1)
def test_Subs2(): # this reflects a limitation of subs(), probably won't fix assert Subs(f(x), x**2, x).doit() == f(sqrt(x))
def test_issue_15226(): assert Subs(Derivative(f(y), x, y), y, g(x)).doit() != 0
def test_Subs_with_Indexed(): A = IndexedBase("A") i, j, k = symbols("i,j,k") x, y, z = symbols("x,y,z") f = Function("f") assert Subs(A[i], A[i], A[j]).diff(A[j]) == 1 assert Subs(A[i], A[i], x).diff(A[i]) == 0 assert Subs(A[i], A[i], x).diff(A[j]) == 0 assert Subs(A[i], A[i], x).diff(x) == 1 assert Subs(A[i], A[i], x).diff(y) == 0 assert Subs(A[i], A[i], A[j]).diff(A[k]) == KroneckerDelta(j, k) assert Subs(x, x, A[i]).diff(A[j]) == KroneckerDelta(i, j) assert Subs(f(A[i]), A[i], x).diff(A[j]) == 0 assert Subs(f(A[i]), A[i], A[k]).diff( A[j]) == Derivative(f(A[k]), A[k]) * KroneckerDelta(j, k) assert Subs(x, x, A[i]**2).diff(A[j]) == 2 * KroneckerDelta(i, j) * A[i] assert Subs(A[i], A[i], A[j]**2).diff(A[k]) == 2 * KroneckerDelta(j, k) * A[j] assert Subs(A[i] * x, x, A[i]).diff(A[i]) == 2 * A[i] assert Subs(A[i] * x, x, A[i]).diff(A[j]) == 2 * A[i] * KroneckerDelta(i, j) assert Subs(A[i] * x, x, A[j]).diff(A[i]) == A[j] + A[i] * KroneckerDelta(i, j) assert Subs(A[i] * x, x, A[j]).diff(A[j]) == A[i] + A[j] * KroneckerDelta(i, j) assert Subs(A[i] * x, x, A[i]).diff(A[k]) == 2 * A[i] * KroneckerDelta(i, k) assert Subs(A[i] * x, x, A[j]).diff( A[k]) == KroneckerDelta(i, k) * A[j] + KroneckerDelta(j, k) * A[i] assert Subs(A[i] * x, A[i], x).diff(A[i]) == 0 assert Subs(A[i] * x, A[i], x).diff(A[j]) == 0 assert Subs(A[i] * x, A[j], x).diff(A[i]) == x assert Subs(A[i] * x, A[j], x).diff(A[j]) == x * KroneckerDelta(i, j) assert Subs(A[i] * x, A[i], x).diff(A[k]) == 0 assert Subs(A[i] * x, A[j], x).diff(A[k]) == x * KroneckerDelta(i, k)
def pde_1st_linear_constant_coeff(eq, func, order, match, solvefun): r""" Solves a first order linear partial differential equation with constant coefficients. The general form of this partial differential equation is .. math:: a \frac{\partial f(x,y)}{\partial x} + b \frac{\partial f(x,y)}{\partial y} + c f(x,y) = G(x,y) where `a`, `b` and `c` are constants and `G(x, y)` can be an arbitrary function in `x` and `y`. The general solution of the PDE is: .. math:: f(x, y) = \left. \left[F(\eta) + \frac{1}{a^2 + b^2} \int\limits^{a x + b y} G\left(\frac{a \xi + b \eta}{a^2 + b^2}, \frac{- a \eta + b \xi}{a^2 + b^2} \right) e^{\frac{c \xi}{a^2 + b^2}}\, d\xi\right] e^{- \frac{c \xi}{a^2 + b^2}} \right|_{\substack{\eta=- a y + b x\\ \xi=a x + b y }}\, , where `F(\eta)` is an arbitrary single-valued function. The solution can be found in SymPy with ``pdsolve``:: >>> from sympy.solvers import pdsolve >>> from sympy.abc import x, y, a, b, c >>> from sympy import Function, pprint >>> f = Function('f') >>> G = Function('G') >>> u = f(x,y) >>> ux = u.diff(x) >>> uy = u.diff(y) >>> genform = a*ux + b*uy + c*u - G(x,y) >>> pprint(genform) d d a*--(f(x, y)) + b*--(f(x, y)) + c*f(x, y) - G(x, y) dx dy >>> pprint(pdsolve(genform, hint='1st_linear_constant_coeff_Integral')) // a*x + b*y \ || / | || | | || | c*xi | || | ------- | || | 2 2 | || | /a*xi + b*eta -a*eta + b*xi\ a + b | || | G|------------, -------------|*e d(xi)| || | | 2 2 2 2 | | || | \ a + b a + b / | || | | || / | || | f(x, y) = ||F(eta) + -------------------------------------------------------|* || 2 2 | \\ a + b / <BLANKLINE> \| || || || || || || || || -c*xi || -------|| 2 2|| a + b || e || || /|eta=-a*y + b*x, xi=a*x + b*y Examples ======== >>> from sympy.solvers.pde import pdsolve >>> from sympy import Function, diff, pprint, exp >>> from sympy.abc import x,y >>> f = Function('f') >>> eq = -2*f(x,y).diff(x) + 4*f(x,y).diff(y) + 5*f(x,y) - exp(x + 3*y) >>> pdsolve(eq) Eq(f(x, y), (F(4*x + 2*y) + exp(x/2 + 4*y)/15)*exp(x/2 - y)) References ========== - Viktor Grigoryan, "Partial Differential Equations" Math 124A - Fall 2010, pp.7 """ # TODO : For now homogeneous first order linear PDE's having # two variables are implemented. Once there is support for # solving systems of ODE's, this can be extended to n variables. xi, eta = symbols("xi eta") f = func.func x = func.args[0] y = func.args[1] b = match[match['b']] c = match[match['c']] d = match[match['d']] e = -match[match['e']] expterm = exp(-S(d) / (b**2 + c**2) * xi) functerm = solvefun(eta) solvedict = solve((b * x + c * y - xi, c * x - b * y - eta), x, y) # Integral should remain as it is in terms of xi, # doit() should be done in _handle_Integral. genterm = (1 / S(b**2 + c**2)) * Integral( (1 / expterm * e).subs(solvedict), (xi, b * x + c * y)) return Eq( f(x, y), Subs(expterm * (functerm + genterm), (eta, xi), (c * x - b * y, b * x + c * y)))
def test_Subs_printing(): assert str(Subs(x, (x,), (1,))) == 'Subs(x, x, 1)' assert str(Subs(x + y, (x, y), (1, 2))) == 'Subs(x + y, (x, y), (1, 2))'
def test_series_of_Subs(): from sympy.abc import z subs1 = Subs(sin(x), x, y) subs2 = Subs(sin(x) * cos(z), x, y) subs3 = Subs(sin(x * z), (x, z), (y, x)) assert subs1.series(x) == subs1 subs1_series = (Subs(x, x, y) + Subs(-x**3/6, x, y) + Subs(x**5/120, x, y) + O(y**6)) assert subs1.series() == subs1_series assert subs1.series(y) == subs1_series assert subs1.series(z) == subs1 assert subs2.series(z) == (Subs(z**4*sin(x)/24, x, y) + Subs(-z**2*sin(x)/2, x, y) + Subs(sin(x), x, y) + O(z**6)) assert subs3.series(x).doit() == subs3.doit().series(x) assert subs3.series(z).doit() == sin(x*y) raises(ValueError, lambda: Subs(x + 2*y, y, z).series()) assert Subs(x + y, y, z).series(x).doit() == x + z
def test_subs_in_derivative(): expr = sin(x*exp(y)) u = Function('u') v = Function('v') assert Derivative(expr, y).subs(expr, y) == Derivative(y, y) assert Derivative(expr, y).subs(y, x).doit() == \ Derivative(expr, y).doit().subs(y, x) assert Derivative(f(x, y), y).subs(y, x) == Subs(Derivative(f(x, y), y), y, x) assert Derivative(f(x, y), y).subs(x, y) == Subs(Derivative(f(x, y), y), x, y) assert Derivative(f(x, y), y).subs(y, g(x, y)) == Subs(Derivative(f(x, y), y), y, g(x, y)).doit() assert Derivative(f(x, y), y).subs(x, g(x, y)) == Subs(Derivative(f(x, y), y), x, g(x, y)) assert Derivative(f(x, y), g(y)).subs(x, g(x, y)) == Derivative(f(g(x, y), y), g(y)) assert Derivative(f(u(x), h(y)), h(y)).subs(h(y), g(x, y)) == \ Subs(Derivative(f(u(x), h(y)), h(y)), h(y), g(x, y)).doit() assert Derivative(f(x, y), y).subs(y, z) == Derivative(f(x, z), z) assert Derivative(f(x, y), y).subs(y, g(y)) == Derivative(f(x, g(y)), g(y)) assert Derivative(f(g(x), h(y)), h(y)).subs(h(y), u(y)) == \ Derivative(f(g(x), u(y)), u(y)) assert Derivative(f(x, f(x, x)), f(x, x)).subs( f, Lambda((x, y), x + y)) == Subs( Derivative(z + x, z), z, 2*x) assert Subs(Derivative(f(f(x)), x), f, cos).doit() == sin(x)*sin(cos(x)) assert Subs(Derivative(f(f(x)), f(x)), f, cos).doit() == -sin(cos(x)) # Issue 13791. No comparison (it's a long formula) but this used to raise an exception. assert isinstance(v(x, y, u(x, y)).diff(y).diff(x).diff(y), Expr) # This is also related to issues 13791 and 13795; issue 15190 F = Lambda((x, y), exp(2*x + 3*y)) abstract = f(x, f(x, x)).diff(x, 2) concrete = F(x, F(x, x)).diff(x, 2) assert (abstract.subs(f, F).doit() - concrete).simplify() == 0 # don't introduce a new symbol if not necessary assert x in f(x).diff(x).subs(x, 0).atoms() # case (4) assert Derivative(f(x,f(x,y)), x, y).subs(x, g(y) ) == Subs(Derivative(f(x, f(x, y)), x, y), x, g(y)) assert Derivative(f(x, x), x).subs(x, 0 ) == Subs(Derivative(f(x, x), x), x, 0) # issue 15194 assert Derivative(f(y, g(x)), (x, z)).subs(z, x ) == Derivative(f(y, g(x)), (x, x)) df = f(x).diff(x) assert df.subs(df, 1) is S.One assert df.diff(df) is S.One dxy = Derivative(f(x, y), x, y) dyx = Derivative(f(x, y), y, x) assert dxy.subs(Derivative(f(x, y), y, x), 1) is S.One assert dxy.diff(dyx) is S.One assert Derivative(f(x, y), x, 2, y, 3).subs( dyx, g(x, y)) == Derivative(g(x, y), x, 1, y, 2) assert Derivative(f(x, x - y), y).subs(x, x + y) == Subs( Derivative(f(x, x - y), y), x, x + y)
def test_Subs(): assert Subs(1, (), ()) is S.One # check null subs influence on hashing assert Subs(x, y, z) != Subs(x, y, 1) # neutral subs works assert Subs(x, x, 1).subs(x, y).has(y) # self mapping var/point assert Subs(Derivative(f(x), (x, 2)), x, x).doit() == f(x).diff(x, x) assert Subs(x, x, 0).has(x) # it's a structural answer assert not Subs(x, x, 0).free_symbols assert Subs(Subs(x + y, x, 2), y, 1) == Subs(x + y, (x, y), (2, 1)) assert Subs(x, (x,), (0,)) == Subs(x, x, 0) assert Subs(x, x, 0) == Subs(y, y, 0) assert Subs(x, x, 0).subs(x, 1) == Subs(x, x, 0) assert Subs(y, x, 0).subs(y, 1) == Subs(1, x, 0) assert Subs(f(x), x, 0).doit() == f(0) assert Subs(f(x**2), x**2, 0).doit() == f(0) assert Subs(f(x, y, z), (x, y, z), (0, 1, 1)) != \ Subs(f(x, y, z), (x, y, z), (0, 0, 1)) assert Subs(x, y, 2).subs(x, y).doit() == 2 assert Subs(f(x, y), (x, y, z), (0, 1, 1)) != \ Subs(f(x, y) + z, (x, y, z), (0, 1, 0)) assert Subs(f(x, y), (x, y), (0, 1)).doit() == f(0, 1) assert Subs(Subs(f(x, y), x, 0), y, 1).doit() == f(0, 1) raises(ValueError, lambda: Subs(f(x, y), (x, y), (0, 0, 1))) raises(ValueError, lambda: Subs(f(x, y), (x, x, y), (0, 0, 1))) assert len(Subs(f(x, y), (x, y), (0, 1)).variables) == 2 assert Subs(f(x, y), (x, y), (0, 1)).point == Tuple(0, 1) assert Subs(f(x), x, 0) == Subs(f(y), y, 0) assert Subs(f(x, y), (x, y), (0, 1)) == Subs(f(x, y), (y, x), (1, 0)) assert Subs(f(x)*y, (x, y), (0, 1)) == Subs(f(y)*x, (y, x), (0, 1)) assert Subs(f(x)*y, (x, y), (1, 1)) == Subs(f(y)*x, (x, y), (1, 1)) assert Subs(f(x), x, 0).subs(x, 1).doit() == f(0) assert Subs(f(x), x, y).subs(y, 0) == Subs(f(x), x, 0) assert Subs(y*f(x), x, y).subs(y, 2) == Subs(2*f(x), x, 2) assert (2 * Subs(f(x), x, 0)).subs(Subs(f(x), x, 0), y) == 2*y assert Subs(f(x), x, 0).free_symbols == set() assert Subs(f(x, y), x, z).free_symbols == {y, z} assert Subs(f(x).diff(x), x, 0).doit(), Subs(f(x).diff(x), x, 0) assert Subs(1 + f(x).diff(x), x, 0).doit(), 1 + Subs(f(x).diff(x), x, 0) assert Subs(y*f(x, y).diff(x), (x, y), (0, 2)).doit() == \ 2*Subs(Derivative(f(x, 2), x), x, 0) assert Subs(y**2*f(x), x, 0).diff(y) == 2*y*f(0) e = Subs(y**2*f(x), x, y) assert e.diff(y) == e.doit().diff(y) == y**2*Derivative(f(y), y) + 2*y*f(y) assert Subs(f(x), x, 0) + Subs(f(x), x, 0) == 2*Subs(f(x), x, 0) e1 = Subs(z*f(x), x, 1) e2 = Subs(z*f(y), y, 1) assert e1 + e2 == 2*e1 assert e1.__hash__() == e2.__hash__() assert Subs(z*f(x + 1), x, 1) not in [ e1, e2 ] assert Derivative(f(x), x).subs(x, g(x)) == Derivative(f(g(x)), g(x)) assert Derivative(f(x), x).subs(x, x + y) == Subs(Derivative(f(x), x), x, x + y) assert Subs(f(x)*cos(y) + z, (x, y), (0, pi/3)).n(2) == \ Subs(f(x)*cos(y) + z, (x, y), (0, pi/3)).evalf(2) == \ z + Rational('1/2').n(2)*f(0) assert f(x).diff(x).subs(x, 0).subs(x, y) == f(x).diff(x).subs(x, 0) assert (x*f(x).diff(x).subs(x, 0)).subs(x, y) == y*f(x).diff(x).subs(x, 0) assert Subs(Derivative(g(x)**2, g(x), x), g(x), exp(x) ).doit() == 2*exp(x) assert Subs(Derivative(g(x)**2, g(x), x), g(x), exp(x) ).doit(deep=False) == 2*Derivative(exp(x), x) assert Derivative(f(x, g(x)), x).doit() == Derivative( f(x, g(x)), g(x))*Derivative(g(x), x) + Subs(Derivative( f(y, g(x)), y), y, x)
def test_sympy__core__function__Subs(): from sympy.core.function import Subs assert _test_args(Subs(x + y, x, 2))
def pde_1st_linear_constant_coeff(eq, func, order, match, solvefun): r""" Solves a first order linear partial differential equation with constant coefficients. The general form of this partial differential equation is .. math:: a \frac{df(x,y)}{dx} + b \frac{df(x,y)}{dy} + c f(x,y) = G(x,y) where `a`, `b` and `c` are constants and `G(x, y)` can be an arbitrary function in `x` and `y`. The general solution of the PDE is:: >>> from sympy.solvers import pdsolve >>> from sympy.abc import x, y, a, b, c >>> from sympy import Function, pprint >>> f = Function('f') >>> G = Function('G') >>> u = f(x,y) >>> ux = u.diff(x) >>> uy = u.diff(y) >>> genform = a*u + b*ux + c*uy - G(x,y) >>> pprint(genform) d d a*f(x, y) + b*--(f(x, y)) + c*--(f(x, y)) - G(x, y) dx dy >>> pprint(pdsolve(genform, hint='1st_linear_constant_coeff_Integral')) // b*x + c*y \ || / | || | | || | a*xi | || | ------- | || | 2 2 | || | /b*xi + c*eta -b*eta + c*xi\ b + c | || | G|------------, -------------|*e d(xi)| || | | 2 2 2 2 | | || | \ b + c b + c / | || | | || / | || | f(x, y) = ||F(eta) + -------------------------------------------------------|* || 2 2 | \\ b + c / <BLANKLINE> \| || || || || || || || || -a*xi || -------|| 2 2|| b + c || e || || /|eta=-b*y + c*x, xi=b*x + c*y Examples ======== >>> from sympy.solvers.pde import pdsolve >>> from sympy import Function, diff, pprint, exp >>> from sympy.abc import x,y >>> f = Function('f') >>> eq = -2*f(x,y).diff(x) + 4*f(x,y).diff(y) + 5*f(x,y) - exp(x + 3*y) >>> pdsolve(eq) f(x, y) == (F(4*x + 2*y) + exp(x/2 + 4*y)/15)*exp(x/2 - y) References ========== - Viktor Grigoryan, "Partial Differential Equations" Math 124A - Fall 2010, pp.7 """ # TODO : For now homogeneous first order linear PDE's having # two variables are implemented. Once there is support for # solving systems of ODE's, this can be extended to n variables. xi, eta = symbols("xi eta") f = func.func x = func.args[0] y = func.args[1] b = match[match['b']] c = match[match['c']] d = match[match['d']] e = -match[match['e']] expterm = exp(-S(d)/(b**2 + c**2)*xi) functerm = solvefun(eta) solvedict = solve((b*x + c*y - xi, c*x - b*y - eta), x, y) # Integral should remain as it is in terms of xi, # doit() should be done in _handle_Integral. genterm = (1/S(b**2 + c**2))*C.Integral( (1/expterm*e).subs(solvedict), (xi, b*x + c*y)) return Eq(f(x,y), Subs(expterm*(functerm + genterm), (eta, xi), (c*x - b*y, b*x + c*y)))
def test_solve_ics(): # Basic tests that things work from dsolve. assert dsolve(f(x).diff(x) - 1/f(x), f(x), ics={f(1): 2}) == \ Eq(f(x), sqrt(2 * x + 2)) assert dsolve(f(x).diff(x) - f(x), f(x), ics={f(0): 1}) == Eq(f(x), exp(x)) assert dsolve(f(x).diff(x) - f(x), f(x), ics={f(x).diff(x).subs(x, 0): 1}) == Eq(f(x), exp(x)) assert dsolve(f(x).diff(x, x) + f(x), f(x), ics={f(0): 1, f(x).diff(x).subs(x, 0): 1}) == Eq(f(x), sin(x) + cos(x)) assert dsolve([f(x).diff(x) - f(x) + g(x), g(x).diff(x) - g(x) - f(x)], [f(x), g(x)], ics={f(0): 1, g(0): 0}) == [Eq(f(x), exp(x)*cos(x)), Eq(g(x), exp(x)*sin(x))] # Test cases where dsolve returns two solutions. eq = (x**2*f(x)**2 - x).diff(x) assert dsolve(eq, f(x), ics={f(1): 0}) == [Eq(f(x), -sqrt(x - 1)/x), Eq(f(x), sqrt(x - 1)/x)] assert dsolve(eq, f(x), ics={f(x).diff(x).subs(x, 1): 0}) == [Eq(f(x), -sqrt(x - S.Half)/x), Eq(f(x), sqrt(x - S.Half)/x)] eq = cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x) assert dsolve(eq, f(x), ics={f(0):1}, hint='1st_exact', simplify=False) == Eq(x*cos(f(x)) + f(x)**3/3, Rational(1, 3)) assert dsolve(eq, f(x), ics={f(0):1}, hint='1st_exact', simplify=True) == Eq(x*cos(f(x)) + f(x)**3/3, Rational(1, 3)) assert solve_ics([Eq(f(x), C1*exp(x))], [f(x)], [C1], {f(0): 1}) == {C1: 1} assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2], {f(0): 1, f(pi/2): 1}) == {C1: 1, C2: 1} assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2], {f(0): 1, f(x).diff(x).subs(x, 0): 1}) == {C1: 1, C2: 1} assert solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2], {f(0): 1}) == \ {C2: 1} # Some more complicated tests Refer to PR #16098 assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0, f(x).diff(x).subs(x, 1):0})) == \ {Eq(f(x), 0), Eq(f(x), x ** 3 / 6 - x / 2)} assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0})) == \ {Eq(f(x), 0), Eq(f(x), C2*x + x**3/6)} K, r, f0 = symbols('K r f0') sol = Eq(f(x), K*f0*exp(r*x)/((-K + f0)*(f0*exp(r*x)/(-K + f0) - 1))) assert (dsolve(Eq(f(x).diff(x), r * f(x) * (1 - f(x) / K)), f(x), ics={f(0): f0})) == sol #Order dependent issues Refer to PR #16098 assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(x).diff(x).subs(x,0):0, f(0):0})) == \ {Eq(f(x), 0), Eq(f(x), x ** 3 / 6)} assert set(dsolve(f(x).diff(x)*(f(x).diff(x, 2)-x), ics={f(0):0, f(x).diff(x).subs(x,0):0})) == \ {Eq(f(x), 0), Eq(f(x), x ** 3 / 6)} # XXX: Ought to be ValueError raises(ValueError, lambda: solve_ics([Eq(f(x), C1*sin(x) + C2*cos(x))], [f(x)], [C1, C2], {f(0): 1, f(pi): 1})) # Degenerate case. f'(0) is identically 0. raises(ValueError, lambda: solve_ics([Eq(f(x), sqrt(C1 - x**2))], [f(x)], [C1], {f(x).diff(x).subs(x, 0): 0})) EI, q, L = symbols('EI q L') # eq = Eq(EI*diff(f(x), x, 4), q) sols = [Eq(f(x), C1 + C2*x + C3*x**2 + C4*x**3 + q*x**4/(24*EI))] funcs = [f(x)] constants = [C1, C2, C3, C4] # Test both cases, Derivative (the default from f(x).diff(x).subs(x, L)), # and Subs ics1 = {f(0): 0, f(x).diff(x).subs(x, 0): 0, f(L).diff(L, 2): 0, f(L).diff(L, 3): 0} ics2 = {f(0): 0, f(x).diff(x).subs(x, 0): 0, Subs(f(x).diff(x, 2), x, L): 0, Subs(f(x).diff(x, 3), x, L): 0} solved_constants1 = solve_ics(sols, funcs, constants, ics1) solved_constants2 = solve_ics(sols, funcs, constants, ics2) assert solved_constants1 == solved_constants2 == { C1: 0, C2: 0, C3: L**2*q/(4*EI), C4: -L*q/(6*EI)}