Block Diagonal Operator
Describe your changes
Takes in a main diagonal, a list of operators, and, optionally, other diagonals and creates an BlockDiagonalOperator that subclasses the operator class.
Describe any testing you have performed
Please add any demo scripts to CIL-Demos/misc/
Link relevant issues
Closes #1568
Checklist when you are ready to request a review
- [ ] I have performed a self-review of my code
- [ ] I have added docstrings in line with the guidance in the developer guide
- [ ] I have implemented unit tests that cover any new or modified functionality
- [ ] CHANGELOG.md has been updated with any functionality change
- [ ] Request review from all relevant developers
- [ ] Change pull request label to 'Waiting for review'
Contribution Notes
Please read and adhere to the developer guide and local patterns and conventions.
- [ ] The content of this Pull Request (the Contribution) is intentionally submitted for inclusion in CIL (the Work) under the terms and conditions of the Apache-2.0 License.
- [ ] I confirm that the contribution does not violate any intellectual property rights of third parties
Some open questions:
- This BlockDiagonalOperator is an Operator but not a BlockOperator because it doesn't have the full list of operators needed for the BlockOperator. I wonder if this will be a problem?
- I haven't worked out how to calculate the norm efficiently. I think for the case of a single main diagonal block operator it is straightforward but not with off diagonals.
- I haven't given the option for non-square block matrices or for the main diagonal not to be defined, because then there is an issue with not knowing the full domain and range geometry for your operator.
- I need to write some more unit tests!
@jakobsj You mentioned that you had thought about this before - any thoughts?
I think this could also be handled by BlockOperator by not calling direct or adjoint of the ZeroOperator on direct or adjoint respectively.
For instance this https://github.com/TomographicImaging/CIL/blob/524d403f624351b787aba882e99d6cbee6d0c385/Wrappers/Python/cil/optimisation/operators/BlockOperator.py#L206-L207
could be substituted by
op = self.get_item(row, col)
if not isinstance(op, ZeroOperator):
prod += op.direct(x_b.get_item(col))