Repository navigation
Conversation
CholLinearOperator inherits most of its methods from RootLinearOperator,
which assumes that the matrix is root @ root.mT. For an upper triangular
factor (upper=True, i.e. R^T R), matmul, diagonal, indexing, expand,
constant multiplication, root_decomposition and sampling therefore used
R R^T instead. Also, upper was not part of the representation, so detach,
clone, to() and the autograd functions rebuilt the operator with
upper=False. Store an upper triangular factor R as the equivalent lower
triangular factor R^T instead, so that all of these methods are correct.
inverse() returned a CholLinearOperator with upper=True whose factor
L^{-1} is lower triangular, so its matmul, diagonal and solve were wrong.
(L L^T)^{-1} = L^{-T} L^{-1} is not a Cholesky factorization, so return a
RootLinearOperator of L^{-T} instead.
Slicing the rows and columns of a CholLinearOperator with the same index,
e.g. op[0:3, 0:3], constructed a CholLinearOperator from the selected
rows of the Cholesky factor, which are not triangular, and raised
"NotImplementedError: torch.tril(InterpolatedLinearOperator, ) is not
implemented". Return a RootLinearOperator of these rows instead. Batch
indexing still returns a CholLinearOperator.
Run the CholLinearOperator tests for upper triangular factors too, and
test slicing with equal row and column indices and the matmul and solve
of the inverse.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #144.
Problem
CholLinearOperatorinherits most of its methods fromRootLinearOperator, which assumes that the matrix isroot @ root.mT(see #144 for reproductions):upper=True, i.e.R^T R),matmul,diagonal, indexing,expand, constant multiplication,root_decompositionand sampling usedR R^Tinstead. Also,upperwas not part of the representation, sodetach(),clone(),to()and the autograd functions rebuilt the operator withupper=False.inverse()returned aCholLinearOperatorwithupper=Truewhose factorL^{-1}is lower triangular, so itsmatmul,diagonalandsolvewere wrong.op[0:3, 0:3], constructed aCholLinearOperatorfrom the selected rows of the factor, which are not triangular, and raisedNotImplementedError: torch.tril(InterpolatedLinearOperator, ) is not implemented.Change
Ras the equivalent lower triangular factorL = R^T(a lazy transpose of theTriangularLinearOperator). Then all inherited methods and the reconstruction from the representation are correct.upperis still accepted, but theupperattribute is now alwaysFalseandrootisR^T. Theif self.upper:branches into_dense,inv_quadetc. are kept, although they are no longer taken; I can remove them if you prefer.inverse()returnsRootLinearOperator(L^{-T}), since(L L^T)^{-1} = L^{-T} L^{-1}is not a Cholesky factorization. This is the same representation thatroot_inv_decomposition()already returns.CholLinearOperator._getitemreturns aRootLinearOperatorof the selected rows for indices of the matrix dimensions. Batch indexing still returns aCholLinearOperator.Tests
TestCholLinearOperatorUpper,...UpperBatchand...UpperMultiBatchrun the wholeLinearOperatorTestCasesuite for upper triangular factors. Their reference matrix uses the operator'supperattribute, so the tests also catchupperbeing lost on reconstruction. Onmain, 26 different tests fail for them, includingtest_getitem,test_diagonal,test_sample, thetest_solve_*tests andtest_constant_mul.test_getitem_square_slicesslices the rows and columns with the same index; it fails onmainfor all 6 classes.test_inversealso checksmatmulandsolveof the inverse; it fails onmainfor all 6 classes. Its gradient comparison now skips non-leaf representation tensors (the lazily transposed factor of the upper variants), like the generic tests do.Full suite: 5238 tests pass, except
test_psd_safe_cholesky_psd, which also fails onmainlocally (torch 2.13 on Windows, unrelated). flake8 passes. Downstream, BoTorch's tests that use Cholesky covariances give the same results with and without this change, and BoTorch'sseparate_mtmvnworks forCholLinearOperatorcovariances without a workaround. Tested with Python 3.13, PyTorch 2.13 (CPU).🤖 Generated with Claude Code