Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
name = "FiniteDiff"
uuid = "6a86dc24-6348-571c-b903-95158fe2bd41"
version = "2.24.0"
version = "2.25.0"

[deps]
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"

[weakdeps]
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"

[extensions]
FiniteDiffBandedMatricesExt = "BandedMatrices"
FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices"
FiniteDiffSparseArraysExt = "SparseArrays"
FiniteDiffStaticArraysExt = "StaticArrays"

[compat]
Expand All @@ -32,8 +32,9 @@ BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "BlockBandedMatrices", "BandedMatrices", "Pkg", "SafeTestsets", "StaticArrays"]
test = ["Test", "BlockBandedMatrices", "BandedMatrices", "Pkg", "SafeTestsets", "SparseArrays", "StaticArrays"]
55 changes: 55 additions & 0 deletions ext/FiniteDiffSparseArraysExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module FiniteDiffSparseArraysExt

using SparseArrays
using FiniteDiff

# jacobians.jl
function FiniteDiff._make_Ji(::SparseMatrixCSC, rows_index, cols_index, dx, colorvec, color_i, nrows, ncols)
pick_inds = [i for i in 1:length(rows_index) if colorvec[cols_index[i]] == color_i]
rows_index_c = rows_index[pick_inds]
cols_index_c = cols_index[pick_inds]
Ji = sparse(rows_index_c, cols_index_c, dx[rows_index_c], nrows, ncols)
Ji

Check warning on line 12 in ext/FiniteDiffSparseArraysExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/FiniteDiffSparseArraysExt.jl#L12

Added line #L12 was not covered by tests
end

function FiniteDiff._make_Ji(::SparseMatrixCSC, xtype, dx, color_i, nrows, ncols)
Ji = sparse(1:nrows, fill(color_i, nrows), dx, nrows, ncols)
Ji

Check warning on line 17 in ext/FiniteDiffSparseArraysExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/FiniteDiffSparseArraysExt.jl#L17

Added line #L17 was not covered by tests
end

@inline function FiniteDiff._colorediteration!(J, sparsity::SparseMatrixCSC, rows_index, cols_index, vfx, colorvec, color_i, ncols)
@inbounds for col_index in 1:ncols
if colorvec[col_index] == color_i
@inbounds for row_index in view(sparsity.rowval, sparsity.colptr[col_index]:sparsity.colptr[col_index+1]-1)
J[row_index, col_index] = vfx[row_index]
end
end
end
end

@inline FiniteDiff.fill_matrix!(J::AbstractSparseMatrix, v) = fill!(nonzeros(J), v)

@inline function FiniteDiff.fast_jacobian_setindex!(J::AbstractSparseMatrix, rows_index, cols_index, _color, color_i, vfx)
@. FiniteDiff.void_setindex!((J.nzval,), getindex((J.nzval,), rows_index) + (getindex((_color,), cols_index) == color_i) * getindex((vfx,), rows_index), rows_index)

Check warning on line 33 in ext/FiniteDiffSparseArraysExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/FiniteDiffSparseArraysExt.jl#L32-L33

Added lines #L32 - L33 were not covered by tests
end

# iteration_utils.jl
## fast version for the case where J and sparsity have the same sparsity pattern
@inline function FiniteDiff._colorediteration!(Jsparsity::SparseMatrixCSC, vfx, colorvec, color_i, ncols)
@inbounds for col_index in 1:ncols
if colorvec[col_index] == color_i
@inbounds for spidx in nzrange(Jsparsity, col_index)
row_index = Jsparsity.rowval[spidx]
Jsparsity.nzval[spidx] = vfx[row_index]
end
end
end
end

FiniteDiff._use_findstructralnz(::SparseMatrixCSC) = false

FiniteDiff._use_sparseCSC_common_sparsity(J::SparseMatrixCSC, sparsity::SparseMatrixCSC) =
((J.colptr == sparsity.colptr) && (J.rowval == sparsity.rowval))


