Utility functions for making derivative() behave uniformly across Sage.¶
To use these functions:
attach the following method to your class:
def _derivative(self, var=None): [ should differentiate wrt the single variable var and return result; var==None means attempt to differentiate wrt a 'default' variable. ]
from sage.misc.derivative import multi_derivative
add the following method to your class:
def derivative(self, *args): return multi_derivative(self, args)
Then your object will support the standard parameter format for derivative(). For example:
F.derivative():
diff wrt. default variable (calls F._derivative(None))
F.derivative(3):
diff three times wrt default variable (calls F._derivative(None) three times)
F.derivative(x):
diff wrt x (calls F._derivative(x))
F.derivative(1, x, z, 3, y, 2, 2):
diff once wrt default variable, then once wrt x, then three times wrt z,
then twice wrt y, then twice wrt default variable.
F.derivative([None, x, z, z, z, y, y, None, None]):
identical to previous example
For the precise specification see the documentation of
derivative_parse().
AUTHORS:
David Harvey (2008-02)
- sage.misc.derivative.derivative_parse(args)[source]¶
Translates a sequence consisting of ‘variables’ and iteration counts into a single sequence of variables.
INPUT:
args– any iterable, interpreted as a sequence of ‘variables’ and iteration counts. An iteration count is any integer type (python int or Sage Integer). Iteration counts must be nonnegative. Any object which is not an integer is assumed to be a variable.
OUTPUT:
A sequence, the ‘expanded’ version of the input, defined as follows. Read the input from left to right. If you encounter a variable V followed by an iteration count N, then output N copies of V. If V is not followed by an iteration count, output a single copy of V. If you encounter an iteration count N (not attached to a preceding variable), then output N copies of None.
Special case: if input is empty, output [None] (i.e. “differentiate once with respect to the default variable”).
Special case: if the input is a 1-tuple containing a single list, then the return value is simply that list.
EXAMPLES:
sage: x = var("x") # needs sage.symbolic sage: y = var("y") # needs sage.symbolic sage: from sage.misc.derivative import derivative_parse
>>> from sage.all import * >>> x = var("x") # needs sage.symbolic >>> y = var("y") # needs sage.symbolic >>> from sage.misc.derivative import derivative_parse
Differentiate twice with respect to x, then once with respect to y, then once with respect to x:
sage: derivative_parse([x, 2, y, x]) # needs sage.symbolic [x, x, y, x]
[Python]>>> from sage.all import * >>> derivative_parse([x, Integer(2), y, x]) # needs sage.symbolic [x, x, y, x]
Differentiate twice with respect to x, then twice with respect to the ‘default variable’:
sage: derivative_parse([x, 2, 2]) # needs sage.symbolic [x, x, None, None]
>>> from sage.all import * >>> derivative_parse([x, Integer(2), Integer(2)]) # needs sage.symbolic [x, x, None, None]
Special case with empty input list:
sage: derivative_parse([]) [None] sage: derivative_parse([-1]) Traceback (most recent call last): ... ValueError: derivative counts must be nonnegative
[Python]>>> from sage.all import * >>> derivative_parse([]) [None] >>> derivative_parse([-Integer(1)]) Traceback (most recent call last): ... ValueError: derivative counts must be nonnegative
Special case with single list argument provided:
sage: derivative_parse(([x, y], )) # needs sage.symbolic [x, y]
>>> from sage.all import * >>> derivative_parse(([x, y], )) # needs sage.symbolic [x, y]
If only the count is supplied:
sage: derivative_parse([0]) [] sage: derivative_parse([1]) [None] sage: derivative_parse([2]) [None, None] sage: derivative_parse([int(2)]) [None, None]
[Python]>>> from sage.all import * >>> derivative_parse([Integer(0)]) [] >>> derivative_parse([Integer(1)]) [None] >>> derivative_parse([Integer(2)]) [None, None] >>> derivative_parse([int(Integer(2))]) [None, None]
Various other cases:
sage: # needs sage.symbolic sage: derivative_parse([x]) [x] sage: derivative_parse([x, x]) [x, x] sage: derivative_parse([x, 2]) [x, x] sage: derivative_parse([x, 0]) [] sage: derivative_parse([x, y, x, 2, 2, y]) [x, y, x, x, None, None, y]
>>> from sage.all import * >>> # needs sage.symbolic >>> derivative_parse([x]) [x] >>> derivative_parse([x, x]) [x, x] >>> derivative_parse([x, Integer(2)]) [x, x] >>> derivative_parse([x, Integer(0)]) [] >>> derivative_parse([x, y, x, Integer(2), Integer(2), y]) [x, y, x, x, None, None, y]
- sage.misc.derivative.multi_derivative(F, args)[source]¶
Call F._derivative(var) for a sequence of variables specified by args.
INPUT:
F– any object with a_derivative(var)methodargs– any tuple that can be processed byderivative_parse()
EXAMPLES:
sage: from sage.misc.derivative import multi_derivative sage: R.<x, y, z> = PolynomialRing(QQ) sage: f = x^3 * y^4 * z^5 sage: multi_derivative(f, (x,)) # like f.derivative(x) 3*x^2*y^4*z^5 sage: multi_derivative(f, (x, y, x)) # like f.derivative(x, y, x) 24*x*y^3*z^5 sage: multi_derivative(f, ([x, y, x],)) # like f.derivative([x, y, x]) 24*x*y^3*z^5 sage: multi_derivative(f, (x, 2)) # like f.derivative(x, 2) 6*x*y^4*z^5
>>> from sage.all import * >>> from sage.misc.derivative import multi_derivative >>> R = PolynomialRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3) >>> f = x**Integer(3) * y**Integer(4) * z**Integer(5) >>> multi_derivative(f, (x,)) # like f.derivative(x) 3*x^2*y^4*z^5 >>> multi_derivative(f, (x, y, x)) # like f.derivative(x, y, x) 24*x*y^3*z^5 >>> multi_derivative(f, ([x, y, x],)) # like f.derivative([x, y, x]) 24*x*y^3*z^5 >>> multi_derivative(f, (x, Integer(2))) # like f.derivative(x, 2) 6*x*y^4*z^5
sage: R.<x> = PolynomialRing(QQ) sage: f = x^4 + x^2 + 1 sage: multi_derivative(f, []) # like f.derivative() 4*x^3 + 2*x sage: multi_derivative(f, [[]]) # like f.derivative([]) x^4 + x^2 + 1 sage: multi_derivative(f, [x]) # like f.derivative(x) 4*x^3 + 2*x
[Python]>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(4) + x**Integer(2) + Integer(1) >>> multi_derivative(f, []) # like f.derivative() 4*x^3 + 2*x >>> multi_derivative(f, [[]]) # like f.derivative([]) x^4 + x^2 + 1 >>> multi_derivative(f, [x]) # like f.derivative(x) 4*x^3 + 2*x