PDMats.jl icon indicating copy to clipboard operation
PDMats.jl copied to clipboard

Cannot construct PDMat from Cholesky{..., ::UpperTriangular}

Open baggepinnen opened this issue 4 years ago • 4 comments

According to the readme, this should work, and there is a method for it, but it fails

julia> c = Cholesky(UpperTriangular(q.R), :U, 0)
Cholesky{Float64,UpperTriangular{Float64,Array{Float64,2}}}
U factor:
4×4 UpperTriangular{Float64,Array{Float64,2}}:
 10.0084  -2.35472  -0.150555  -0.651091
   ⋅       8.48846  -0.832921   0.32629
   ⋅        ⋅       -9.36361    0.0278495
   ⋅        ⋅         ⋅        10.4634

julia> PDMat(c)
ERROR: MethodError: no method matching PDMat{Float64,Array{Float64,2}}(::Int64, ::Array{Float64,2}, ::Cholesky{Float64,UpperTriangular{Float64,Array{Float64,2}}})

[90014a1f] PDMats v0.9.11

The problem seems to be that the matrix in my cholesky object is an UpperTriangular as opposed to a regular matrix.

baggepinnen avatar Mar 13 '20 05:03 baggepinnen

What's q?

johnczito avatar Mar 13 '20 14:03 johnczito

It was a qr decomposition

baggepinnen avatar Mar 13 '20 14:03 baggepinnen

Sure. It will be easier to help if you provide a reproducible example of the error for folks to play around with.

johnczito avatar Mar 13 '20 14:03 johnczito

This issue was not really a request for help, it's just to point out that one can not create a pdmat like it says in the Readme if the cholesky object houses an upper triangular matrix as opposed to a regular matrix.

baggepinnen avatar Mar 13 '20 14:03 baggepinnen

Still exists, but looks different now (with reproducer, PDMats v0.11.16):

julia> c = Cholesky(UpperTriangular(Float64[1 0; 0 1]), :U, 0)
Cholesky{Float64, UpperTriangular{Float64, Matrix{Float64}}}
U factor:
2×2 UpperTriangular{Float64, Matrix{Float64}}:
 1.0  0.0
  ⋅   1.0

julia> PDMat(c)
ERROR: MethodError: Cannot `convert` an object of type Matrix{Float64} to an object of type UpperTriangular{Float64, Matrix{Float64}}
Closest candidates are:
  convert(::Type{var"#s814"} where var"#s814"<:UpperTriangular, ::Union{UnitUpperTriangular, UpperTriangular}) at /Users/ericdavies/repos/julia1p6/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/special.jl:61
  convert(::Type{var"#s814"} where var"#s814"<:UpperTriangular, ::Union{LinearAlgebra.AbstractTriangular, Bidiagonal, Diagonal}) at /Users/ericdavies/repos/julia1p6/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/special.jl:65
  convert(::Type{T}, ::Factorization) where T<:AbstractArray at /Users/ericdavies/repos/julia1p6/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/factorization.jl:58
  ...
Stacktrace:
 [1] PDMat(mat::Matrix{Float64}, chol::Cholesky{Float64, UpperTriangular{Float64, Matrix{Float64}}})
   @ PDMats ~/.julia/packages/PDMats/ZW0lN/src/pdmat.jl:16
 [2] PDMat(fac::Cholesky{Float64, UpperTriangular{Float64, Matrix{Float64}}})
   @ PDMats ~/.julia/packages/PDMats/ZW0lN/src/pdmat.jl:20
 [3] top-level scope
   @ REPL[23]:1

iamed2 avatar Feb 24 '23 23:02 iamed2

I'm not really sure what we can do here since this seems to be an issue stemming from the Cholesky constructor itself: this package (correctly?) assumes that the second type parameter of Cholesky is the type of the matrix that was factorized but the constructor method being used just takes its input's type since it has no other information.

Note that if you used Cholesky(UpperTriangular(...)) and omitted the second two arguments, it works as expected:

julia> c = Cholesky(UpperTriangular(Float64[1 0; 0 1]))
Cholesky{Float64, Matrix{Float64}}
U factor:
2×2 UpperTriangular{Float64, Matrix{Float64}}:
 1.0  0.0
  ⋅   1.0

julia> PDMat(c)
2×2 PDMat{Float64, Matrix{Float64}}:
 1.0  0.0
 0.0  1.0

ararslan avatar Feb 25 '23 02:02 ararslan

I'm going to close this as I don't believe there's anything actionable.

ararslan avatar Feb 27 '23 16:02 ararslan