Skip to content

MAINT: LindbladCoefficientBlock blocktype branching#701

Merged
rileyjmurray merged 31 commits intodevelopfrom
lindbladcoeffblock-blocktype-branching
Mar 30, 2026
Merged

MAINT: LindbladCoefficientBlock blocktype branching#701
rileyjmurray merged 31 commits intodevelopfrom
lindbladcoeffblock-blocktype-branching

Conversation

@rileyjmurray
Copy link
Copy Markdown
Contributor

@rileyjmurray rileyjmurray commented Jan 6, 2026

This PR has major changes to LindbladCoefficientBlock. I've taken care to produce code that is equivalent to the old code from an input-output perspective.

After this PR we'll be well-positioned to make a base class for LindbladCoefficientBlock (or just make LindbladCoefficientBlock a base class) from which new classes can inherit. I want to do this because I have an idea for a sparse Cholesky approach to reduced-order CPTP models.

The diff for this PR is kind of awful. Honestly, it's a little hopeless to track what happened. My ask is that we merge anyway once all tests pass. The approach I took to the refactor was to go function by function, preserving as much of the original implementation as possible. My first pass used an LLM for applying the refactoring pattern below. Once some tests failed after this, I did another pass that manually copy-pasted relevant codeblocks from the old perform_operation functions into the new _perform_operation_<blocktype> helper functions.

general approach

I took functions like

def perform_operation(self, *args, **kwargs):
    # some pre-branching work ...
    if self._blocktype == 'ham':
        # insert 3 to 5 lines here; call this codeblock "X"
        pass
    elif self._blocktype == 'other_diagonal':
        # insert 10 to 20 lines of code here; call this codeblock "Y"
        pass
    elif self._blocktype == 'other':
        # insert 20 to 80 lines of code here; call this codeblock "Z"
        pass
    else:
        raise ValueError('unsupported block type')
     # some post-branching work ...
     return

and refactored them to

def perform_operation(self, *args, **kwargs):
    # some pre-branching work ...
    if self._blocktype == 'ham':
        self._perform_operation_ham(*args, **kwargs)
    elif self._blocktype == 'other_diagonal':
        self._perform_operation_otherdiag(*args, **kwargs)
    elif self._blocktype == 'other':
        self._perform_operation_other(*args, **kwargs)
    else:
        raise InvalidBlockTypeError()
     # some post-branching work ...
    return

def _perform_operation_ham(self, *args, **kwargs):
    # insert codeblock "X" here
    return

def _perform_operation_otherdiag(self, *args, **kwargs):
    # insert codeblock "Y" here
    return
    
def _perform_operation_other(self, *args, **kwargs):
    # insert codeblock "Z" here
    return
    
    

…_deriv_wrt_params; apply input checking in caller function LindbladErrorgen.deriv_wrt_params.
@rileyjmurray rileyjmurray marked this pull request as ready for review January 23, 2026 05:39
@rileyjmurray rileyjmurray requested a review from a team as a code owner January 23, 2026 05:39
Comment thread pygsti/modelmembers/operations/lindbladcoefficients.py Outdated
Copy link
Copy Markdown
Contributor

@coreyostrove coreyostrove left a comment

Choose a reason for hiding this comment

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

A couple non-blocking questions/requests. Generally this looks good and I appreciate the hard work and your patience waiting on my review. git diff really made a mess of this one...

A provocative question for you to seed future refactoring discussions. Should we (eventually) go even one step further and split the three block types off into separate classes, ditching the branching and dispatch structure entirely? There is a small shared core, but really the three blocks do quite different things with their internal parameters and it might be even cleaner longer term.

Comment thread pygsti/modelmembers/operations/lindbladcoefficients.py Outdated
Comment thread pygsti/modelmembers/operations/lindbladcoefficients.py Outdated
Comment thread pygsti/modelmembers/operations/lindbladcoefficients.py
@rileyjmurray
Copy link
Copy Markdown
Contributor Author

A provocative question for you to seed future refactoring discussions. Should we (eventually) go even one step further and split the three block types off into separate classes, ditching the branching and dispatch structure entirely? There is a small shared core, but really the three blocks do quite different things with their internal parameters and it might be even cleaner longer term.

Not provocative at all! That's my evil plan 😈. This is just a stepping stone.

@rileyjmurray
Copy link
Copy Markdown
Contributor Author

Original response to Corey's comments referenced a wrong function name. I've fixed in the latest commit. Will see if tests pass.

@rileyjmurray rileyjmurray merged commit 2b4784f into develop Mar 30, 2026
4 checks passed
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.

3 participants