1
1
using FiniteDiff, LinearAlgebra, SparseArrays, Test, LinearAlgebra,
2
- BlockBandedMatrices, ArrayInterfaceCore, BandedMatrices,
3
- ArrayInterfaceBlockBandedMatrices
2
+ BlockBandedMatrices, ArrayInterfaceCore, BandedMatrices,
3
+ ArrayInterfaceBlockBandedMatrices
4
4
5
5
fcalls = 0
6
- function f (dx,x)
6
+ function f (dx, x)
7
7
global fcalls += 1
8
8
for i in 2 : length (x)- 1
9
9
dx[i] = x[i- 1 ] - 2 x[i] + x[i+ 1 ]
@@ -14,98 +14,98 @@ function f(dx,x)
14
14
end
15
15
function oopf (x)
16
16
global fcalls += 1
17
- vcat ([- 2 x[1 ]+ x[2 ]],[x[i- 1 ]- 2 x[i]+ x[i+ 1 ] for i in 2 : length (x)- 1 ],[x[end - 1 ]- 2 x[end ]])
17
+ vcat ([- 2 x[1 ] + x[2 ]], [x[i- 1 ] - 2 x[i] + x[i+ 1 ] for i in 2 : length (x)- 1 ], [x[end - 1 ] - 2 x[end ]])
18
18
end
19
19
20
20
function second_derivative_stencil (N)
21
- A = zeros (N,N)
21
+ A = zeros (N, N)
22
22
for i in 1 : N, j in 1 : N
23
- (j - i == - 1 || j- i == 1 ) && (A[i,j] = 1 )
24
- j - i == 0 && (A[i,j] = - 2 )
23
+ (j - i == - 1 || j - i == 1 ) && (A[i, j] = 1 )
24
+ j - i == 0 && (A[i, j] = - 2 )
25
25
end
26
26
A
27
27
end
28
28
29
- J = FiniteDiff. finite_difference_jacobian (oopf,rand (30 ))
29
+ J = FiniteDiff. finite_difference_jacobian (oopf, rand (30 ))
30
30
@test J ≈ second_derivative_stencil (30 )
31
31
_J = sparse (J)
32
32
@test fcalls == 31
33
33
34
34
_J2 = similar (_J)
35
35
fcalls = 0
36
- FiniteDiff. finite_difference_jacobian! (_J2,f, rand (30 ),colorvec= repeat (1 : 3 ,10 ))
36
+ FiniteDiff. finite_difference_jacobian! (_J2, f, rand (30 ), colorvec= repeat (1 : 3 , 10 ))
37
37
@test fcalls == 4
38
38
@test _J2 ≈ _J
39
39
40
40
_J2 = similar (_J)
41
41
fcalls = 0
42
- FiniteDiff. finite_difference_jacobian! (_J2,f, rand (30 ),Val{:central },colorvec= repeat (1 : 3 ,10 ))
42
+ FiniteDiff. finite_difference_jacobian! (_J2, f, rand (30 ), Val{:central }, colorvec= repeat (1 : 3 , 10 ))
43
43
@test fcalls == 6
44
44
@test _J2 ≈ _J
45
45
46
46
_J2 = similar (_J)
47
47
fcalls = 0
48
- FiniteDiff. finite_difference_jacobian! (_J2,f, rand (30 ),Val{:complex },colorvec= repeat (1 : 3 ,10 ))
48
+ FiniteDiff. finite_difference_jacobian! (_J2, f, rand (30 ), Val{:complex }, colorvec= repeat (1 : 3 , 10 ))
49
49
@test fcalls == 3
50
50
@test _J2 ≈ _J
51
51
52
52
_J2 = similar (_J)
53
53
_denseJ2 = collect (_J2)
54
54
fcalls = 0
55
- FiniteDiff. finite_difference_jacobian! (_denseJ2,f, rand (30 ),colorvec= repeat (1 : 3 ,10 ),sparsity= _J2)
55
+ FiniteDiff. finite_difference_jacobian! (_denseJ2, f, rand (30 ), colorvec= repeat (1 : 3 , 10 ), sparsity= _J2)
56
56
@test fcalls == 4
57
57
@test sparse (_denseJ2) ≈ _J
58
58
59
59
_J2 = similar (_J)
60
60
_denseJ2 = collect (_J2)
61
61
fcalls = 0
62
- FiniteDiff. finite_difference_jacobian! (_denseJ2,f, rand (30 ),Val{:central },colorvec= repeat (1 : 3 ,10 ),sparsity= _J2)
62
+ FiniteDiff. finite_difference_jacobian! (_denseJ2, f, rand (30 ), Val{:central }, colorvec= repeat (1 : 3 , 10 ), sparsity= _J2)
63
63
@test fcalls == 6
64
64
@test sparse (_denseJ2) ≈ _J
65
65
66
66
_J2 = similar (_J)
67
67
_denseJ2 = collect (_J2)
68
68
fcalls = 0
69
- FiniteDiff. finite_difference_jacobian! (_denseJ2,f, rand (30 ),Val{:complex },colorvec= repeat (1 : 3 ,10 ),sparsity= _J2)
69
+ FiniteDiff. finite_difference_jacobian! (_denseJ2, f, rand (30 ), Val{:complex }, colorvec= repeat (1 : 3 , 10 ), sparsity= _J2)
70
70
@test fcalls == 3
71
71
@test sparse (_denseJ2) ≈ _J
72
72
73
73
_J2 = similar (Tridiagonal (_J))
74
74
fcalls = 0
75
- FiniteDiff. finite_difference_jacobian! (_J2,f, rand (30 ),colorvec= repeat (1 : 3 ,10 ))
75
+ FiniteDiff. finite_difference_jacobian! (_J2, f, rand (30 ), colorvec= repeat (1 : 3 , 10 ))
76
76
@test fcalls == 4
77
77
@test _J2 ≈ _J
78
78
79
79
_J2 = similar (_J2)
80
80
fcalls = 0
81
- FiniteDiff. finite_difference_jacobian! (_J2,f, rand (30 ),Val{:central },colorvec= repeat (1 : 3 ,10 ))
81
+ FiniteDiff. finite_difference_jacobian! (_J2, f, rand (30 ), Val{:central }, colorvec= repeat (1 : 3 , 10 ))
82
82
@test fcalls == 6
83
83
@test _J2 ≈ _J
84
84
85
85
_J2 = similar (_J2)
86
86
fcalls = 0
87
- FiniteDiff. finite_difference_jacobian! (_J2,f, rand (30 ),Val{:complex },colorvec= repeat (1 : 3 ,10 ))
87
+ FiniteDiff. finite_difference_jacobian! (_J2, f, rand (30 ), Val{:complex }, colorvec= repeat (1 : 3 , 10 ))
88
88
@test fcalls == 3
89
89
@test _J2 ≈ _J
90
90
91
- _Jb = BandedMatrices. BandedMatrix (similar (_J2),(1 ,1 ))
92
- FiniteDiff. finite_difference_jacobian! (_Jb, f, rand (30 ), colorvec= repeat (1 : 3 ,10 ))
91
+ _Jb = BandedMatrices. BandedMatrix (similar (_J2), (1 , 1 ))
92
+ FiniteDiff. finite_difference_jacobian! (_Jb, f, rand (30 ), colorvec= repeat (1 : 3 , 10 ))
93
93
@test _Jb ≈ _J
94
94
95
95
_Jtri = Tridiagonal (similar (_J2))
96
- FiniteDiff. finite_difference_jacobian! (_Jtri, f, rand (30 ), colorvec= repeat (1 : 3 ,10 ))
96
+ FiniteDiff. finite_difference_jacobian! (_Jtri, f, rand (30 ), colorvec= repeat (1 : 3 , 10 ))
97
97
@test _Jtri ≈ _J
98
98
99
99
# https://github.com/JuliaDiff/FiniteDiff.jl/issues/67#issuecomment-516871956
100
100
function f (out, x)
101
- x = reshape (x, 100 , 100 )
102
- out = reshape (out, 100 , 100 )
103
- for i in 1 : 100
104
- for j in 1 : 100
105
- out[i, j] = x[i, j] + x[max (i - 1 , 1 ), j] + x[min (i+ 1 , size (x, 1 )), j] + x[i, max (j- 1 , 1 )] + x[i, min (j+ 1 , size (x, 2 ))]
106
- end
107
- end
108
- return vec (out)
101
+ x = reshape (x, 100 , 100 )
102
+ out = reshape (out, 100 , 100 )
103
+ for i in 1 : 100
104
+ for j in 1 : 100
105
+ out[i, j] = x[i, j] + x[max (i - 1 , 1 ), j] + x[min (i + 1 , size (x, 1 )), j] + x[i, max (j - 1 , 1 )] + x[i, min (j + 1 , size (x, 2 ))]
106
+ end
107
+ end
108
+ return vec (out)
109
109
end
110
110
x = rand (10000 )
111
111
Jbbb = BandedBlockBandedMatrix (Ones (10000 , 10000 ), fill (100 , 100 ), fill (100 , 100 ), (1 , 1 ), (1 , 1 ))
@@ -114,7 +114,7 @@ colorsbbb = ArrayInterfaceCore.matrix_colors(Jbbb)
114
114
FiniteDiff. finite_difference_jacobian! (Jbbb, f, x, colorvec= colorsbbb)
115
115
FiniteDiff. finite_difference_jacobian! (Jsparse, f, x, colorvec= colorsbbb)
116
116
@test Jbbb ≈ Jsparse
117
- Jbb = BlockBandedMatrix (similar (Jsparse),fill (100 , 100 ), fill (100 , 100 ),(1 ,1 ));
117
+ Jbb = BlockBandedMatrix (similar (Jsparse), fill (100 , 100 ), fill (100 , 100 ), (1 , 1 ));
118
118
colorsbb = ArrayInterfaceCore. matrix_colors (Jbb)
119
119
FiniteDiff. finite_difference_jacobian! (Jbb, f, x, colorvec= colorsbb)
120
120
@test Jbb ≈ Jsparse
@@ -123,21 +123,21 @@ FiniteDiff.finite_difference_jacobian!(Jbb, f, x, colorvec=colorsbb)
123
123
# Non-square Jacobian test.
124
124
# The Jacobian of f_nonsquare! has size (n, 2*n).
125
125
function f_nonsquare! (y, x)
126
- global fcalls += 1
127
- @assert length (x) == 2 * length (y)
128
- n = length (x) ÷ 2
129
- x1 = @view x[1 : n]
130
- x2 = @view x[n+ 1 : end ]
131
-
132
- @. y = (x1 .- 3 ). ^ 2 .+ x1.* x2 .+ (x2 .+ 4 ). ^ 2 .- 3
133
- return nothing
126
+ global fcalls += 1
127
+ @assert length (x) == 2 * length (y)
128
+ n = length (x) ÷ 2
129
+ x1 = @view x[1 : n]
130
+ x2 = @view x[n+ 1 : end ]
131
+
132
+ @. y = (x1 .- 3 ) .^ 2 .+ x1 .* x2 .+ (x2 .+ 4 ) .^ 2 .- 3
133
+ return nothing
134
134
end
135
135
136
136
n = 4
137
- x0 = vcat (ones (n).* (1 : n) .+ 0.5 , ones (n).* (1 : n) .+ 1.5 )
137
+ x0 = vcat (ones (n) .* (1 : n) .+ 0.5 , ones (n) .* (1 : n) .+ 1.5 )
138
138
y0 = zeros (n)
139
139
rows = vcat ([i for i in 1 : n], [i for i in 1 : n])
140
- cols = vcat ([i for i in 1 : n], [i+ n for i in 1 : n])
140
+ cols = vcat ([i for i in 1 : n], [i + n for i in 1 : n])
141
141
sparsity = sparse (rows, cols, ones (length (rows)))
142
142
colorvec = vcat (fill (1 , n), fill (2 , n))
143
143
@@ -146,15 +146,76 @@ FiniteDiff.finite_difference_jacobian!(J_nonsquare1, f_nonsquare!, x0)
146
146
147
147
J_nonsquare2 = similar (sparsity)
148
148
for method in [Val (:forward ), Val (:central ), Val (:complex )]
149
- cache = FiniteDiff. JacobianCache (copy (x0), copy (y0), copy (y0), method; sparsity, colorvec)
150
- global fcalls = 0
151
- FiniteDiff. finite_difference_jacobian! (J_nonsquare2, f_nonsquare!, x0, cache)
152
- if method == Val (:central )
153
- @test fcalls == 2 * maximum (colorvec)
154
- elseif method == Val (:complex )
155
- @test fcalls == maximum (colorvec)
156
- else
157
- @test fcalls == maximum (colorvec) + 1
158
- end
159
- @test isapprox (J_nonsquare2, J_nonsquare1; rtol= 1e-6 )
149
+ cache = FiniteDiff. JacobianCache (copy (x0), copy (y0), copy (y0), method; sparsity, colorvec)
150
+ global fcalls = 0
151
+ FiniteDiff. finite_difference_jacobian! (J_nonsquare2, f_nonsquare!, x0, cache)
152
+ if method == Val (:central )
153
+ @test fcalls == 2 * maximum (colorvec)
154
+ elseif method == Val (:complex )
155
+ @test fcalls == maximum (colorvec)
156
+ else
157
+ @test fcalls == maximum (colorvec) + 1
158
+ end
159
+ @test isapprox (J_nonsquare2, J_nonsquare1; rtol= 1e-6 )
160
+ end
161
+
162
+ # # Non-sparse prototype
163
+ # Test structralnz for dense matrix
164
+ A = [[1 1 ; 0 1 ], [1 1 1 ], [1.0 1.0 ; 1.0 1.0 ; 1.0 1.0 ], [true true ; true true ]]
165
+ for a in A
166
+ rows_index, cols_index = FiniteDiff. _findstructralnz (a)
167
+ rows_index2, cols_index2 = ArrayInterfaceCore. findstructralnz (sparse (a))
168
+ @test (rows_index, cols_index) == (rows_index2, cols_index2)
169
+ end
170
+
171
+ # Square Jacobian
172
+ function _f (dx, x)
173
+ dx .= [x[1 ]^ 2 + x[2 ]^ 2 , x[1 ] + x[2 ]]
174
+ end
175
+ J = zeros (2 , 2 )
176
+ θ = [5.0 , 3.0 ]
177
+ y0 = [0.0 , 0.0 ]
178
+ cache = FiniteDiff. JacobianCache (copy (θ), copy (y0), copy (y0), Val (:forward ); sparsity= [1 1 ; 1 1 ])
179
+ FiniteDiff. finite_difference_jacobian! (J, _f, θ, cache)
180
+ @test J ≈ [10 6 ; 1 1 ]
181
+
182
+ function _f2 (dx, x)
183
+ dx .= [x[1 ]^ 2 + x[2 ]^ 2 , x[1 ]]
184
+ end
185
+ J = zeros (2 , 2 )
186
+ θ = [- 3.0 , 2.0 ]
187
+ y0 = [0.0 , 0.0 ]
188
+ cache = FiniteDiff. JacobianCache (copy (θ), copy (y0), copy (y0), Val (:forward ); sparsity= [1 1 ; 1 0 ])
189
+ FiniteDiff. finite_difference_jacobian! (J, _f2, θ, cache)
190
+ @test J ≈ [- 6 4 ; 1 0 ]
191
+
192
+ # Rectangular Jacobian
193
+ function _f3 (dx, x)
194
+ dx .= [x[1 ]^ 2 + x[2 ]^ 2 - x[1 ]]
195
+ end
196
+ J = zeros (1 , 2 )
197
+ θ = [- 3.0 , 2.0 ]
198
+ y0 = [0.0 , 0.0 ]
199
+ cache = FiniteDiff. JacobianCache (copy (θ), copy (y0), copy (y0), Val (:forward ); sparsity= [1 1 ])
200
+ FiniteDiff. finite_difference_jacobian! (J, _f3, θ, cache)
201
+ @test J ≈ [- 7 4 ]
202
+
203
+ function _f4 (dx, x)
204
+ dx .= [x[1 ]^ 2 + x[2 ]^ 2 - x[1 ]; x[1 ]* x[2 ]; x[1 ]* x[3 ]; x[1 ]]
205
+ end
206
+ J = zeros (4 , 3 )
207
+ θ = [- 3.0 , 2.0 , 13.3 ]
208
+ y0 = [0.0 , 0.0 , 0.0 , 0.0 ]
209
+ cache = FiniteDiff. JacobianCache (copy (θ), copy (y0), copy (y0), Val (:forward ); sparsity= [1 1 0 ; 1 1 0 ; 1 0 1 ; 1 0 0 ])
210
+ FiniteDiff. finite_difference_jacobian! (J, _f4, θ, cache)
211
+ @test J ≈ [- 7.0 4.0 0 ; 2.0 - 3.0 0.0 ; 13.3 0.0 - 3.0 ; 1.0 0.0 0.0 ]
212
+
213
+ function _f5 (dx, x)
214
+ dx .= [x[1 ]^ 2 + x[2 ]^ 2 ]
160
215
end
216
+ J = zeros (1 , 2 )
217
+ θ = [5.0 , 3.0 ]
218
+ y0 = [0.0 ]
219
+ cache = FiniteDiff. JacobianCache (copy (θ), copy (y0), copy (y0), Val (:forward ); sparsity = [1 1 ])
220
+ FiniteDiff. finite_difference_jacobian! (J, _f5, θ, cache)
221
+ @test J ≈ [10.0 6.0 ]
0 commit comments