end
2 changes: 1 addition & 1 deletion src/FiniteDiff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Fast non-allocating calculations of gradients, Jacobians, and Hessians with spar
"""
module FiniteDiff

using LinearAlgebra, SparseArrays, ArrayInterface
using LinearAlgebra, ArrayInterface

import Base: resize!

Expand Down
26 changes: 0 additions & 26 deletions src/iteration_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,8 @@
end
end

@inline function _colorediteration!(J,sparsity::SparseMatrixCSC,rows_index,cols_index,vfx,colorvec,color_i,ncols)
@inbounds for col_index in 1:ncols
if colorvec[col_index] == color_i
@inbounds for row_index in view(sparsity.rowval,sparsity.colptr[col_index]:sparsity.colptr[col_index+1]-1)
J[row_index,col_index]=vfx[row_index]
end
end
end
end

# fast version for the case where J and sparsity have the same sparsity pattern
@inline function _colorediteration!(Jsparsity::SparseMatrixCSC,vfx,colorvec,color_i,ncols)
@inbounds for col_index in 1:ncols
if colorvec[col_index] == color_i
@inbounds for spidx in nzrange(Jsparsity, col_index)
row_index = Jsparsity.rowval[spidx]
Jsparsity.nzval[spidx]=vfx[row_index]
end
end
end
end

#override default setting of using findstructralnz
_use_findstructralnz(sparsity) = ArrayInterface.has_sparsestruct(sparsity)
_use_findstructralnz(::SparseMatrixCSC) = false

# test if J, sparsity are both SparseMatrixCSC and have the same sparsity pattern of stored values
_use_sparseCSC_common_sparsity(J, sparsity) = false
_use_sparseCSC_common_sparsity(J::SparseMatrixCSC, sparsity::SparseMatrixCSC) =
((J.colptr == sparsity.colptr) && (J.rowval == sparsity.rowval))

46 changes: 11 additions & 35 deletions src/jacobians.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,6 @@
JacobianCache{typeof(_x1),typeof(_x2),typeof(_fx),typeof(fx1),typeof(colorvec),typeof(sparsity),fdtype,returntype}(_x1,_x2,_fx,fx1,colorvec,sparsity)
end

function _make_Ji(::SparseMatrixCSC, rows_index,cols_index,dx,colorvec,color_i,nrows,ncols)
pick_inds = [i for i in 1:length(rows_index) if colorvec[cols_index[i]] == color_i]
rows_index_c = rows_index[pick_inds]
cols_index_c = cols_index[pick_inds]
Ji = sparse(rows_index_c, cols_index_c, dx[rows_index_c],nrows,ncols)
Ji
end

function _make_Ji(::AbstractArray, rows_index,cols_index,dx,colorvec,color_i,nrows,ncols)
pick_inds = [i for i in 1:length(rows_index) if colorvec[cols_index[i]] == color_i]
rows_index_c = rows_index[pick_inds]
Expand All @@ -145,12 +137,6 @@
Ji
end

function _make_Ji(::SparseMatrixCSC, xtype, dx, color_i, nrows, ncols)
Ji = sparse(1:nrows,fill(color_i,nrows),dx,nrows,ncols)
Ji
end


function _make_Ji(::AbstractArray, xtype, dx, color_i, nrows, ncols)
Ji = mapreduce(i -> i==color_i ? dx : zero(dx), hcat, 1:ncols)
size(Ji) != (nrows, ncols) ? reshape(Ji, (nrows, ncols)) : Ji #branch when size(dx) == (1,) => size(Ji) == (1,) while size(J) == (1,1)
Expand Down Expand Up @@ -445,11 +431,7 @@
end

if sparsity !== nothing
if J isa AbstractSparseMatrix
fill!(nonzeros(J),false)
else
fill!(J,false)
end
fill_matrix!(J, false)
end

# fast path if J and sparsity are both AbstractSparseMatrix and have the same sparsity pattern
Expand Down Expand Up @@ -497,11 +479,7 @@
J[rows_index, cols_index] .+= (colorvec[cols_index] .== color_i) .* vfx1[rows_index]
+= means requires a zero'd out start
=#
if J isa AbstractSparseMatrix
@. void_setindex!((J.nzval,), getindex((J.nzval,), rows_index) + (getindex((_color,), cols_index) == color_i) * getindex((vfx1,), rows_index), rows_index)
else
@. void_setindex!((J,), getindex((J,), rows_index, cols_index) + (getindex((_color,), cols_index) == color_i) * getindex((vfx1,), rows_index), rows_index, cols_index)
end
fast_jacobian_setindex!(J, rows_index, cols_index, _color, color_i, vfx1)

Check warning on line 482 in src/jacobians.jl

View check run for this annotation

Codecov / codecov/patch

src/jacobians.jl#L482

Added line #L482 was not covered by tests
end
# Now return x1 back to its original value
@. x1 = x1 - epsilon * (_color == color_i)
Expand Down Expand Up @@ -535,11 +513,7 @@
_colorediteration!(J,sparsity,rows_index,cols_index,vfx1,colorvec,color_i,n)
end
else
if J isa AbstractSparseMatrix
@. void_setindex!((J.nzval,), getindex((J.nzval,), rows_index) + (getindex((_color,), cols_index) == color_i) * getindex((vfx1,), rows_index), rows_index)
else
@. void_setindex!((J,), getindex((J,), rows_index, cols_index) + (getindex((_color,), cols_index) == color_i) * getindex((vfx1,), rows_index), rows_index, cols_index)
end
fast_jacobian_setindex!(J, rows_index, cols_index, _color, color_i, vfx1)

Check warning on line 516 in src/jacobians.jl

View check run for this annotation

Codecov / codecov/patch

src/jacobians.jl#L516

Added line #L516 was not covered by tests
end
@. x1 = x1 - epsilon * (_color == color_i)
@. x = x + epsilon * (_color == color_i)
Expand All @@ -565,11 +539,7 @@
_colorediteration!(J,sparsity,rows_index,cols_index,vfx,colorvec,color_i,n)
end
else
if J isa AbstractSparseMatrix
@. void_setindex!((J.nzval,), getindex((J.nzval,), rows_index) + (getindex((_color,), cols_index) == color_i) * getindex((vfx,),rows_index), rows_index)
else
@. void_setindex!((J,), getindex((J,), rows_index, cols_index) + (getindex((_color,), cols_index) == color_i) * getindex((vfx,), rows_index), rows_index, cols_index)
end
fast_jacobian_setindex!(J, rows_index, cols_index, _color, color_i, vfx)

Check warning on line 542 in src/jacobians.jl

View check run for this annotation

Codecov / codecov/patch

src/jacobians.jl#L542

Added line #L542 was not covered by tests
end
@. x1 = x1 - im * epsilon * (_color == color_i)
end
Expand All @@ -583,7 +553,13 @@
function resize!(cache::JacobianCache, i::Int)
resize!(cache.x1, i)
resize!(cache.fx, i)
cache.fx1 != nothing && resize!(cache.fx1, i)
cache.fx1 !== nothing && resize!(cache.fx1, i)

Check warning on line 556 in src/jacobians.jl

View check run for this annotation

Codecov / codecov/patch

src/jacobians.jl#L556

Added line #L556 was not covered by tests
cache.colorvec = 1:i
nothing
end

@inline fill_matrix!(J, v) = fill!(J, v)

@inline function fast_jacobian_setindex!(J, rows_index, cols_index, _color, color_i, vfx)
@. void_setindex!((J,), getindex((J,), rows_index, cols_index) + (getindex((_color,), cols_index) == color_i) * getindex((vfx,), rows_index), rows_index, cols_index)

Check warning on line 564 in src/jacobians.jl

View check run for this annotation

Codecov / codecov/patch

src/jacobians.jl#L563-L564

Added lines #L563 - L564 were not covered by tests
end
Loading