|
26 | 26 | -a^3 + 3*a^2*x - 3*a*x^2 + x^3
|
27 | 27 | """
|
28 | 28 |
|
| 29 | +from sage.misc.derivative import derivative_parse |
| 30 | +from sage.structure.element import get_coercion_model, parent |
29 | 31 | from .calculus import SR
|
30 | 32 | from sage.symbolic.expression import Expression
|
31 |
| -from sage.misc.derivative import derivative_parse |
32 |
| -from sage.structure.element import get_coercion_model |
33 | 33 |
|
34 | 34 | def simplify(f):
|
35 | 35 | r"""
|
@@ -143,18 +143,53 @@ def derivative(f, *args, **kwds):
|
143 | 143 | sage: derivative(a).display()
|
144 | 144 | da = 2 dx∧dy
|
145 | 145 |
|
| 146 | + The parent of the result might end up being a common parent of the |
| 147 | + function and the arguments:: |
| 148 | +
|
| 149 | + sage: derivative(0, SR.var('t')).parent() |
| 150 | + Symbolic Ring |
| 151 | + sage: R.<x> = ZZ[] |
| 152 | + sage: derivative(0, x).parent() |
| 153 | + Univariate Polynomial Ring in x over Integer Ring |
| 154 | +
|
| 155 | + In the following example, the parent of the result might seem confusing. |
| 156 | + This behaviour of the ``derivaive`` function is a consequence of how |
| 157 | + derivatives are implemented for polynomials:: |
| 158 | +
|
| 159 | + sage: S.<y> = ZZ[] |
| 160 | + sage: derivative(S.zero(), x).parent() |
| 161 | + Univariate Polynomial Ring in y over Integer Ring |
| 162 | + sage: derivative(y, x).parent() |
| 163 | + Traceback (most recent call last): |
| 164 | + ... |
| 165 | + ValueError: cannot differentiate with respect to x |
| 166 | +
|
| 167 | + sage: S.zero().derivative(x).parent() |
| 168 | + Univariate Polynomial Ring in y over Integer Ring |
| 169 | + sage: y.derivative(x).parent() |
| 170 | + Traceback (most recent call last): |
| 171 | + ... |
| 172 | + ValueError: cannot differentiate with respect to x |
146 | 173 | """
|
| 174 | + # 0. plain call to f.derivative |
147 | 175 | try:
|
148 | 176 | return f.derivative(*args, **kwds)
|
149 | 177 | except AttributeError:
|
150 | 178 | pass
|
151 |
| - try: |
152 |
| - elts = [e for e in derivative_parse(args) if e is not None] |
153 |
| - elts.append(f) |
154 |
| - cm = get_coercion_model() |
155 |
| - return cm.common_parent(*elts)(f).derivative(*args, **kwds) |
156 |
| - except (AttributeError, TypeError): |
157 |
| - pass |
| 179 | + |
| 180 | + # 1. conversion to a common parent |
| 181 | + elts = [e for e in derivative_parse(args) if e is not None] |
| 182 | + elts.append(f) |
| 183 | + cm = get_coercion_model() |
| 184 | + P = cm.common_parent(*elts) |
| 185 | + if parent(f) is not P: |
| 186 | + ff = P(f) |
| 187 | + try: |
| 188 | + return ff.derivative(*args, **kwds) |
| 189 | + except AttributeError: |
| 190 | + pass |
| 191 | + |
| 192 | + # 2. convert to symbolic ring |
158 | 193 | if not isinstance(f, Expression):
|
159 | 194 | f = SR(f)
|
160 | 195 | return f.derivative(*args, **kwds)
|
|
0 commit comments