Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/calculus/functions.py
4045 views
1
r"""
2
Calculus functions.
3
"""
4
5
from sage.matrix.all import matrix, is_Matrix
6
from sage.structure.element import is_Vector
7
from sage.symbolic.ring import is_SymbolicVariable
8
from functional import diff
9
10
11
def wronskian(*args):
12
"""
13
Returns the Wronskian of the provided functions, differentiating with
14
respect to the given variable. If no variable is provided,
15
diff(f) is called for each function f.
16
17
wronskian(f1,...,fn, x) returns the Wronskian of f1,...,fn, with
18
derivatives taken with respect to x.
19
20
wronskian(f1,...,fn) returns the Wronskian of f1,...,fn where
21
k'th derivatives are computed by doing `.derivative(k)' on each
22
function.
23
24
The Wronskian of a list of functions is a determinant of derivatives.
25
The nth row (starting from 0) is a list of the nth derivatives of the
26
given functions.
27
28
For two functions::
29
30
| f g |
31
W(f, g) = det| | = f*g' - g*f'.
32
| f' g' |
33
34
EXAMPLES::
35
36
sage: wronskian(e^x, x^2)
37
-x^2*e^x + 2*x*e^x
38
39
sage: x,y = var('x, y')
40
sage: wronskian(x*y, log(x), x)
41
-y*log(x) + y
42
43
If your functions are in a list, you can use `*' to turn them into
44
arguments to :func:`wronskian`::
45
46
sage: wronskian(*[x^k for k in range(1, 5)])
47
12*x^4
48
49
If you want to use 'x' as one of the functions in the Wronskian,
50
you can't put it last or it will be interpreted as the variable
51
with respect to which we differentiate. There are several ways to
52
get around this.
53
54
Two-by-two Wronskian of sin(x) and e^x::
55
56
sage: wronskian(sin(x), e^x, x)
57
e^x*sin(x) - e^x*cos(x)
58
59
Or don't put x last::
60
61
sage: wronskian(x, sin(x), e^x)
62
(e^x*sin(x) + e^x*cos(x))*x - 2*e^x*sin(x)
63
64
Example where one of the functions is constant::
65
66
sage: wronskian(1, e^(-x), e^(2*x))
67
-6*e^x
68
69
NOTES:
70
71
- http://en.wikipedia.org/wiki/Wronskian
72
- http://planetmath.org/encyclopedia/WronskianDeterminant.html
73
74
AUTHORS:
75
76
- Dan Drake (2008-03-12)
77
"""
78
if len(args) == 0:
79
raise TypeError, 'wronskian() takes at least one argument (0 given)'
80
elif len(args) == 1:
81
# a 1x1 Wronskian is just its argument
82
return args[0]
83
else:
84
if is_SymbolicVariable(args[-1]):
85
# if last argument is a variable, peel it off and
86
# differentiate the other args
87
v = args[-1]
88
fs = args[0:-1]
89
row = lambda n: map(lambda f: diff(f, v, n), fs)
90
else:
91
# if the last argument isn't a variable, just run
92
# .derivative on everything
93
fs = args
94
row = lambda n: map(lambda f: diff(f, n), fs)
95
# NOTE: I rewrote the below as two lines to avoid a possible subtle
96
# memory management problem on some platforms (only VMware as far
97
# as we know?). See trac #2990.
98
# There may still be a real problem that this is just hiding for now.
99
A = matrix(map(row, range(len(fs))))
100
return A.determinant()
101
#return matrix(map(row, range(len(fs)))).determinant()
102
103
104
def jacobian(functions, variables):
105
"""
106
Return the Jacobian matrix, which is the matrix of partial
107
derivatives in which the i,j entry of the Jacobian matrix is the
108
partial derivative diff(functions[i], variables[j]).
109
110
EXAMPLES::
111
112
sage: x,y = var('x,y')
113
sage: g=x^2-2*x*y
114
sage: jacobian(g, (x,y))
115
[2*x - 2*y -2*x]
116
117
The Jacobian of the Jacobian should give us the "second derivative", which is the Hessian matrix::
118
119
sage: jacobian(jacobian(g, (x,y)), (x,y))
120
[ 2 -2]
121
[-2 0]
122
sage: g.hessian()
123
[ 2 -2]
124
[-2 0]
125
126
sage: f=(x^3*sin(y), cos(x)*sin(y), exp(x))
127
sage: jacobian(f, (x,y))
128
[ 3*x^2*sin(y) x^3*cos(y)]
129
[-sin(x)*sin(y) cos(x)*cos(y)]
130
[ e^x 0]
131
sage: jacobian(f, (y,x))
132
[ x^3*cos(y) 3*x^2*sin(y)]
133
[ cos(x)*cos(y) -sin(x)*sin(y)]
134
[ 0 e^x]
135
136
"""
137
if is_Matrix(functions) and (functions.nrows()==1 or functions.ncols()==1):
138
functions = functions.list()
139
elif not (isinstance(functions, (tuple, list)) or is_Vector(functions)):
140
functions = [functions]
141
142
if not isinstance(variables, (tuple, list)) and not is_Vector(variables):
143
variables = [variables]
144
145
return matrix([[diff(f, v) for v in variables] for f in functions])
146
147