Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
28964: fix sympy conversions of derivative
Browse files Browse the repository at this point in the history
This fixes several problems related to the conversion of
derivatives to and from sympy:

- the derivative arguments were permuted when converting to sympy
- the first argument of the derivative was skipped when converting from sympy
- sympy returns arguments of type sympy.core.containers.Tuple which was not handled
- Sage's derivative does not accept tuples, so the arguments must be flattened
- sympy's derivative count is converted to rationals, so Sage's derivative must accept rational arguments
  • Loading branch information
mwageringel committed Feb 17, 2020
1 parent 1d465c7 commit 42d400b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
22 changes: 21 additions & 1 deletion src/sage/interfaces/sympy.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,30 @@ def _sympysage_derivative(self):
sage: sympy_diff = Derivative(f(x)._sympy_(), x._sympy_())
sage: assert diff(f(x),x)._sympy_() == sympy_diff
sage: assert diff(f(x),x) == sympy_diff._sage_()
TESTS:
Check that :trac:`28964` is fixed::
sage: f = function('f')
sage: _ = var('x,t')
sage: assert diff(f(x, t), t)._sympy_()._sage_() == diff(f(x, t), t)
sage: assert diff(f(x, t), x, 2, t)._sympy_()._sage_() == diff(f(x, t), x, 2, t)
sage: diff(f(x, t), x).integrate(x)
f(x, t)
sage: diff(f(x, t), x).integrate(t, algorithm='maxima')
integrate(diff(f(x, t), x), t)
sage: diff(f(x, t), x).integrate(t, algorithm='sympy')
integrate(diff(f(x, t), x), t)
sage: integrate(f(x, t), x).diff(t)
integrate(diff(f(x, t), t), x)
"""
from sage.calculus.functional import derivative
from sympy.core.containers import Tuple
f = self.args[0]._sage_()
args = [[a._sage_() for a in arg] if isinstance(arg,tuple) else arg._sage_() for arg in self.args[2:]]
args = [a._sage_() for arg in self.args[1:]
for a in (arg if isinstance(arg, (tuple, Tuple)) else [arg])]
return derivative(f, *args)

def _sympysage_order(self):
Expand Down
10 changes: 9 additions & 1 deletion src/sage/misc/derivative.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ AUTHORS:
"""

from sage.rings.integer cimport Integer
from sage.rings.rational cimport Rational


def derivative_parse(args):
Expand Down Expand Up @@ -146,6 +147,13 @@ def derivative_parse(args):
sage: derivative_parse([x, y, x, 2, 2, y])
[x, y, x, x, None, None, y]
TESTS:
Check that rational arguments are handled gracefully (:trac:`28964`)::
sage: f = function('f')
sage: f(x).derivative(x, QQ(1)) # indirect doctest
diff(f(x), x)
"""
if not args:
return [None]
Expand All @@ -157,7 +165,7 @@ def derivative_parse(args):
cdef int count, i

for arg in args:
if isinstance(arg, (int, Integer)):
if isinstance(arg, (int, Integer, Rational)):
# process iteration count
count = int(arg)
if count < 0:
Expand Down
9 changes: 8 additions & 1 deletion src/sage/symbolic/expression_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,13 @@ def derivative(self, ex, operator):
Derivative(f_sage(x, y), (x, 2), y)
sage: df_sympy == f_sympy.diff(x, 2, y, 1)
True
Check that :trac:`28964` is fixed::
sage: f = function('f')
sage: _ = var('x,t')
sage: diff(f(x, t), x)._sympy_(), diff(f(x, t), t)._sympy_()
(Derivative(f(x, t), x), Derivative(f(x, t), t))
"""
import sympy

Expand All @@ -860,7 +867,7 @@ def derivative(self, ex, operator):
# retrieve order
order = operator._parameter_set
# arguments
_args = ex.arguments()
_args = ex.operands()

sympy_arg = []
for i, a in enumerate(_args):
Expand Down

0 comments on commit 42d400b

Please sign in to comment.