Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions doc/release/1.1.0-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,25 @@ Deprecated features
Backwards incompatible changes
==============================

When using complex-valued wavelets with the ``cwt``, the output will now be
the complex conjugate of the result that was produced by PyWavelets 1.0.x.
This was done to account for a bug described below. The magnitude of the
``cwt`` coefficients will still match those from previous releases.

Bugs Fixed
==========

For a ``cwt`` with complex wavelets, the results in PyWavelets 1.0.x releases
matched the output of Matlab R2012a's ``cwt``. Howveer, older Matlab releases
like R2012a had a phase that was of opposite sign to that given in textbook
definitions of the CWT (Eq. 2 of Torrence and Compo's review article, "A
Practical Guide to Wavelet Analysis"). Consequently, the wavelet coefficients
were the complex conjugates of the expected result. This was validated by
comparing the results of a transform using ``cmor1.0-1.0`` as compared to the
``cwt`` implementation available in Matlab R2017b as well as the function
``wt.m`` from the Lancaster University Physics department's
`MODA toolbox <https://github.com/luphysics/MODA>`_

Other changes
=============

Expand Down
1 change: 1 addition & 0 deletions pywt/_cwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1):
out = np.empty((np.size(scales),) + data.shape, dtype=dt_out)
precision = 10
int_psi, x = integrate_wavelet(wavelet, precision=precision)
int_psi = np.conj(int_psi) if wavelet.complex_cwt else int_psi

# convert int_psi, x to the same precision as the data
dt_psi = dt_cplx if int_psi.dtype.kind == 'c' else dt
Expand Down
2 changes: 1 addition & 1 deletion pywt/tests/data/generate_matlab_data_cwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
try:
all_matlab_results = {}
for wavelet in wavelets:
w = pywt.Wavelet(wavelet)
w = pywt.ContinuousWavelet(wavelet)
if np.any((wavelet == np.array(['shan', 'cmor'])),axis=0):
mlab.set_variable('wavelet', wavelet+str(w.bandwidth_frequency)+'-'+str(w.center_frequency))
elif wavelet == 'fbsp':
Expand Down
5 changes: 5 additions & 0 deletions pywt/tests/test_matlab_compatibility_cwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ def _check_accuracy(data, w, scales, coefs, wavelet, epsilon):
# PyWavelets result
coefs_pywt, freq = pywt.cwt(data, scales, w)

# coefs from Matlab are from R2012a which is missing the complex conjugate
# as shown in Eq. 2 of Torrence and Compo. We take the complex conjugate of
# the precomputed Matlab result to account for this.
coefs = np.conj(coefs)

# calculate error measures
err = coefs_pywt - coefs
rms = np.real(np.sqrt(np.mean(np.conj(err) * err)))
Expand Down
1 change: 1 addition & 0 deletions util/authors.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
u('Helder'): u('Helder Oliveira'),
u('Kai'): u('Kai Wohlfahrt'),
u('asnt'): u('Alexandre Saint'),
u('pavleb'): u('Pavle Boškoski'),
}


Expand Down