-
Notifications
You must be signed in to change notification settings - Fork 106
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
create custom COO matrix representation for product operators #1635
Conversation
Checking updated PR... No PEP8 issues. Comment last updated at 2024-02-19 07:48:06 UTC |
Has somebody investigated yet whether switching to scipy's |
After some thinking (and talking with @JevgenijaAksjonova) I would go further and say it's probably most reasonable to not use a dedicated sparse-matrix class at all, but simply a dictionary associating index-tuples to operators. This makes Why I hesitate about making a dedicated class: this won't be a proper sparse-matrix implementation unless a lot more work is put into it. One would in principle need to think about questions like how duplicate and out-of-order indices are to be handled. Getting this wrong could lead to strange and subtle bugs. With a plain Performance / memory concerns should not really matter here, assuming that Maybe I'm wrong and some users need products over lots of spaces, though that would sound more like some tensor product space. |
One setting where one might end up with a constructing operators that acts on products over lots of spaces is in Kaczmarz method. The idea is to apply the forward operator on subsets of the data, which in tomography is typically data acquired when the source is in a specific position. Thus, one easily ends up with products over hundreds (if not thousands) of spaces. ODL has an implementation of Kaczmarz, see here for the documentation and here for an example usage. |
ProductSpaceOperator is not used in the example with Kaczmarz method. |
@ozanoktem I get the point: the Kaczmarz method conceptually always inverts a large In that case using a There is still an alternative to be considered to having a custom COO class here: since the cases All of that requires extra code though, so I tend to agree to going with the custom-class approach, then. |
Some tests are failing on this branch:
I'm looking into why this happens, it's probably fairly trivial. Incidentally, |
Ok, the test discrepancies are purely down to the patch --- a/odl/util/testutils.py
+++ b/odl/util/testutils.py
@@ -323,7 +323,7 @@ def noise_array(space):
"""
from odl.space import ProductSpace
if isinstance(space, ProductSpace):
- return np.array([noise_array(si) for si in space])
+ return np.array([noise_array(si) for si in space], dtype=object)
else:
if space.dtype == bool:
arr = np.random.randint(0, 2, size=space.shape, dtype=bool) I think it's more the test suite that's at fault here, than the code being tested. |
@leftaroundabout Overall, I agree with your assessment. I think the duplicate and out-of-order elements issues also arise with the scipy implementation so the suggested class-based approach should not break any existing code at least. Checks for duplicates and ordering could be implemented pretty cheaply here. It might be misleading to call the class |
I think the name is ok, as long as there's some documentation as to the fact that this is merely a bare-bones container data structure with only one use case. Then I would support merging this; the |
Besides making sure unit tests pass, one should also ensure that the examples listed in the links below (many of these rely on constructing product space operators) actually work: |
I checked that the examples involving product space operators ( Can't vouch for correctness of computations. For now, so much in ODL just doesn't work at all that I'm afraid we first need to squash the issues that prevent getting results at all, then when all the examples run and plotting works again we have to scrutinise the results again. Thanks to the high-level |
The update methods for colorbars have been removed in favour of more global updates. Applying the change to the `clim`s simply on the `csub` was suggested by paulhausner in odlgroup#1635 and seems to work fine. Actually updating the drawing of the colorbar (specifically, the ticks on it) did not work with the fix suggested in the Matplotlib documentation, but `canvas.draw_idle()` does seem to have the intended effect. Fixes odlgroup#1636.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be merged. Although I'm not sure the custom class is really the best from a project-maintenance perspective, it is certainly close to what SciPy used to do, and it just works for the tests and examples we currently have.
There are some things in here that don't really belong to the sparse matrix issue, those are addressed in #1640 and #1638. It's probably easiest to first merge those PRs and then rebase this one on top of them.
@@ -436,7 +436,7 @@ def show_discrete_data(values, grid, title=None, method='', | |||
plt.colorbar(mappable=csub, ticks=ticks, format=fmt) | |||
elif update_in_place: | |||
# If it exists and we should update it | |||
csub.colorbar.set_clim(minval, maxval) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not be in this PR, this is subject of #1638
@@ -323,7 +323,7 @@ def noise_array(space): | |||
""" | |||
from odl.space import ProductSpace | |||
if isinstance(space, ProductSpace): | |||
return np.array([noise_array(si) for si in space]) | |||
return np.array([noise_array(si) for si in space], dtype=object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handled by #1640
The update methods for colorbars have been removed in favour of more global updates. Applying the change to the `clim`s simply on the `csub` was suggested by paulhausner in #1635 and seems to work fine. Actually updating the drawing of the colorbar (specifically, the ticks on it) did not work with the fix suggested in the Matplotlib documentation, but `canvas.draw_idle()` does seem to have the intended effect. Fixes #1636.
Could you please rebase this PR? |
Rebased version at https://github.com/leftaroundabout/odl/tree/feature/custom-coo-sparse I have confirmed that this still succeeds the unit tests and relevant examples. |
I can still not run the test example in https://github.com/odlgroup/odl/blob/master/examples/solvers/pdhg_tomography_tgv.py, get error message |
The code below for TV reconstruction using Douglas-Rachford that used to work earlier does not work. The problem is the line defining
|
Were you using the rebased version? The PDHG examply works fine for me on that branch. The branch here does not include the other fixes yet. |
Pull request #1642 has been merged. |
Since scipy version 1.9 the creation of product space operators fails due to API changes. See #1626.
A simple way to fix this is utilizing a custom structure for the coo matrices instead which has the same signature as scipy.
Tested using python version 3.11.7 and scipy 1.10.1
Fixes #1626