diff --git a/Project.toml b/Project.toml index 962727f..48b74fc 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "PDMatsExtras" uuid = "2c7acb1b-7338-470f-b38f-951d2bcb9193" authors = ["Invenia Technical Computing"] -version = "2.5.0" +version = "2.5.1" [deps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" @@ -14,7 +14,7 @@ SuiteSparse = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" ChainRulesCore = "0.9.17, 0.10" Distributions = "0.23, 0.24" FiniteDifferences = "0.11, 0.12" -PDMats = "0.9, 0.10" +PDMats = "0.9, 0.10, 0.11" Zygote = "0.5.5" julia = "1" diff --git a/src/woodbury_pd_mat.jl b/src/woodbury_pd_mat.jl index 05db7fb..7f2e36a 100644 --- a/src/woodbury_pd_mat.jl +++ b/src/woodbury_pd_mat.jl @@ -38,6 +38,8 @@ function WoodburyPDMat( return WoodburyPDMat(A, Diagonal(D), Diagonal(S)) end +WoodburyPDMat{T, TA, TD, TS}(vals...) where {T, TA, TD, TS} = WoodburyPDMat(vals...) + PDMats.dim(W::WoodburyPDMat) = size(W.A, 1) # Convesion method. Primarily useful for testing purposes. @@ -88,14 +90,4 @@ end # NOTE: the parameterisation to scale up the Woodbury matrix is not unique. Here we # implement one way to scale it. *(a::WoodburyPDMat, c::Real) = WoodburyPDMat(a.A, a.D * c, a.S * c) -*(c::Real, a::WoodburyPDMat) = a * c -function *(a::WoodburyPDMat, c::Diagonal{T}) where {T<:Real} - isposdef(c) || throw(ArgumentError("c must be positive definite")) - WoodburyPDMat(sqrt(c) * a.A, a.D, a.S * c) -end -*(c::Diagonal{T}, a::WoodburyPDMat) where {T<:Real} = a * c -function *(c1::Diagonal{T}, a::WoodburyPDMat, c2::Diagonal{T}) where {T<:Real} - isposdef(c1) || throw(ArgumentError("c1 must be positive definite")) - isposdef(c2) || throw(ArgumentError("c2 must be positive definite")) - WoodburyPDMat(sqrt(c1) * sqrt(c2) * a.A, a.D, c1 * a.S * c2) -end +*(c::Real, a::WoodburyPDMat) = a * c \ No newline at end of file diff --git a/test/woodbury_pd_mat.jl b/test/woodbury_pd_mat.jl index 09f0e3c..9e146ea 100644 --- a/test/woodbury_pd_mat.jl +++ b/test/woodbury_pd_mat.jl @@ -7,6 +7,10 @@ W = WoodburyPDMat(A, D, S) W_dense = PDMat(Symmetric(Matrix(W))) + @testset "Valid constructors" begin + @test W == typeof(W)(W.A, W.D, W.S) + end + @testset "invalid constructors error" begin @test_throws ArgumentError WoodburyPDMat(randn(5, 2), D, S) @test_throws ArgumentError WoodburyPDMat(randn(4, 3), D, S) @@ -44,24 +48,6 @@ @test c * W == W * c @test c * W_dense ≈ c * W atol=1e-6 @test (c * W) isa WoodburyPDMat - - c = Diagonal(2.0 * ones(4,)) - @test c * W == W * c - @test c * W_dense ≈ c * W atol=1e-6 - @test (c * W) isa WoodburyPDMat - - c1 = Diagonal(2.0 * ones(4,)) - c2 = Diagonal(3.0 * ones(4,)) - c_neg = Diagonal([1,2,-2,3]) - - @test c2 * W * c1 == c1 * W * c2 - @test c1 * W * c2 ≈ c1 * W_dense * c2 - @test (c1 * W * c2) isa WoodburyPDMat - - @test_throws(ArgumentError, c_neg * W) - @test_throws(ArgumentError, c_neg * W * c2) - @test_throws(ArgumentError, c1 * W * c_neg) - end @testset "MvNormal logpdf" begin