-
Notifications
You must be signed in to change notification settings - Fork 20
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
First stage dual tree filters #36
Comments
Hi Nikola, The first stage filters for the dual-tree complex wavelet transform is supposed to be a normal, DWT filter. So these lines are working as expected: from pywt import Wavelet
wavelet = Wavelet("db2")
real_first, imag_first = dt_first_stage("db2")
real_first.filter_bank == wavelet.filter_bank # returns True as expected
imag_first.filter_bank == wavelet.filter_bank # returns True as expected As for the last line: real_first.filter_bank == imag_first.filter_bank # return True I don't have access anymore to the reference paper on the dual-tree complex wavelet transform, but I remember following it closely. Based on that reference, what did you expect? |
Hi Laurent, Based on the reference paper :
where is the decomposition low pass filter bank (or the analysis filter) for the first stage for the imaginary tree, and is the decomposition low pass filter bank (or the analysis filter) for the first stage for the real tree. So, according to me, the set of filters for the imaginary tree has to be shifted by one sample with respect to the set of filters for the real tree. My confusion is to the following lines : import numpy as np
from pywt import Wavelet
db2 = Wavelet("db2")
filter_bank = [np.array(f, copy=True) for f in db2.filter_bank]
for filt in filter_bank:
extended = np.zeros(shape=(filt.shape[0] + 2,), dtype=float)
extended[1:-1] = filt
filt = extended I suppose that the every filter in the set of filters in filter_bank should be surrounded by one zero at the beginning and one zero at the end. But after the execution of the function, filter_bank is the same as the db2.filter_bank. The following lines of code do this : import numpy as np
from pywt import Wavelet
db2 = Wavelet("db2")
# extend filter bank with zeros
filter_bank = [np.array(f, copy=True) for f in db2.filter_bank]
for i, filt in enumerate(filter_bank):
extended = np.zeros(shape=(filt.shape[0] + 2,), dtype=float)
extended[1:-1] = filt
filter_bank[i] = extended After that : In [5]: filter_bank
Out[5]:
[array([ 0. , -0.12940952, 0.22414387, 0.8365163 , 0.48296291, 0. ]),
array([ 0. , -0.48296291, 0.8365163 , -0.22414387, -0.12940952, 0. ]),
array([ 0. , 0.48296291, 0.8365163 , 0.22414387, -0.12940952, 0. ]),
array([ 0. , -0.12940952, -0.22414387, 0.8365163 , -0.48296291, 0. ])]
In [6]: db2.filter_bank
Out[6]:
([-0.12940952255126037, 0.2241438680420134, 0.8365163037378079, 0.48296291314453416],
[-0.48296291314453416, 0.8365163037378079, -0.2241438680420134, -0.12940952255126037],
[0.48296291314453416, 0.8365163037378079, 0.2241438680420134, -0.12940952255126037],
[-0.12940952255126037, -0.2241438680420134, 0.8365163037378079, -0.48296291314453416])
In [7]: filter_bank == db2.filter_bank
Out[7]: False I suppose that this is specific to the numpy issue with the arrays. Similarly, the following lines of code do not change shifted_fb : import numpy as np
from pywt import Wavelet
db2 = Wavelet("db2")
# Shift deconstruction filters to one side, and reconstruction
# to the other side
shifted_fb = [np.array(f, copy=True) for f in db2.filter_bank]
for filt in shifted_fb[::2]: # Deconstruction filters
filt = np.roll(filt, 1)
for filt in shifted_fb[2::]: # Reconstruction filters
filt = np.roll(filt, -1)
In [11]: db2.filter_bank
Out[11]:
([-0.12940952255126037, 0.2241438680420134, 0.8365163037378079, 0.48296291314453416],
[-0.48296291314453416, 0.8365163037378079, -0.2241438680420134, -0.12940952255126037],
[0.48296291314453416, 0.8365163037378079, 0.2241438680420134, -0.12940952255126037],
[-0.12940952255126037, -0.2241438680420134, 0.8365163037378079, -0.48296291314453416])
In [12]: shifted_fb
Out[12]:
[array([-0.12940952, 0.22414387, 0.8365163 , 0.48296291]),
array([-0.48296291, 0.8365163 , -0.22414387, -0.12940952]),
array([ 0.48296291, 0.8365163 , 0.22414387, -0.12940952]),
array([-0.12940952, -0.22414387, 0.8365163 , -0.48296291])] The following lines of code do change shifted_fb : import numpy as np
from pywt import Wavelet
db2 = Wavelet("db2")
filter_bank = [
np.array([ 0. , -0.12940952, 0.22414387, 0.8365163 , 0.48296291, 0. ]),
np.array([ 0. , -0.48296291, 0.8365163 , -0.22414387, -0.12940952, 0. ]),
np.array([ 0. , 0.48296291, 0.8365163 , 0.22414387, -0.12940952, 0. ]),
np.array([ 0. , -0.12940952, -0.22414387, 0.8365163 , -0.48296291, 0. ])
]
# Shift deconstruction filters to one side, and reconstruction
# to the other side
shifted_fb = [np.array(f, copy=True) for f in filter_bank]
for i, filt in enumerate(shifted_fb[:2]): # Deconstruction filters
shifted_fb[i] = np.roll(filt, 1)
for i, filt in enumerate(shifted_fb[2:]): # Reconstruction filters
shifted_fb[i + 2] = np.roll(filt, -1)
In [15]: db2.filter_bank
Out[15]:
([-0.12940952255126037, 0.2241438680420134, 0.8365163037378079, 0.48296291314453416],
[-0.48296291314453416, 0.8365163037378079, -0.2241438680420134, -0.12940952255126037],
[0.48296291314453416, 0.8365163037378079, 0.2241438680420134, -0.12940952255126037],
[-0.12940952255126037, -0.2241438680420134, 0.8365163037378079, -0.48296291314453416])
In [16]: shifted_fb
Out[16]:
[array([ 0. , 0. , -0.12940952, 0.22414387, 0.8365163 , 0.48296291]),
array([ 0. , 0. , -0.48296291, 0.8365163 , -0.22414387, -0.12940952]),
array([ 0.48296291, 0.8365163 , 0.22414387, -0.12940952, 0. , 0. ]),
array([-0.12940952, -0.22414387, 0.8365163 , -0.48296291, 0. , 0. ])] I changed from pywt import Wavelet
db2 = Wavelet("db2")
db2.filter_bank[0] == db2.dec_lo # return True
db2.filter_bank[1] == db2.dec_hi # return True
db2.filter_bank[2] == db2.rec_lo # return True
db2.filter_bank[3] == db2.rec_hi # return True |
Ahh yes I see the problem now. Thank you for investigating! If you feel comfortable, you might want to submit a pull-request yourself. Otherwise, I will be able to fix this only next week. |
Hi Laurent, I wish you successes. 👍 |
Version 2.1.7 has just been released, which contains a fix for this. Don't hesitate to open other issues if you find more problems. Thanks! |
Version / Platform Info
Expected Behavior
Hello. My question is about the function dt_first_stage(wavelet) in scikit-ued/skued/baseline/dtcwt.py module. To my best knowledge, for the two sets of the first filter banks it is necessary to translate one set of filters by one sample with respect to the other set.
Actual Behavior
As one can see from the minimal example below, the first stage real and imaginary filters are actually same as the filters for the normal DWT. Furthermore, the first stage real and imaginary filters are the same. If this is really true, the DTCWT cannot be realized.
Minimal Example of Issue
The function dt_first_stage(wavelet) is actually copied from the source code.
The text was updated successfully, but these errors were encountered: