Skip to content

Commit

Permalink
Merge branch 'main' into dk/dot_hermorsym
Browse files Browse the repository at this point in the history
  • Loading branch information
dkarrasch authored Jul 22, 2023
2 parents 9152333 + cb10c1e commit cdde659
Show file tree
Hide file tree
Showing 10 changed files with 453 additions and 341 deletions.
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ julia> R = sparsevec(I,V)

The inverse of the [`sparse`](@ref) and [`sparsevec`](@ref) functions is
[`findnz`](@ref), which retrieves the inputs used to create the sparse array.
[`findall(!iszero, x)`](@ref) returns the cartesian indices of non-zero entries in `x`
[`findall(!iszero, x)`](@ref) returns the Cartesian indices of non-zero entries in `x`
(including stored entries equal to zero).

```jldoctest sparse_function
Expand Down
2 changes: 1 addition & 1 deletion src/higherorderfns.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const SpBroadcasted2{Style<:SPVM,Axes,F,Args<:Tuple{SparseVecOrMat,SparseVecOrMa

# (1) The definitions below provide a common interface to sparse vectors and matrices
# sufficient for the purposes of map[!]/broadcast[!]. This interface treats sparse vectors
# as n-by-one sparse matrices which, though technically incorrect, is how broacast[!] views
# as n-by-one sparse matrices which, though technically incorrect, is how broadcast[!] views
# sparse vectors in practice.
@inline numrows(A::AbstractCompressedVector) = length(A)
@inline numrows(A::AbstractSparseMatrixCSC) = size(A, 1)
Expand Down
731 changes: 405 additions & 326 deletions src/linalg.jl

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/solvers/cholmod.jl
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ Factor(FC::FactorComponent) = FC.F
#################

# Dense wrappers
# The ifelse here may be unecessary.
# The ifelse here may be unnecessary.
# nothing different actually occurs in cholmod_l_allocate vs cholmod_allocate AFAICT.
# And CHOLMOD has no way of tracking the difference internally (no internal itype field).
# This leads me to believe they can be mixed with long and int versions of sparse freely.
Expand Down
4 changes: 2 additions & 2 deletions src/solvers/umfpack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ UmfpackWS(F::ATLU, refinement::Bool=has_refinement(F)) = UmfpackWS(F.parent, ref
A shallow copy of UmfpackLU to use in multithreaded solve applications.
This function duplicates the working space, control, info and lock fields.
"""
# Not using simlar helps if the actual needed size has changed as it would need to be resized again
# Not using similar helps if the actual needed size has changed as it would need to be resized again
Base.copy(F::UmfpackLU{Tv, Ti}, ws=UmfpackWS(F)) where {Tv, Ti} =
UmfpackLU(
F.symbolic,
Expand Down Expand Up @@ -413,7 +413,7 @@ When `check = false`, responsibility for checking the decomposition's
validity (via [`issuccess`](@ref)) lies with the user.
The permutation `q` can either be a permutation vector or `nothing`. If no permutation vector
is proveded or `q` is `nothing`, UMFPACK's default is used. If the permutation is not zero based, a
is provided or `q` is `nothing`, UMFPACK's default is used. If the permutation is not zero based, a
zero based copy is made.
See also [`lu`](@ref)
Expand Down
5 changes: 4 additions & 1 deletion src/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Get a writable copy of x. See `_unsafe_unfix(x)`
"""
SparseMatrixCSC(x::FixedSparseCSC) = SparseMatrixCSC(size(x, 1), size(x, 2),
copy(parent(getcolptr(x))),
copy(parent(rowval(x))),
copy(parent(rowvals(x))),
copy(nonzeros(x)))

function sparse_check_Ti(m::Integer, n::Integer, Ti::Type)
Expand Down Expand Up @@ -294,6 +294,9 @@ column. In conjunction with [`nonzeros`](@ref) and
# perform sparse wizardry...
end
end
!!! warning
Adding or removing nonzero elements to the matrix may invalidate the `nzrange`, one should not mutate the matrix while iterating.
"""
nzrange(S::AbstractSparseMatrixCSC, col::Integer) = getcolptr(S)[col]:(getcolptr(S)[col+1]-1)
nzrange(S::SparseMatrixCSCView, col::Integer) = nzrange(S.parent, S.indices[2][col])
Expand Down
8 changes: 4 additions & 4 deletions src/sparsevector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import Base: sort!, findall, copy!
import LinearAlgebra: promote_to_array_type, promote_to_arrays_
using LinearAlgebra: adj_or_trans
using LinearAlgebra: wrapperop

### The SparseVector

Expand Down Expand Up @@ -1236,7 +1236,7 @@ function hvcat(rows::Tuple{Vararg{Int}}, X::_SparseConcatGroup...)
if anysparse(X...)
vcat(_hvcat_rows(rows, X...)...)
else
Base.typed_hvcat(promote_eltypeof(X...), rows, X...)
Base.typed_hvcat(Base.promote_eltypeof(X...), rows, X...)
end
end
function _hvcat_rows((row1, rows...)::Tuple{Vararg{Int}}, X::_SparseConcatGroup...)
Expand Down Expand Up @@ -1780,7 +1780,7 @@ function (*)(A::_StridedOrTriangularMatrix{Ta}, x::AbstractSparseVector{Tx}) whe
length(x) == n || throw(DimensionMismatch())
Ty = promote_op(matprod, eltype(A), eltype(x))
y = Vector{Ty}(undef, m)
mul!(y, A, x, true, false)
mul!(y, A, x)
end

function LinearAlgebra.generic_matvecmul!(y::AbstractVector, tA, A::StridedMatrix, x::AbstractSparseVector,
Expand Down Expand Up @@ -1981,7 +1981,7 @@ function *(A::AbstractSparseMatrixCSC, x::AbstractSparseVector)
end

*(xA::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}, x::AbstractSparseVector) =
_At_or_Ac_mul_B((a,b) -> adj_or_trans(xA)(a) * b, xA.parent, x, promote_op(matprod, eltype(xA), eltype(x)))
_At_or_Ac_mul_B((a,b) -> wrapperop(xA)(a) * b, xA.parent, x, promote_op(matprod, eltype(xA), eltype(x)))

function _At_or_Ac_mul_B(tfun::Function, A::AbstractSparseMatrixCSC{TvA,TiA}, x::AbstractSparseVector{TvX,TiX},
Tv = promote_op(matprod, TvA, TvX)) where {TvA,TiA,TvX,TiX}
Expand Down
34 changes: 32 additions & 2 deletions test/fixed.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ using SparseArrays: AbstractSparseVector, AbstractSparseMatrixCSC, FixedSparseCS
@test (r[1] = r[1]; true)
end

@testset "SparseMatrixCSC from readonly" begin

# test that SparseMatrixCSC from readonly does copy
A = sprandn(12, 11, 0.3)
B = SparseMatrixCSC(size(A)..., ReadOnly(getcolptr(A)), ReadOnly(rowvals(A)), nonzeros(A))

@test typeof(B) == typeof(A)
@test A == B

@test getcolptr(A) == getcolptr(B)
@test getcolptr(A) !== getcolptr(B)
@test rowvals(A) == rowvals(B)
@test rowvals(A) !== rowvals(B)
@test nonzeros(A) == nonzeros(B)
@test nonzeros(A) === nonzeros(B)
end

struct_eq(A, B, C...) = struct_eq(A, B) && struct_eq(B, C...)
struct_eq(A::AbstractSparseMatrixCSC, B::AbstractSparseMatrixCSC) =
getcolptr(A) == getcolptr(B) && rowvals(A) == rowvals(B)
Expand All @@ -30,6 +47,10 @@ struct_eq(A::AbstractSparseVector, B::AbstractSparseVector) =
A = sprandn(10, 10, 0.3)

F = FixedSparseCSC(copy(A))
Ft = FixedSparseCSC{eltype(A),eltype(rowvals(A))}(A)
@test typeof(Ft) == typeof(F)
@test Ft == F

@test struct_eq(F, A)
nonzeros(F) .= 0
@test struct_eq(F, A)
Expand Down Expand Up @@ -69,7 +90,16 @@ struct_eq(A::AbstractSparseVector, B::AbstractSparseVector) =
@test typeof(B) == typeof(F)
@test struct_eq(B, F)
end
@testset "SparseMatrixCSC conversions" begin
A = sprandn(10, 10, 0.3)
F = fixed(copy(A))
B = SparseMatrixCSC(F)
@test A == B

# fixed(x...)
@test sparse(2I, 3, 3) == sparse(fixed(2I, 3, 3))
@test SparseArrays._unsafe_unfix(A) == A
end
@testset "FixedSparseVector" begin
y = sprandn(10, 0.3)
x = FixedSparseVector(copy(y))
Expand All @@ -88,7 +118,7 @@ end
@test f(x, y, z) == 0
t = similar(x)
@test typeof(t) == typeof(x)
@test struct_eq(t, x)
@test struct_eq(t, x)
end

@testset "Issue #190" begin
Expand Down Expand Up @@ -139,4 +169,4 @@ always_false(x...) = false
@test all(iszero, nonzeros(b))

end
end
end
2 changes: 1 addition & 1 deletion test/linalg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ end
ACa = sparse(trop(AC)) # copied and adjoint
@test AT \ B AC \ B
@test ATa \ B ACa \ B
@test ATa \ sparse(B) == ATa \ B
@test ATa \ sparse(B) ATa \ B
@test Matrix(ATa) \ B ATa \ B
@test ATa * ( ATa \ B ) B
end
Expand Down
4 changes: 2 additions & 2 deletions test/sparsematrix_constructors_indexing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,7 @@ end
@test Base.isstored(A, c[1], c[2]) == false
end

# `isstored` for adjoint and tranposed matrices:
# `isstored` for adjoint and transposed matrices:
for trans in (adjoint, transpose)
B = trans(A)
stored_indices = [CartesianIndex(j, i) for (j, i) in zip(J, I)]
Expand Down Expand Up @@ -1390,7 +1390,7 @@ using Base: swaprows!, swapcols!
(swaprows!, 2, 3), # Test swapping rows of unequal length
(swaprows!, 2, 4), # Test swapping non-adjacent rows
(swapcols!, 1, 2), # Test swapping columns where one column is fully sparse
(swapcols!, 2, 3), # Test swapping coulms of unequal length
(swapcols!, 2, 3), # Test swapping columns of unequal length
(swapcols!, 2, 4)) # Test swapping non-adjacent columns
Scopy = copy(S)
Sdense = Array(S)
Expand Down

0 comments on commit cdde659

Please sign in to comment.