diff --git a/CHANGELOG.md b/CHANGELOG.md index a0db2221..36aafb24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # SparseConnectivityTracer.jl +## Unreleased +* ![Feature][badge-feature] Add support for `cholesky` ([#322]) + ## Version `v1.2.1` * ![Bugfix][badge-bugfix] Fix `NaNMath.pow` method ambiguity ([#292]) @@ -166,6 +169,7 @@ This release is only breaking for users who touched unexported internals. [badge-maintenance]: https://img.shields.io/badge/maintenance-gray.svg [badge-docs]: https://img.shields.io/badge/docs-orange.svg +[#322]: https://github.com/adrhill/SparseConnectivityTracer.jl/pull/322 [#292]: https://github.com/adrhill/SparseConnectivityTracer.jl/pull/292 [#290]: https://github.com/adrhill/SparseConnectivityTracer.jl/pull/290 [#289]: https://github.com/adrhill/SparseConnectivityTracer.jl/pull/289 diff --git a/src/overloads/arrays.jl b/src/overloads/arrays.jl index b8068544..41ba5453 100644 --- a/src/overloads/arrays.jl +++ b/src/overloads/arrays.jl @@ -72,6 +72,31 @@ function LinearAlgebra.eigen( return LinearAlgebra.Eigen(values, vectors) end +## Cholesky +# A generic `cholesky` compares matrix entries (pivoting / positive-definiteness), which on tracers +# return a tracer rather than a `Bool`. Like `eigen`, return a conservative all-depends factor. +function LinearAlgebra.cholesky( + A::AbstractMatrix{T}, + ::LinearAlgebra.NoPivot = LinearAlgebra.NoPivot(); + check::Bool = true, + ) where {T <: AbstractTracer} + LinearAlgebra.checksquare(A) + n = size(A, 1) + t = second_order_or(A) + return LinearAlgebra.Cholesky(Fill(t, n, n), 'U', 0) +end +function LinearAlgebra.cholesky( + A::AbstractMatrix{T}, + ::LinearAlgebra.RowMaximum; + tol::Real = 0.0, + check::Bool = true, + ) where {T <: AbstractTracer} + LinearAlgebra.checksquare(A) + n = size(A, 1) + t = second_order_or(A) + return LinearAlgebra.CholeskyPivoted(Fill(t, n, n), 'U', 1:n, n, tol, 0) +end + ## Inverse function Base.inv(A::StridedMatrix{T}) where {T <: AbstractTracer} LinearAlgebra.checksquare(A) diff --git a/test/test_arrays.jl b/test/test_arrays.jl index 6eb8d102..bbba8acf 100644 --- a/test/test_arrays.jl +++ b/test/test_arrays.jl @@ -12,6 +12,7 @@ using Test using LinearAlgebra: Symmetric, Diagonal, diagind using LinearAlgebra: det, logdet, logabsdet, norm, opnorm using LinearAlgebra: eigen, eigmax, eigmin +using LinearAlgebra: cholesky, NoPivot, RowMaximum using LinearAlgebra: inv, pinv, dot using SparseArrays: sparse, spdiagm @@ -697,6 +698,21 @@ end @test all(t -> sameidx(t, s_out), vectors) end +@testset "Cholesky" begin + t1 = idx2tracer([1, 3, 4]) + t2 = idx2tracer([2, 4]) + t3 = idx2tracer([8, 9]) + t4 = idx2tracer([8, 9]) + A = [t1 t2; t3 t4] + s_out = idx2set([1, 2, 3, 4, 8, 9]) + @testset "$pivot" for pivot in (NoPivot(), RowMaximum()) + factors = cholesky(A, pivot).factors + @test size(factors) == (2, 2) + @test all(t -> sameidx(t, s_out), factors) + end + @test all(t -> sameidx(t, s_out), cholesky(A).factors) +end + @testset "SparseMatrixCSC construction" begin t1 = idx2tracer(1) t2 = idx2tracer(2)