Skip to content

Conversation

sethaxen
Copy link
Contributor

@sethaxen sethaxen commented May 9, 2025

As discussed in #132 (comment), this PR overloads X_A_Xt, Xt_A_X, X_invA_Xt, and Xt_invA_X to return the appropriate PDMats type when we can guarantee the return type is an AbstractPDMat and when it doesn't require computing a new decomposition. Fixes #132.

@codecov-commenter
Copy link

codecov-commenter commented May 9, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 93.62%. Comparing base (508d717) to head (71b295f).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #222      +/-   ##
==========================================
+ Coverage   93.20%   93.62%   +0.42%     
==========================================
  Files           9       10       +1     
  Lines         736      769      +33     
==========================================
+ Hits          686      720      +34     
+ Misses         50       49       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sethaxen sethaxen changed the title Overload congruent transforms for AbstractPDMat return types Overload congruence transforms for AbstractPDMat return types May 9, 2025
return ScalMat(A.dim, abs2(B.value) * A.value)
end
$(f)(A::PDiagMat, B::PDiagMat) = PDiagMat(abs2.(B.diag) .* A.diag)
$(f)(A::PDiagMat, B::ScalMat) = PDiagMat(abs2(B.value) .* A.diag)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT we also have to check that dimensions match in this function:

Suggested change
$(f)(A::PDiagMat, B::ScalMat) = PDiagMat(abs2(B.value) .* A.diag)
function $(f)(A::PDiagMat, B::ScalMat)
@check_argdims size(A, 1) == B.dim
return PDiagMat(abs2(B.value) .* A.diag)
end

Comment on lines +19 to +25
uplo = A.chol.uplo
if uplo === 'U'
factors = A.chol.factors * B.value'
else
factors = B.value * A.chol.factors
end
chol = Cholesky(factors, uplo, A.chol.info)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since ScalMat is a AbstractMatrix{<:Real}, it seems we could merge the two branches:

Suggested change
uplo = A.chol.uplo
if uplo === 'U'
factors = A.chol.factors * B.value'
else
factors = B.value * A.chol.factors
end
chol = Cholesky(factors, uplo, A.chol.info)
factors = B.value * A.chol.factors
chol = Cholesky(factors, A.chol.uplo, A.chol.info)

chol = Cholesky(factors, uplo, A.chol.info)
return PDMat(mat, chol)
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For completeness, probably we should also add definitions for first arguments of types PDSparseMat and Cholesky.

@check_argdims A.dim == size(B, 1)
return PDiagMat(B.diag .* (A.value .\ B.diag))
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason to omit definitions for PDMat (and PDSparseMat and Cholesky)? That they wouldn't be more efficient than the generic definitions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For PDMat, PDMat yes, the result is a PDMat, but we can't reuse the decomposition, so if we construct a PDMat, then it requires a cholesky call. I think this is worse than outputting a Matrix.

For PDSparseMat, ScalMat, the problem is that only \ is implemented for SparseArrays.CHOLMOD.FactorComponent and only with dense vectors/matrices; we have no way to modify the entries of the factor, so it seems better not to overload it.

I can add Cholesky overloads.

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

Successfully merging this pull request may close these issues.

Constructor for PDMat with Cholesky pre- and post- multiplied by diagonal matrix
3 participants