-
Notifications
You must be signed in to change notification settings - Fork 107
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
Added DTCWT
operator
#495
Added DTCWT
operator
#495
Conversation
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.
Well done, this is a very good start :)
I have a few general comments (apart from the specific ones in the code review):
- I always find better to make multiple operators for 1D, 2D, ND. Unless the library that we leverage handles that for us, you will see that we end up having a messy code full of if..else statements if we try to pack all together. Also for 1D you have the special case where the array is 1D, for 2D this doesn't make sense (similar for 3D it doesnt make sense to have 1D and 2D arrays).
- For the 1D case we still want to allow ND arrays as in the philosophy of most pylops operators (see other comments for more on this)
@dikwickley let me know when this is ready for review. Thanks! |
@cako i was planning to look at it over the weekend (@dikwickley told me is ready) but feel free to go ahead if you have time |
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.
The code looks solid, thanks for the feature. One think I think would be nice (but is not necessary) is the addition of a more "intuitive" example. Using random input signals is quite hard to interpret. I would prefer something like two wavelets with different frequencies, and show how they (maybe) will be separated in the DTCWT domain. Just my two cents!
I will let @mrava87 have one final look before we approve.
""" | ||
Dual-Tree Complex Wavelet Transform | ||
========================= | ||
This example shows how to use the :py:class:`pylops.signalprocessing.DCT` operator. |
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 be pylops.signalprocessing.DTCWT
|
||
from typing import Union | ||
|
||
import dtcwt |
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.
this needs to be wrapped in a pylops.utils.deps
check like here:
https://github.com/PyLops/pylops/blob/dev/pylops/_torchoperator.py#LL5-LL10
I haven't been able to look into this yet, but I agree with @cako on the example. Tests are meant to check the correctness of the code so should use as random signals as possible (generally this may bring to surface problems that specials signals - eg constant - dont). But the examples should be as communicative as possible. Whilst it is not always needed to have a tutorial, and example of DTCWT like @cako suggests would be much nicer for the users than using random signals. @dikwickley RTD seems to fail, not sure if this is due to your new code (likely not) or some changes in the RTD process... for now let's not worry, once you push changes we will see if things go back to green light :) |
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.
A couple of additional minor comments to avoid diverging from common practice in matvec/rmatvec
return self._array_to_coeff(X) | ||
|
||
@reshaped | ||
def _matvec(self, x: NDArray) -> NDArray: | ||
x = x.swapaxes(self.axis, -1) |
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.
@this is not good, you should use swapaxes
like here
@reshaped(swapaxis=True) |
When something is readily available and used in many other operators we should not deviate from it unless there is a special requirement, I do not see it here :)
def _rmatvec(self, x: NDArray) -> NDArray: | ||
Y = self._transform.inverse(self._array_to_coeff(x)) | ||
Y = self._2d_to_nd(Y) | ||
return Y.swapaxes(self.axis, -1) |
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.
Same
@@ -0,0 +1,74 @@ | |||
""" | |||
Dual-Tree Complex Wavelet Transform | |||
========================= |
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.
This needs to go all the way to the end of the title
@dikwickley I am reviewing your code and I found quite a few unclear points:
which will give output (14, 1) and (14, 10). Also note that x is a 2d array when you compute elements, why do you need np.prod as by definition you are getting only one element from shape? For now, I limited myself to make some cleaning of the docstring and include dtcwt in installation files where missing, but we need to make sure what you do above is correct before moving ahead :) |
PS: I made another PR to fix the doc issue and also done a bit of cleaning: |
|
I see the point of
Ok, I see, but again you have already |
@dikwickley i am checking if you are still interested to finalize this PR? Since we were close perhaps we can try to finalize it (I remember I only had a few concerns with handling of ndarrays which I didn’t agree with your code… other than that everything seemed good to me) |
@dikwickley I created a new PR as this one is quite hold and has some conflicts. In the new PR you will see that the code is changed quite a bit, because as I mentioned above I think your code is not correct for beyond 1d arrays since it moves Let me know if you are still interested to follow that PR or not? |
move to #538 |
Added Dual-Tree Complex Wavelet Transform Operator. Issues: #46