Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constructor for PDMat with Cholesky pre- and post- multiplied by diagonal matrix #132

Open
sethaxen opened this issue Jun 8, 2021 · 0 comments

Comments

@sethaxen
Copy link
Contributor

sethaxen commented Jun 8, 2021

Suppose a user has a Cholesky decomposition of a matrix R and a vector of positive entries σ and wishes to create Σ = PDMat(cholesky(σ .* Matrix(R) .* σ')). This is common in Bayesian inference. e.g. a Cholesky factor of a correlation matrix is drawn from a LKJCholesky distribution, while a vector of standard deviations is drawn from some other distribution, and one wants to construct the Cholesky factorization of the covariance matrix for use in MvNormal.

This can be done much more efficiently with Σ = PDMat(Cholesky(R.uplo == 'U' ? R.U * Diagonal(σ) : Diagonal(σ) * R.L, R.uplo, 0)). But this is still quite long. It would be ideal to have either a constructor for PDMat or some other utility function like the following:

function PDMat(fac::Cholesky, scale::AbstractVector)
    factors_scaled = fac.uplo == 'U' ? fac.factors .* scale' : scale .* fac.factors
    return PDMat(Cholesky(factors_scaled, fac.uplo, 0))
end
function PDMat(fac::Cholesky, scale::UniformScaling)
    return PDMat(Cholesky(fac.factors * scale, fac.uplo, 0))
end
PDMat(fac::Cholesky, scale::Number) = PDMat(fac, scale * I)

See also discussions in JuliaStats/Distributions.jl#1336 and TuringLang/Turing.jl#1629 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant