1
1
# Compute the Jacobian matrix of a real-valued callable f.
2
2
function finite_difference_jacobian (f, x:: AbstractArray{<:Number} ,
3
3
fdtype:: DataType = Val{:central }, funtype:: DataType = Val{:Real }, wrappertype:: DataType = Val{:Default },
4
- fx:: Union{Void,AbstractArray{<:Number}} = nothing , epsilon:: Union{Void,AbstractArray{<:Real}} = nothing , returntype= eltype (x))
4
+ fx:: Union{Void,AbstractArray{<:Number}} = nothing , epsilon:: Union{Void,AbstractArray{<:Real}} = nothing , returntype= eltype (x),
5
+ df:: Union{Void,AbstractArray{<:Number}} = nothing )
5
6
6
7
J = zeros (returntype, length (x), length (x))
7
- finite_difference_jacobian! (J, f, x, fdtype, funtype, wrappertype, fx, epsilon, returntype)
8
+ finite_difference_jacobian! (J, f, x, fdtype, funtype, wrappertype, fx, epsilon, returntype, df )
8
9
end
9
10
10
- function finite_difference_jacobian! (J:: AbstractMatrix{<:Number} , f, x:: AbstractArray{<:Number} ,
11
+ function finite_difference_jacobian! (J:: AbstractMatrix{<:Number} , df :: AbstractVector , f, x:: AbstractArray{<:Number} ,
11
12
fdtype:: DataType = Val{:central }, funtype:: DataType = Val{:Real }, wrappertype:: DataType = Val{:Default },
12
13
fx:: Union{Void,AbstractArray{<:Number}} = nothing , epsilon:: Union{Void,AbstractArray{<:Number}} = nothing , returntype= eltype (x))
13
14
14
- finite_difference_jacobian! (J, f, x, fdtype, funtype, wrappertype, fx, epsilon, returntype)
15
+ finite_difference_jacobian! (J, f, x, fdtype, funtype, wrappertype, fx, epsilon, returntype, df)
16
+ end
17
+
18
+ function finite_difference_jacobian! (J:: AbstractMatrix{<:Number} , f, x:: AbstractArray{<:Number} ,
19
+ fdtype:: DataType = Val{:central }, funtype:: DataType = Val{:Real }, wrappertype:: DataType = Val{:Default },
20
+ fx:: Union{Void,AbstractArray{<:Number}} = nothing , epsilon:: Union{Void,AbstractArray{<:Number}} = nothing , returntype= eltype (x),
21
+ df:: Union{Void,AbstractArray{<:Number}} = nothing )
22
+
23
+ finite_difference_jacobian! (J, f, x, fdtype, funtype, wrappertype, fx, epsilon, returntype, df)
15
24
end
16
25
17
26
function finite_difference_jacobian! (J:: AbstractMatrix{<:Real} , f, x:: AbstractArray{<:Real} ,
18
27
fdtype:: DataType , :: Type{Val{:Real}} , :: Type{Val{:Default}} ,
19
- fx:: Union{Void,AbstractArray{<:Real}} = nothing , epsilon:: Union{Void,AbstractArray{<:Real}} = nothing , returntype= eltype (x))
28
+ fx:: Union{Void,AbstractArray{<:Real}} = nothing , epsilon:: Union{Void,AbstractArray{<:Real}} = nothing , returntype= eltype (x),
29
+ df:: Union{Void,AbstractArray{<:Real}} = nothing )
20
30
21
31
# TODO : test and rework this
22
32
m, n = size (J)
@@ -48,12 +58,16 @@ function finite_difference_jacobian!(J::AbstractMatrix{<:Real}, f, x::AbstractAr
48
58
else
49
59
error (" Unrecognized fdtype: must be Val{:forward} or Val{:central}." )
50
60
end
61
+ if typeof (df) != Void
62
+ df .= diag (J)
63
+ end
51
64
J
52
65
end
53
66
54
67
function finite_difference_jacobian! (J:: StridedMatrix{<:Real} , f, x:: StridedArray{<:Real} ,
55
68
fdtype:: DataType , :: Type{Val{:Real}} , :: Type{Val{:Default}} ,
56
- fx:: Union{Void,StridedArray{<:Real}} = nothing , epsilon:: Union{Void,StridedArray{<:Real}} = nothing , returntype= eltype (x))
69
+ fx:: Union{Void,StridedArray{<:Real}} = nothing , epsilon:: Union{Void,StridedArray{<:Real}} = nothing , returntype= eltype (x),
70
+ df:: Union{Void,StridedArray{<:Real}} = nothing )
57
71
58
72
m, n = size (J)
59
73
epsilon_elemtype = compute_epsilon_elemtype (epsilon, x)
@@ -73,6 +87,9 @@ function finite_difference_jacobian!(J::StridedMatrix{<:Real}, f, x::StridedArra
73
87
J[j,i] = (f (x[j]+ epsilon) - fx[j]) * epsilon_inv
74
88
end
75
89
end
90
+ if typeof (df) != Void
91
+ df[i] = J[j,i]
92
+ end
76
93
else
77
94
J[j,i] = zero (returntype)
78
95
end
@@ -86,6 +103,9 @@ function finite_difference_jacobian!(J::StridedMatrix{<:Real}, f, x::StridedArra
86
103
for j in 1 : m
87
104
if i== j
88
105
J[j,i] = (f (x[j]+ epsilon) - f (x[j]- epsilon)) * epsilon_double_inv
106
+ if typeof (df) != Void
107
+ df[i] = J[j,i]
108
+ end
89
109
else
90
110
J[j,i] = zero (returntype)
91
111
end
@@ -98,6 +118,9 @@ function finite_difference_jacobian!(J::StridedMatrix{<:Real}, f, x::StridedArra
98
118
for j in 1 : m
99
119
if i== j
100
120
J[j,i] = imag (f (x[j]+ im* epsilon)) * epsilon_inv
121
+ if typeof (df) != Void
122
+ df[i] = J[j,i]
123
+ end
101
124
else
102
125
J[j,i] = zero (returntype)
103
126
end
109
132
110
133
function finite_difference_jacobian! (J:: StridedMatrix{<:Number} , f, x:: StridedArray{<:Number} ,
111
134
fdtype:: DataType , :: Type{Val{:Complex}} , :: Type{Val{:Default}} ,
112
- fx:: Union{Void,StridedArray{<:Number}} = nothing , epsilon:: Union{Void,StridedArray{<:Real}} = nothing , returntype= eltype (x))
135
+ fx:: Union{Void,StridedArray{<:Number}} = nothing , epsilon:: Union{Void,StridedArray{<:Real}} = nothing , returntype= eltype (x),
136
+ df:: Union{Void,StridedArray{<:Number}} = nothing )
113
137
114
138
# TODO : finish this
115
139
m, n = size (J)
@@ -126,6 +150,9 @@ function finite_difference_jacobian!(J::StridedMatrix{<:Number}, f, x::StridedAr
126
150
else
127
151
J[j,i] = ( real ( f (x[j]+ epsilon) - fx[j] ) + im* imag ( f (x[j]+ im* epsilon) - fx[j] ) ) * epsilon_inv
128
152
end
153
+ if typeof (df) != Void
154
+ df[i] = J[j,i]
155
+ end
129
156
else
130
157
J[j,i] = zero (returntype)
131
158
end
@@ -139,6 +166,9 @@ function finite_difference_jacobian!(J::StridedMatrix{<:Number}, f, x::StridedAr
139
166
for j in 1 : m
140
167
if i== j
141
168
J[j,i] = ( real ( f (x[j]+ epsilon)- f (x[j]- epsilon) ) + im* imag ( f (x[j]+ im* epsilon) - f (x[j]- im* epsilon) ) ) * epsilon_double_inv
169
+ if typeof (df) != Void
170
+ df[i] = J[j,i]
171
+ end
142
172
else
143
173
J[j,i] = zero (returntype)
144
174
end
0 commit comments