11using FiniteDiff, LinearAlgebra, SparseArrays, Test, LinearAlgebra,
2- BlockBandedMatrices, ArrayInterfaceCore, BandedMatrices,
3- ArrayInterfaceBlockBandedMatrices
2+ BlockBandedMatrices, ArrayInterfaceCore, BandedMatrices,
3+ ArrayInterfaceBlockBandedMatrices
44
55fcalls = 0
6- function f (dx,x)
6+ function f (dx, x)
77 global fcalls += 1
88 for i in 2 : length (x)- 1
99 dx[i] = x[i- 1 ] - 2 x[i] + x[i+ 1 ]
@@ -14,98 +14,98 @@ function f(dx,x)
1414end
1515function oopf (x)
1616 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 ]])
1818end
1919
2020function second_derivative_stencil (N)
21- A = zeros (N,N)
21+ A = zeros (N, N)
2222 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 )
2525 end
2626 A
2727end
2828
29- J = FiniteDiff. finite_difference_jacobian (oopf,rand (30 ))
29+ J = FiniteDiff. finite_difference_jacobian (oopf, rand (30 ))
3030@test J ≈ second_derivative_stencil (30 )
3131_J = sparse (J)
3232@test fcalls == 31
3333
3434_J2 = similar (_J)
3535fcalls = 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 ))
3737@test fcalls == 4
3838@test _J2 ≈ _J
3939
4040_J2 = similar (_J)
4141fcalls = 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 ))
4343@test fcalls == 6
4444@test _J2 ≈ _J
4545
4646_J2 = similar (_J)
4747fcalls = 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 ))
4949@test fcalls == 3
5050@test _J2 ≈ _J
5151
5252_J2 = similar (_J)
5353_denseJ2 = collect (_J2)
5454fcalls = 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)
5656@test fcalls == 4
5757@test sparse (_denseJ2) ≈ _J
5858
5959_J2 = similar (_J)
6060_denseJ2 = collect (_J2)
6161fcalls = 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)
6363@test fcalls == 6
6464@test sparse (_denseJ2) ≈ _J
6565
6666_J2 = similar (_J)
6767_denseJ2 = collect (_J2)
6868fcalls = 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)
7070@test fcalls == 3
7171@test sparse (_denseJ2) ≈ _J
7272
7373_J2 = similar (Tridiagonal (_J))
7474fcalls = 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 ))
7676@test fcalls == 4
7777@test _J2 ≈ _J
7878
7979_J2 = similar (_J2)
8080fcalls = 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 ))
8282@test fcalls == 6
8383@test _J2 ≈ _J
8484
8585_J2 = similar (_J2)
8686fcalls = 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 ))
8888@test fcalls == 3
8989@test _J2 ≈ _J
9090
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 ))
9393@test _Jb ≈ _J
9494
9595_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 ))
9797@test _Jtri ≈ _J
9898
9999# https://github.com/JuliaDiff/FiniteDiff.jl/issues/67#issuecomment-516871956
100100function 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)
109109end
110110x = rand (10000 )
111111Jbbb = BandedBlockBandedMatrix (Ones (10000 , 10000 ), fill (100 , 100 ), fill (100 , 100 ), (1 , 1 ), (1 , 1 ))
@@ -114,7 +114,7 @@ colorsbbb = ArrayInterfaceCore.matrix_colors(Jbbb)
114114FiniteDiff. finite_difference_jacobian! (Jbbb, f, x, colorvec= colorsbbb)
115115FiniteDiff. finite_difference_jacobian! (Jsparse, f, x, colorvec= colorsbbb)
116116@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 ));
118118colorsbb = ArrayInterfaceCore. matrix_colors (Jbb)
119119FiniteDiff. finite_difference_jacobian! (Jbb, f, x, colorvec= colorsbb)
120120@test Jbb ≈ Jsparse
@@ -123,21 +123,21 @@ FiniteDiff.finite_difference_jacobian!(Jbb, f, x, colorvec=colorsbb)
123123# Non-square Jacobian test.
124124# The Jacobian of f_nonsquare! has size (n, 2*n).
125125function 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
134134end
135135
136136n = 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 )
138138y0 = zeros (n)
139139rows = 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])
141141sparsity = sparse (rows, cols, ones (length (rows)))
142142colorvec = vcat (fill (1 , n), fill (2 , n))
143143
@@ -146,15 +146,76 @@ FiniteDiff.finite_difference_jacobian!(J_nonsquare1, f_nonsquare!, x0)
146146
147147J_nonsquare2 = similar (sparsity)
148148for 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 ]
160215end
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