Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

r""" 

Calculus functions 

""" 

from __future__ import absolute_import 

from sage.matrix.all import matrix 

from sage.structure.element import is_Matrix 

from sage.structure.element import is_Vector 

from sage.symbolic.ring import is_SymbolicVariable 

from .functional import diff 

 

 

def wronskian(*args): 

""" 

Returns the Wronskian of the provided functions, differentiating with 

respect to the given variable. If no variable is provided, 

diff(f) is called for each function f. 

 

wronskian(f1,...,fn, x) returns the Wronskian of f1,...,fn, with 

derivatives taken with respect to x. 

 

wronskian(f1,...,fn) returns the Wronskian of f1,...,fn where 

k'th derivatives are computed by doing ``.derivative(k)`` on each 

function. 

 

The Wronskian of a list of functions is a determinant of derivatives. 

The nth row (starting from 0) is a list of the nth derivatives of the 

given functions. 

 

For two functions:: 

 

| f g | 

W(f, g) = det| | = f*g' - g*f'. 

| f' g' | 

 

EXAMPLES:: 

 

sage: wronskian(e^x, x^2) 

-x^2*e^x + 2*x*e^x 

 

sage: x,y = var('x, y') 

sage: wronskian(x*y, log(x), x) 

-y*log(x) + y 

 

If your functions are in a list, you can use `*' to turn them into 

arguments to :func:`wronskian`:: 

 

sage: wronskian(*[x^k for k in range(1, 5)]) 

12*x^4 

 

If you want to use 'x' as one of the functions in the Wronskian, 

you can't put it last or it will be interpreted as the variable 

with respect to which we differentiate. There are several ways to 

get around this. 

 

Two-by-two Wronskian of sin(x) and e^x:: 

 

sage: wronskian(sin(x), e^x, x) 

-cos(x)*e^x + e^x*sin(x) 

 

Or don't put x last:: 

 

sage: wronskian(x, sin(x), e^x) 

(cos(x)*e^x + e^x*sin(x))*x - 2*e^x*sin(x) 

 

Example where one of the functions is constant:: 

 

sage: wronskian(1, e^(-x), e^(2*x)) 

-6*e^x 

 

REFERENCES: 

 

- :wikipedia:`Wronskian` 

- http://planetmath.org/encyclopedia/WronskianDeterminant.html 

 

AUTHORS: 

 

- Dan Drake (2008-03-12) 

""" 

if len(args) == 0: 

raise TypeError('wronskian() takes at least one argument (0 given)') 

elif len(args) == 1: 

# a 1x1 Wronskian is just its argument 

return args[0] 

else: 

if is_SymbolicVariable(args[-1]): 

# if last argument is a variable, peel it off and 

# differentiate the other args 

v = args[-1] 

fs = args[0:-1] 

row = lambda n: [diff(f, v, n) for f in fs] 

else: 

# if the last argument isn't a variable, just run 

# .derivative on everything 

fs = args 

row = lambda n: [diff(f, n) for f in fs] 

# NOTE: I rewrote the below as two lines to avoid a possible subtle 

# memory management problem on some platforms (only VMware as far 

# as we know?). See trac #2990. 

# There may still be a real problem that this is just hiding for now. 

A = matrix([row(_) for _ in range(len(fs))]) 

return A.determinant() 

#return matrix(map(row, range(len(fs)))).determinant() 

 

 

def jacobian(functions, variables): 

""" 

Return the Jacobian matrix, which is the matrix of partial 

derivatives in which the i,j entry of the Jacobian matrix is the 

partial derivative diff(functions[i], variables[j]). 

 

EXAMPLES:: 

 

sage: x,y = var('x,y') 

sage: g=x^2-2*x*y 

sage: jacobian(g, (x,y)) 

[2*x - 2*y -2*x] 

 

The Jacobian of the Jacobian should give us the "second derivative", which is the Hessian matrix:: 

 

sage: jacobian(jacobian(g, (x,y)), (x,y)) 

[ 2 -2] 

[-2 0] 

sage: g.hessian() 

[ 2 -2] 

[-2 0] 

 

sage: f=(x^3*sin(y), cos(x)*sin(y), exp(x)) 

sage: jacobian(f, (x,y)) 

[ 3*x^2*sin(y) x^3*cos(y)] 

[-sin(x)*sin(y) cos(x)*cos(y)] 

[ e^x 0] 

sage: jacobian(f, (y,x)) 

[ x^3*cos(y) 3*x^2*sin(y)] 

[ cos(x)*cos(y) -sin(x)*sin(y)] 

[ 0 e^x] 

 

""" 

if is_Matrix(functions) and (functions.nrows()==1 or functions.ncols()==1): 

functions = functions.list() 

elif not (isinstance(functions, (tuple, list)) or is_Vector(functions)): 

functions = [functions] 

 

if not isinstance(variables, (tuple, list)) and not is_Vector(variables): 

variables = [variables] 

 

return matrix([[diff(f, v) for v in variables] for f in functions])