94
94
end
95
95
96
96
function forwarddiff_color_jacobian (f,x:: AbstractArray{<:Number} ,jac_cache:: ForwardColorJacCache ,jac_prototype= nothing )
97
- dx = jac_cache. dx
98
- vecx = vec (x)
99
- sparsity = jac_cache. sparsity
100
97
101
- J = jac_prototype isa Nothing ? (sparsity isa Nothing ? false .* vec (dx) .* vecx' : zeros (eltype (x),size (sparsity))) : zero (jac_prototype)
98
+ if jac_prototype isa Nothing ? ArrayInterface. ismutable (x) : ArrayInterface. ismutable (jac_prototype)
99
+ # Whenever J is mutable, we mutate it to avoid allocations
100
+ dx = jac_cache. dx
101
+ vecx = vec (x)
102
+ sparsity = jac_cache. sparsity
102
103
103
- if ArrayInterface. ismutable (J) # Whenever J is mutable, we mutate it to avoid allocations
104
+ J = jac_prototype isa Nothing ? (sparsity isa Nothing ? false .* vec (dx) .* vecx' :
105
+ zeros (eltype (x),size (sparsity))) : zero (jac_prototype)
104
106
forwarddiff_color_jacobian (J, f, x, jac_cache)
105
107
else
106
- forwarddiff_color_jacobian_immutable (J, f, x, jac_cache)
108
+ return forwarddiff_color_jacobian_immutable (f, x, jac_cache, jac_prototype )
107
109
end
108
110
end
109
111
@@ -138,17 +140,20 @@ function forwarddiff_color_jacobian(J::AbstractMatrix{<:Number},f,x::AbstractArr
138
140
pick_inds = [i for i in 1 : length (rows_index) if colorvec[cols_index[i]] == color_i]
139
141
rows_index_c = rows_index[pick_inds]
140
142
cols_index_c = cols_index[pick_inds]
141
- if J isa SparseMatrixCSC
143
+ if J isa SparseMatrixCSC || j > 1
144
+ # Use sparse matrix to add to J column by column except . . .
142
145
Ji = sparse (rows_index_c, cols_index_c, dx[rows_index_c],nrows,ncols)
143
146
else
147
+ # To overwrite pre-allocated matrix J, using sparse will cause an error
148
+ # so we use this step to overwrite J
144
149
len_rows = length (pick_inds)
145
150
unused_rows = setdiff (1 : nrows,rows_index_c)
146
151
perm_rows = sortperm (vcat (rows_index_c,unused_rows))
147
152
cols_index_c = vcat (cols_index_c,zeros (Int,nrows- len_rows))[perm_rows]
148
153
Ji = [j== cols_index_c[i] ? dx[i] : false for i in 1 : nrows, j in 1 : ncols]
149
154
end
150
155
if j == 1 && i == 1
151
- J .= Ji # overwrite pre-allocated matrix
156
+ J .= Ji # overwrite pre-allocated matrix J
152
157
else
153
158
J .+ = Ji
154
159
end
@@ -172,7 +177,7 @@ function forwarddiff_color_jacobian(J::AbstractMatrix{<:Number},f,x::AbstractArr
172
177
end
173
178
174
179
# When J is immutable, this version of forwarddiff_color_jacobian will avoid mutating J
175
- function forwarddiff_color_jacobian_immutable (J :: AbstractArray{<:Number} , f,x:: AbstractArray{<:Number} ,jac_cache:: ForwardColorJacCache )
180
+ function forwarddiff_color_jacobian_immutable (f,x:: AbstractArray{<:Number} ,jac_cache:: ForwardColorJacCache ,jac_prototype = nothing )
176
181
t = jac_cache. t
177
182
dx = jac_cache. dx
178
183
p = jac_cache. p
@@ -184,6 +189,7 @@ function forwarddiff_color_jacobian_immutable(J::AbstractArray{<:Number},f,x::Ab
184
189
185
190
vecx = vec (x)
186
191
192
+ J = jac_prototype isa Nothing ? (sparsity isa Nothing ? false .* vec (dx) .* vecx' : zeros (eltype (x),size (sparsity))) : zero (jac_prototype)
187
193
nrows,ncols = size (J)
188
194
189
195
if ! (sparsity isa Nothing)
0 commit comments