diff --git a/sympy/solvers/solvers.py b/sympy/solvers/solvers.py
index 6ce6f12..0f03a8f 100644
--- a/sympy/solvers/solvers.py
+++ b/sympy/solvers/solvers.py
@@ -587,7 +587,7 @@ def solve_ODE_first_order(eq, f):
def solve_ODE_second_order(eq, f):
"""
solves many kinds of second order odes, different methods are used
- depending on the form of the given equation. Now the constanst
+ depending on the form of the given equation. So far the constants
coefficients case and a special case are implemented.
"""
x = f.args[0]
--
1.6.2
In [1]: A = Symbol("A", commutative=False)
In [2]: A*f(x).diff(x)*A
Out[2]:
d
A⋅──(f(x))⋅A
dx
After:
In [1]: A = Symbol("A", commutative=False)
In [2]: A*f(x).diff(x)*A
Out[2]:
d 2
──(f(x))⋅A
dx
The problem was that Derivative was not set as commutative even if f(x) is
commutative. This was fixed by checking if the argument of the derivative is
commutative and if so, making the whole Derivative commutative too. Then
everything works.
Some tests have to be fixed by making Wild() explicitly not depending on "x".
One doctest had to be robustified.
Signed-off-by: Ondrej Certik <ond...@certik.cz>
---
sympy/core/function.py | 13 ++++++++++---
sympy/core/tests/test_diff.py | 9 ++++++++-
sympy/core/tests/test_match.py | 6 ++++--
sympy/simplify/simplify.py | 5 +++--
sympy/solvers/solvers.py | 1 +
5 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/sympy/core/function.py b/sympy/core/function.py
index d6f3baa..3242a53 100644
--- a/sympy/core/function.py
+++ b/sympy/core/function.py
@@ -474,8 +474,15 @@ def __new__(cls, expr, *symbols, **assumptions):
expr = sympify(expr)
if not symbols: return expr
symbols = Derivative._symbolgen(*symbols)
- if not assumptions.get("evaluate", False) and not isinstance(expr, Derivative):
- obj = Basic.__new__(cls, expr, *symbols)
+ if expr.is_commutative:
+ assumptions["commutative"] = True
+ if assumptions.has_key("evaluate"):
+ evaluate = assumptions["evaluate"]
+ del assumptions["evaluate"]
+ else:
+ evaluate = False
+ if not evaluate and not isinstance(expr, Derivative):
+ obj = Basic.__new__(cls, expr, *symbols, **assumptions)
return obj
unevaluated_symbols = []
for s in symbols:
@@ -494,7 +501,7 @@ def __new__(cls, expr, *symbols, **assumptions):
if not unevaluated_symbols:
return expr
- return Basic.__new__(cls, expr, *unevaluated_symbols)
+ return Basic.__new__(cls, expr, *unevaluated_symbols, **assumptions)
def _eval_derivative(self, s):
#print
diff --git a/sympy/core/tests/test_diff.py b/sympy/core/tests/test_diff.py
index 2cf9502..e2c7d41 100644
--- a/sympy/core/tests/test_diff.py
+++ b/sympy/core/tests/test_diff.py
@@ -1,4 +1,4 @@
-from sympy import Symbol, Rational, cos, sin, tan, cot, exp, log
+from sympy import Symbol, Rational, cos, sin, tan, cot, exp, log, Function
def test_diff():
a = Symbol("a")
@@ -62,3 +62,10 @@ def test_speed():
# this should return in 0.0s. If it takes forever, it's wrong.
x = Symbol("x")
assert x.diff(x, 10**8) == 0
+
+def test_deriv_noncommutative():
+ A = Symbol("A", commutative=False)
+ f = Function("f")
+ x = Symbol("x")
+ assert A*f(x)*A == f(x)*A**2
+ assert A*f(x).diff(x)*A == f(x).diff(x) * A**2
diff --git a/sympy/core/tests/test_match.py b/sympy/core/tests/test_match.py
index 54e6876..e3777d0 100644
--- a/sympy/core/tests/test_match.py
+++ b/sympy/core/tests/test_match.py
@@ -161,12 +161,14 @@ def test_derivative1():
assert (fd+1).match(p+1) == {p: fd}
assert (fd).match(fd) == {}
assert (3*fd).match(p*fd) != None
+ p = Wild("p", exclude=[x])
+ q = Wild("q", exclude=[x])
assert (3*fd-1).match(p*fd + q) == {p: 3, q: -1}
def test_derivative_bug1():
f = Function("f")
x = Symbol("x")
- a = Wild("a", exclude=[f])
+ a = Wild("a", exclude=[f, x])
b = Wild("b", exclude=[f])
pattern = a * Derivative(f(x), x, x) + b
expr = Derivative(f(x), x)+x**2
@@ -177,7 +179,7 @@ def test_derivative_bug1():
def test_derivative2():
f = Function("f")
x = Symbol("x")
- a = Wild("a", exclude=[f])
+ a = Wild("a", exclude=[f, x])
b = Wild("b", exclude=[f])
e = Derivative(f(x), x)
assert e.match(Derivative(f(x), x)) == {}
diff --git a/sympy/simplify/simplify.py b/sympy/simplify/simplify.py
index 1265f1f..2aeb5e4 100644
--- a/sympy/simplify/simplify.py
+++ b/sympy/simplify/simplify.py
@@ -454,8 +454,9 @@ def collect(expr, syms, evaluate=True, exact=False):
Or you can even match both derivative order and exponent at time:
- >>> collect(a*D(D(f,x),x)**2 + b*D(D(f,x),x)**2, D(f,x))
- (a + b)*D(f(x), x, x)**2
+ >>> collect(a*D(D(f,x),x)**2 + b*D(D(f,x),x)**2, D(f,x)) == \
+ (a + b)*D(D(f,x),x)**2
+ True
Notes
diff --git a/sympy/solvers/solvers.py b/sympy/solvers/solvers.py
index 0f03a8f..6377ac8 100644
--- a/sympy/solvers/solvers.py
+++ b/sympy/solvers/solvers.py
@@ -617,6 +617,7 @@ def solve_ODE_second_order(eq, f):
#other cases of the second order odes will be implemented here
#special equations, that we know how to solve
+ a = Wild('a')
t = x*C.exp(f(x))
tt = a*t.diff(x, x)/t
r = eq.match(tt.expand())
--
1.6.2
Thanks for the review, it's in.
Ondrej