@@ -27,6 +27,123 @@ function _finite_difference_jacobian!(J::AbstractMatrix{<:Real}, f,
27
27
fdtype:: DataType , :: Type{Val{:Real}} , :: Type{Val{:Default}} ,
28
28
fx, epsilon, returntype, inplace:: Type{Val{true}} )
29
29
30
+ # TODO : test and rework this to support GPUArrays and non-indexable types, if possible
31
+ m, n = size (J)
32
+ epsilon_elemtype = compute_epsilon_elemtype (epsilon, x)
33
+ if fdtype == Val{:forward }
34
+ if typeof (fx) == Void
35
+ fx = similar (x,returntype)
36
+ end
37
+ f (fx,x)
38
+ # TODO : Remove these allocations
39
+ fx2 = similar (x,returntype)
40
+ shifted_x = copy (x)
41
+ epsilon_factor = compute_epsilon_factor (Val{:forward }, epsilon_elemtype)
42
+ @inbounds for i in 1 : n
43
+ epsilon = compute_epsilon (Val{:forward }, x[i], epsilon_factor)
44
+ shifted_x[i] += epsilon
45
+ f (fx2,shifted_x)
46
+ J[:, i] .= (fx2 - fx) / epsilon
47
+ shifted_x[i] = x[i]
48
+ end
49
+ elseif fdtype == Val{:central }
50
+ epsilon_factor = compute_epsilon_factor (Val{:central }, epsilon_elemtype)
51
+ if typeof (fx) == Void
52
+ fx1 = similar (x,returntype)
53
+ else
54
+ fx1 = fx
55
+ end
56
+ # TODO : Remove these allocations
57
+ fx2 = similar (x,returntype)
58
+ shifted_x_plus = copy (x)
59
+ shifted_x_minus = copy (x)
60
+ @inbounds for i in 1 : n
61
+ epsilon = compute_epsilon (Val{:central }, x[i], epsilon_factor)
62
+ shifted_x_plus[i] += epsilon
63
+ shifted_x_minus[i] -= epsilon
64
+ f (fx1,shifted_x_plus)
65
+ f (fx2,shifted_x_minus)
66
+ J[:, i] .= (fx1 - fx2) / (epsilon + epsilon)
67
+ shifted_x_plus[i] = x[i]
68
+ shifted_x_minus[i] = x[i]
69
+ end
70
+ elseif fdtype == Val{:complex }
71
+ x0 = Vector {Complex{eltype(x)}} (x)
72
+ epsilon = eps (eltype (x))
73
+ fx1 = similar (x,Complex{eltype (x)})
74
+ @inbounds for i in 1 : n
75
+ x0[i] += im * epsilon
76
+ f (fx1,x0)
77
+ J[:,i] .= imag .(fx1) / epsilon
78
+ x0[i] -= im * epsilon
79
+ end
80
+ else
81
+ fdtype_error (Val{:Real })
82
+ end
83
+ J
84
+ end
85
+
86
+ function _finite_difference_jacobian! (J:: AbstractMatrix{<:Number} , f,
87
+ x:: AbstractArray{<:Number} ,
88
+ fdtype:: DataType , :: Type{Val{:Complex}} , :: Type{Val{:Default}} ,
89
+ fx, epsilon, returntype, inplace:: Type{Val{true}} )
90
+
91
+ # TODO : test and rework this to support GPUArrays and non-indexable types, if possible
92
+ m, n = size (J)
93
+ epsilon_elemtype = compute_epsilon_elemtype (epsilon, x)
94
+ if fdtype == Val{:forward }
95
+
96
+ if typeof (fx) == Void
97
+ fx = similar (x,returntype)
98
+ end
99
+ f (fx,x)
100
+ # TODO : Remove these allocations
101
+ fx2 = similar (x,returntype)
102
+ shifted_x = copy (x)
103
+
104
+ epsilon_factor = compute_epsilon_factor (Val{:forward }, epsilon_elemtype)
105
+
106
+ @inbounds for i in 1 : n
107
+ epsilon = compute_epsilon (Val{:forward }, real (x[i]), epsilon_factor)
108
+ shifted_x[i] += epsilon
109
+ f (fx2,shifted_x)
110
+ @. J[:, i] = ( real (fx2 - fx ) + im* imag ( fx2 - fx ) ) / epsilon
111
+ shifted_x[i] = x[i]
112
+ end
113
+ elseif fdtype == Val{:central }
114
+ epsilon_factor = compute_epsilon_factor (Val{:central }, epsilon_elemtype)
115
+
116
+ if typeof (fx) == Void
117
+ fx1 = similar (x,returntype)
118
+ else
119
+ fx1 = fx
120
+ end
121
+ # TODO : Remove these allocations
122
+ fx2 = similar (x,returntype)
123
+ shifted_x_plus = copy (x)
124
+ shifted_x_minus = copy (x)
125
+
126
+ @inbounds for i in 1 : n
127
+ epsilon = compute_epsilon (Val{:central }, real (x[i]), epsilon_factor)
128
+ shifted_x_plus[i] += epsilon
129
+ shifted_x_minus[i] -= epsilon
130
+ f (fx1,shifted_x_plus)
131
+ f (fx2,shifted_x_minus)
132
+ @. J[:, i] = ( real (fx1 - fx2) + im* imag (fx1 - fx2) ) / (2 * epsilon)
133
+ shifted_x_plus[i] = x[i]
134
+ shifted_x_minus[i] = x[i]
135
+ end
136
+ else
137
+ fdtype_error (Val{:Complex })
138
+ end
139
+ J
140
+ end
141
+
142
+ function _finite_difference_jacobian! (J:: AbstractMatrix{<:Real} , f,
143
+ x:: AbstractArray{<:Real} ,
144
+ fdtype:: DataType , :: Type{Val{:Real}} , :: Type{Val{:Default}} ,
145
+ fx, epsilon, returntype, inplace:: Type{Val{false}} )
146
+
30
147
# TODO : test and rework this to support GPUArrays and non-indexable types, if possible
31
148
m, n = size (J)
32
149
epsilon_elemtype = compute_epsilon_elemtype (epsilon, x)
71
188
function _finite_difference_jacobian! (J:: AbstractMatrix{<:Number} , f,
72
189
x:: AbstractArray{<:Number} ,
73
190
fdtype:: DataType , :: Type{Val{:Complex}} , :: Type{Val{:Default}} ,
74
- fx, epsilon, returntype, inplace:: Type{Val{true }} )
191
+ fx, epsilon, returntype, inplace:: Type{Val{false }} )
75
192
76
193
# TODO : test and rework this to support GPUArrays and non-indexable types, if possible
77
194
m, n = size (J)
0 commit comments