Synchrosqueezing, wavelet transforms, and time-frequency analysis in Python

Overview

Synchrosqueezing in Python

ssqueezepy CI codecov PyPI version Codacy Badge DOI License: MIT

Synchrosqueezing is a powerful reassignment method that focuses time-frequency representations, and allows extraction of instantaneous amplitudes and frequencies. Friendly overview.

Features

  • Continuous Wavelet Transform (CWT), forward & inverse, and its Synchrosqueezing
  • Short-Time Fourier Transform (STFT), forward & inverse, and its Synchrosqueezing
  • Wavelet visualizations and testing suite
  • Generalized Morse Wavelets
  • Ridge extraction
  • Fastest wavelet transforms in Python1, beating MATLAB

1: feel free to open Issue showing otherwise

Installation

pip install ssqueezepy. Or, for latest version (most likely stable):

pip install git+https://github.com/OverLordGoldDragon/ssqueezepy

GPU & CPU acceleration

Multi-threaded execution is enabled by default (disable via os.environ['SSQ_PARALLEL'] = '0'). GPU requires CuPy >= 8.0.0 and PyTorch >= 1.8.0 installed (enable via os.environ['SSQ_GPU'] = '1'). pyfftw optionally supported for maximum CPU FFT speed. See Performance guide.

Benchmarks

Code. Transforms use padding, float32 precision (float64 supported), and output shape (300, len(x)), averaged over 10 runs. pyfftw not used, which'd speed 1-thread & parallel further. Benched on author's i7-7700HQ, GTX 1070.

len(x)-transform 1-thread CPU parallel gpu pywavelets scipy librosa
10k-cwt 0.126 0.0462 0.00393 3.58 0.523 -
10k-stft 0.108 0.0385 0.00534 - 0.118 0.0909
10k-ssq_cwt 0.372 0.148 0.00941 - - -
10k-ssq_stft 0.282 0.147 0.0278 - - -
160k-cwt 2.99 1.25 0.0367 12.7 10.7 -
160k-stft 1.66 0.418 0.0643 - 1.93 1.38
160k-ssq_cwt 8.38 3.16 0.0856 - - -
160k-ssq_stft 4.65 2.48 0.159 - - -

Examples

1. Signal recovery under severe noise

image

2. Medical: EEG

3. Testing suite: CWT vs STFT, reflect-added parallel linear chirp

4. Ridge extraction: cubic polynom. F.M. + pure tone; noiseless & 1.69dB SNR

More

5. Testing suite: GMW vs Morlet, reflect-added hyperbolic chirp (extreme time-loc.)

6. Higher-order GMW CWT, reflect-added parallel linear chirp, 3.06dB SNR

More examples

Introspection

ssqueezepy is equipped with a visualization toolkit, useful for exploring wavelet behavior across scales and configurations. (Also see explanations and code)


Minimal example

import numpy as np
import matplotlib.pyplot as plt
from ssqueezepy import ssq_cwt, ssq_stft

def viz(x, Tx, Wx):
    plt.imshow(np.abs(Wx), aspect='auto', cmap='turbo')
    plt.show()
    plt.imshow(np.abs(Tx), aspect='auto', vmin=0, vmax=.2, cmap='turbo')
    plt.show()

#%%# Define signal ####################################
N = 2048
t = np.linspace(0, 10, N, endpoint=False)
xo = np.cos(2 * np.pi * 2 * (np.exp(t / 2.2) - 1))
xo += xo[::-1]  # add self reflected
x = xo + np.sqrt(2) * np.random.randn(N)  # add noise

plt.plot(xo); plt.show()
plt.plot(x);  plt.show()

#%%# CWT + SSQ CWT ####################################
Twxo, Wxo, *_ = ssq_cwt(xo)
viz(xo, Twxo, Wxo)

Twx, Wx, *_ = ssq_cwt(x)
viz(x, Twx, Wx)

#%%# STFT + SSQ STFT ##################################
Tsxo, Sxo, *_ = ssq_stft(xo)
viz(xo, np.flipud(Tsxo), np.flipud(Sxo))

Tsx, Sx, *_ = ssq_stft(x)
viz(x, np.flipud(Tsx), np.flipud(Sx))

Also see ridge extraction README.

Learning resources

  1. Continuous Wavelet Transform, & vs STFT
  2. Synchrosqueezing's phase transform, intuitively
  3. Wavelet time & frequency resolution visuals
  4. Why oscillations in SSQ of mixed sines? Separability visuals
  5. Zero-padding's effect on spectrum

DSP fundamentals: I recommend starting with 3b1b's Fourier Transform, then proceeding with DSP Guide chapters 7-11. The Discrete Fourier Transform lays the foundation of signal processing with real data. Deeper on DFT coefficients here, also 3b1b.

Contributors (noteworthy)

  • David Bondesson: ridge extraction (ridge_extraction.py; examples/: extracting_ridges.py, ridge_extraction/README.md)

How to cite

Short form:

OverLordGoldDragon, ssqueezepy, 2020. GitHub repository, https://github.com/OverLordGoldDragon/ssqueezepy/. DOI: 10.5281/zenodo.5080514

BibTeX:

@article{OverLordGoldDragon2020ssqueezepy,
  title={ssqueezepy},
  author={OverLordGoldDragon},
  journal={GitHub. Note: https://github.com/OverLordGoldDragon/ssqueezepy/},
  year={2020},
  doi={10.5281/zenodo.5080514},
}

References

ssqueezepy was originally ported from MATLAB's Synchrosqueezing Toolbox, authored by E. Brevdo and G. Thakur [1]. Synchrosqueezed Wavelet Transform was introduced by I. Daubechies and S. Maes [2], which was followed-up in [3], and adapted to STFT in [4]. Many implementation details draw from [5]. Ridge extraction based on [6].

  1. G. Thakur, E. Brevdo, N.-S. Fučkar, and H.-T. Wu. "The Synchrosqueezing algorithm for time-varying spectral analysis: robustness properties and new paleoclimate applications", Signal Processing 93:1079-1094, 2013.
  2. I. Daubechies, S. Maes. "A Nonlinear squeezing of the Continuous Wavelet Transform Based on Auditory Nerve Models".
  3. I. Daubechies, J. Lu, H.T. Wu. "Synchrosqueezed Wavelet Transforms: a Tool for Empirical Mode Decomposition", Applied and Computational Harmonic Analysis 30(2):243-261, 2011.
  4. G. Thakur, H.T. Wu. "Synchrosqueezing-based Recovery of Instantaneous Frequency from Nonuniform Samples", SIAM Journal on Mathematical Analysis, 43(5):2078-2095, 2011.
  5. Mallat, S. "Wavelet Tour of Signal Processing 3rd ed".
  6. D. Iatsenko, P. V. E. McClintock, A. Stefanovska. "On the extraction of instantaneous frequencies from ridges in time-frequency representations of signals".

License

ssqueezepy is MIT licensed, as found in the LICENSE file. Some source functions may be under other authorship/licenses; see NOTICE.txt.

Comments
  • Added time-frequency ridge extraction

    Added time-frequency ridge extraction

    Added folder/files:

    ssqueezepy/ridge_extraction.py test/ridge_extract_test.py test/ridge_extract_readme -->imgs test/ridge_extract_readme -->Readme

    enhancement 
    opened by DavidBondesson 17
  • Pick a license?

    Pick a license?

    Regarding:

    Licensing; unsure how to proceed here; original's says to "Redistributions in binary form must reproduce the above copyright notice" - but I'm not "redistributing" it, I'm distributing my rewriting of it

    The original code is published under a 2-clause BSD, so basically you are free to chose your license. It would be great if you can pick one, because code without a license on GitHub is a gray area (impossible to use / contribute) -- ideally something similar like BSD/MIT/Apache :wink:

    opened by bluenote10 13
  • GPU performance questions, `maprange`

    GPU performance questions, `maprange`

    Hi, it's me again

    Wanted to know if there is some example of maprange around so I can do some quick tests and study it from there ?

    On my tests, I have observed that if a sudden peak of energy while on a window, is much higher than the already "detected" clusters of energy, the first clusters detected of lower energy are marginalized, in the sense that they become dark ( they lose the color they had )

    What is a practical way, if there is any, to tune the scales so this effect does not happen or at least it's less obvious ?

    Thank you very much for this wonderful library

    question 
    opened by chromafunk 12
  • Oscillations in overtones

    Oscillations in overtones

    I have no idea if this is expected behavior in a SST, but at least to me it was a surprise. I noticed this at first when analyzing raw audio material, which revealed oscillations in overtones much more than what my hear would tell. But it is also possible to reproduce the effect synthetically:

    The following example shows a mix of sine waves with frequencies i * f_base. In each plot one more frequency is added; the left side shows the transform of the mix, the right side is the transform of only the last/added harmonic (just as a check how its transform looks in isolation):

    overtones_1 overtones_2 overtones_3 overtones_4 overtones_5 overtones_6 overtones_7 overtones_8

    Full reproduction code
    import numpy as np
    import matplotlib.pyplot as plt
    
    from ssqueezepy import synsq_cwt_fwd
    
    SAMPLE_RATE = 44100
    
    
    def sine(freq, num_samples, amp=1.0):
        ts = np.arange(num_samples) / SAMPLE_RATE
        wave = amp * np.sin(2.0 * np.pi * freq * ts)
        return wave
    
    
    def mix(*waves):
        return np.array(waves).sum(axis=0) / len(waves)
    
    
    def plot(Tx, ax):
        xs = np.arange(Tx.shape[1] + 1)
        ys = np.arange(Tx.shape[0] + 1)
        img = ax.pcolormesh(xs, ys, np.abs(Tx))
        plt.colorbar(img, ax=ax)
    
    
    def plot_overtone_series(num_overtones, freq=440.0, num_samples=SAMPLE_RATE // 4):
        waves = [
            sine(freq * i, num_samples)
            for i in range(1, num_overtones + 1)
        ]
    
        Tx_mix, *_ = synsq_cwt_fwd(mix(*waves), fs=1.0, nv=32)
        Tx_add, *_ = synsq_cwt_fwd(waves[-1], fs=1.0, nv=32)
    
        fig, axes = plt.subplots(1, 2, figsize=(18, 8))
        plot(Tx_mix, axes[0])
        plot(Tx_add, axes[1])
        fig.tight_layout()
        plt.savefig("/tmp/overtones_{}".format(num_overtones))
        plt.show()
    
    
    if __name__ == "__main__":
        for i in range(1, 9):
            plot_overtone_series(i)
    

    Observations:

    • Even though the sine waves have a constant instantaneous frequency, the SST plot shows relatively large oscillations -- each time in the highest harmonic. For instance here is a zoomed in version of the n = 4 case:

      image

      If I understand it correctly there are 32 "voices" per octave. The oscillation covers ~10 bins, which in musical terms would correspond to more than 3 semitones -- which seems a lot for a constant frequency signal.

    • The highest harmonic seems to cover up the harmonics in between. Perhaps this oscillation in the highest harmonic is actually an reassignment artifact of "stealing" energy from the lower harmonics?

    question 
    opened by bluenote10 12
  • Optionally output frequencies rather than scales (or provide a function to convert)

    Optionally output frequencies rather than scales (or provide a function to convert)

    In the Matlab cwt documentation, it gives this useful example (emphasis added by me):

    [wt,f] = cwt(___,fs) specifies the sampling frequency, fs, in Hz as a positive scalar. cwt uses fs to determine the scale-to-frequency conversions and returns the frequencies f in Hz. If you do not specify a sampling frequency, cwt returns f in cycles per sample. If the input x is complex, the scale-to-frequency conversions apply to both pages of wt. If x is a timetable, you cannot specify fs. fs is determined from the RowTimes of the timetable.

    In this example, if you provide the sampling frequency, then the frequencies are returned. It would be really useful if ssqueezepy could do this too (or at least provide a scale2frequency function to do the required conversion with the specified wavelet).

    opened by abudden 11
  • STFT: streaming peformance, output shapes

    STFT: streaming peformance, output shapes

    Hi, for my project https://github.com/falseywinchnet/streamcleaner I have previously been using the librosa stft. However, after i was able to make the ssqueezepy stft behave similar to it by appending 128 samples and then slicing all but the last 127 from the istft output, I switched over to ssqueezepy, believing that for my purposes https://github.com/librosa/librosa/issues/1279 this was an important caveat I should consider.

    However, librosa's stft only consumes ~2% CPU, and the ssqueezepy on a similar workload takes up 25%. I'm concerned this is due to my crude attempt at making the two behave similar, when doing this the STFT representation is MSE very close to librosas.

    Is there a proper way to make the stft of ssqueezepy generate a 257x376 complex representation from 48,000 samples and return 48,000 samples and perform with similar compute requirements?

    question 
    opened by falseywinchnet 8
  • Can I get 0.6.0 `ssq_cwt()` results using 0.6.1 `ssq_cwt`?

    Can I get 0.6.0 `ssq_cwt()` results using 0.6.1 `ssq_cwt`?

    I have used ssq_cwt() to get Tx on 0.6.0 version of ssqueezepy. I would like to use speed improvents of 0.6.1 and get the same Tx of 0.6.0 but using 0.6.1 version. Is it possible? How can it be done?

    Thanks in advance

    EDIT: I have reformulated the question

    opened by srvanrell 7
  • No option to specify a maximum frequency for stft, ssq_stft etc.

    No option to specify a maximum frequency for stft, ssq_stft etc.

    Currently the default for stft and ssq_stft is to return all scales up to the Nyquist frequency, but it would be helpful if there were a simple way to specify a maximum frequency or, better yet, a specific set of scales that should be queried. https://github.com/OverLordGoldDragon/ssqueezepy/blob/master/ssqueezepy/_ssq_stft.py#L241 Particularly in cases where you don't want to query everything up to the Nyquist frequency for efficiency purposes, it would be helpful to have this option.

    opened by scottfleming 7
  • ConceFT

    ConceFT

    Dear Eugene Brevdo and Gaurav Thakur,

    First of all, thank you very much for your python library ssqueezepy. it is very useful and is the first library that really implements very well the icwt in python (at least from my concern). I would like to know if It would be possible to improve the ssq_cwt method applying the ConceFT (Daubechies et al., 2016) algorithm. What is your opinion? is it worth it?

    If that were the case, what wavelet families could be applied? it could be applied an stack of synchrosqueezed scalograms generated by morlet families at different number of cycles or on the contrary morse wavelet have a clear advantage? For the STFT, what is the advantage of the orthonormal Hermite functions over the Discrete Prolate Spheroidal (Slepian) Sequences?

    Thank you very much in advance for your time and for your help

    Best Regards, Roberto Cabieces

    opened by rcabdia 6
  • 0.6.1 - can't input `ssq_freqs` into `ssq_stft`

    0.6.1 - can't input `ssq_freqs` into `ssq_stft`

    Hello,

    You may be aware of this, and I apologize if this is redundant or if I'm using the code improperly. I upgraded from ssqueezepy 0.6.0 to 0.6.1 today but am running into an issue with ssq_stft input parameter ssq_freqs. I am using a numpy ndarray of frequencies of interest, but in 0.6.1 I get the following error:

    File "/home/user/ssqtest.py", line 90, in SSQ_Tvst, Sxo, ssq_freqs, scaleS = ssq.ssq_stft(xo, ssq_freqs=fcm, fs=10, t=time)

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/ssqueezepy/_ssq_stft.py", line 112, in ssq_stft maprange='maximal', transform='stft')

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/ssqueezepy/ssqueezing.py", line 204, in ssqueeze _ssqueeze(Tx, w, Wx, dWx, *args)

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/ssqueezepy/ssqueezing.py", line 143, in _ssqueeze gamma, out=Tx, Sfs=Sfs)

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/ssqueezepy/algos.py", line 149, in ssqueeze_fast fn(*args, **params)

    TypeError: missing argument 'vmin'

    I did some poking around in algos.py and to me it looks like **params has a vlmin and dvl, rather than the vmin and dv required for the _ssq_stft function. However, if I simply change the input parameter names to match (aka vmin --> vlmin and dv --> dvl), I get the same error as above with the added errors:

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/numba/core/dispatcher.py", line 420, in _compile_for_args error_rewrite(e, 'typing')

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/numba/core/dispatcher.py", line 361, in error_rewrite raise e.with_traceback(None)

    TypingError: Cannot determine Numba type of <class 'numba.core.ir.UndefinedType'>

    I wasn't sure what to do with this error. Thanks!

    bug 
    opened by ARBolton96 5
  • Added setup.py

    Added setup.py

    So far the package isn't really pip installable due to lack of a setup.py. I thought I'd add something basic to get you started, including properly specifying dependencies.

    I guess few people in the Python community actually download releases from GitHub. So I guess you can safe you some time, and simply add a pip + git based installation instruction to the README like:

    pip install git+https://github.com/OverLordGoldDragon/ssqueezepy
    

    I could also help with publishing to PyPI in the long term.

    opened by bluenote10 5
  • How to use torch tensors already on GPU?

    How to use torch tensors already on GPU?

    Hi, Thanks for your wonderful work.

    Currently, only NumPy arrays are supported as input. Is there a way to use torch tensors already on the GPU?

    If not, if you give me some pointers, I can work on implementing that feature.

    Best regards Nabarun

    opened by naba89 7
  • Incorrect raising of ValueError(

    Incorrect raising of ValueError("must set `wavelet` if `scales` isn't array") line 220 cwt_utils,py

    Hi,

    I've encountered what i believe to be a bug in a call to ssqueezepy.ssqueeze to synchro-squeeze a continous wavelet transform. I'll try to explain the issue as best i can, because i can't send the exact implementation. This is also my first issue, to bear with me if i get anything wrong in the format or conventions :)

    I'm running ssqueezepy v0.6.3

    The call is of the form:

    Tx, fvec = sq.ssqueeze(
    			Mx, w=phase, ssq_freqs="log", wavelet=wavelet, scales="log", fs=sampleRate, maprange="maximal",
    			transform="cwt"
    		)
    

    where,

    wavelet = sq.Wavelet("morlet") is set before calling the method. and is of type(wavelet) = ssqueezepy.wavelets.Wavelet

    and Mx, phase are the normal matrices of the transform and phase produced by ssqueezepy.cwt()

    In 'squeezing.py/squeeze' after the call to _process_args is completed, the following if statement on line 168 calls the method process_scales if transform == 'cwt'. See below

        if transform == 'cwt':
            scales, cwt_scaletype, _, nv = process_scales(scales, N, get_params=True)
    

    However the call to process_scales does NOT pass the wavelet as an input argument (which it expects and sets to None if not passed). This results in the exception ValueError("must set `wavelet` if `scales` isn't array") being raised on line 220 in cwt_utils.pt/_process_args as called from process_scales.

    The argument wavelet passed to ssqueeze() was in fact set correctly.

    Hopefully that makes sense...

    Thanks, J.

    opened by jelsom 1
  • cc and cw in issq_cwt

    cc and cw in issq_cwt

    Suppose that we have a highly non-sinusoidal wave that is composed of multiple waves. Assuming that we know the frequency range that we are interested in, how should we define cc and cw in issq_cwt so the reconstructed signal only contains the components in he frequency range of interest. An illustrative example will be helpful.

    documentation question 
    opened by zeydabadi 3
  • `center_frequency` yields negative frequency for extreme scale

    `center_frequency` yields negative frequency for extreme scale

    The following example returns wc = -3.1354 but according to the specs it should be nonnegative, unless I'm misunderstanding something.

    from ssqueezepy import wavelets, Wavelet
    wavelet = Wavelet(("morlet", {"mu":14.0}))
    _ = wavelets.center_frequency(
        wavelet,  
        scale=np.array([1.0]),  
        kind='peak',
        N=1024,
        viz=1
    )
    
    bug 
    opened by scottfleming 1
  • Real-world tests

    Real-world tests

    Thread for sharing/discussing applications on real-world data. Feel free to open a separate Issue if needed.

    Comments occasionally cleared to keep focus on examples.

    opened by OverLordGoldDragon 7
Releases(0.6.3)
  • 0.6.3(Jan 23, 2022)

    FEATURES

    • freq_to_scale & scale_to_freq, experimental
    • Improved auto-scales
    • Optional nan_checks
    • Improved default gamma

    BREAKING

    • ssq_freqs now correctly maps frequencies to corresponding rows of Tx for ssq_cwt, no longer requiring [::-1]
    • scales returned as 1D
    • extract_ridges: ridge_f (formerly fridge) now returns scales rather than log(scales)
    • extract_ridges: renamed: fridge -> ridge_f, max_energy -> ridge_e

    FIXES

    • False warning for t & fs
    • Extended scope of astensor to scales, ssq_freqs
    • visuals: improve xticks & yticks handling

    MISC

    • Added citation; README changes; docs changes
    • experimental: remove phase_squeeze, phase_transform
    • visuals.imshow: default cmap='turbo'
    • visuals: added auto_xlims, squeeze
    Source code(tar.gz)
    Source code(zip)
  • 0.6.1b(Jul 7, 2021)

  • 0.6.1(May 5, 2021)

  • 0.6.0(Feb 19, 2021)

    A massive update.

    FEATURES (major)

    • Generalized Morse Wavelets (gmw, morsewave in _gmw.py)
    • Automatic time-frequency ridge extraction, ridge_extraction.py
    • Signal testing suite, _test_signals.py, and examples
    • Higher-order CWT (via GMWs); _cwt.cwt_higher_order
    • configs.ini, used to control function defaults globally
    • scales default improved to not over-represent low frequencies

    FEATURES (other)

    • visuals: added wavelet_filterbank, viz_cwt_higher_order, viz_gmw_orders (first callable as wavelet.viz('filterbank'))
    • visuals.wavelet_tf: autopicks scale for scale=None to give a nice visual for any wavelet
    • ssq_cwt & ssq_stft: added arg preserve_transform to (see docstrings)
    • padsignal: 2D input support, of form (n_signals, signal_length) (i.e. will pad every row vector).
    • cwt: support for padtype=None
    • maprange: tuple of floats now supported (help(_ssq_cwt.ssq_cwt))
    • Wavelet.info() and @propertys of Wavelet revamped for generality; added @propertys: wc_ct, scalec_ct.
    • wavelets.center_frequency: added kind='peak-ct'
    • utils.find_max_scale now simpler and more effective, guaranteeing complete spectral coverage for low frequencies

    BREAKING

    • utils.py -> utils/*: common.py, cwt_utils.py, stft_utils.py
    • The default wavelet has been changed from 'morlet' to 'gmw'
    • Changed Morlet's default parameters to closely match GMW's defaults per time & frequency resolution
    • ssq_cwt(mapkind=) default change: 'maximal' to 'peak'
    • scales default change: implicit preset from 'maximal' to 'minimal' for low scales, 'maximal' for high
    • ssq_cwt return order change: Tx, ssq_freqs, Wx, scales, w to Tx, Wx, ssq_freqs, scales, w, dWx (additionally returning dWx)
    • ssq_stft return order change: Tx, ssq_freqs, Sx, Sfs, dSx, w to Tx, Sx, ssq_freqs, Sfs, w, dSx
    • ssqueezing & ssq_cwt: renamed mapkind to maprange
    • difftype: 'direct' -> 'trig'
    • _infer_scaletype -> infer_scaletype
    • _integrate_analytic -> integrate_analytic
    • find_max_scale -> find_max_scale_alt, but find_max_scale is still (but a different) function

    MISC

    • phase_cwt: takes abs(w) instead of zeroing negatives
    • wavelet in icwt and issq_cwt now defaults to the default wavelet
    • cwt: added args order, average
    • stft & ssq_stft: added t argument
    • stft default window increased frequency resolution
    • visuals.imshow(): cmap now defaults to 'jet' instead of 'bone' for abs=True
    • Added Examples to README, adjusted Minimal Example
    • NOTICE.txt: added jLab
    • setup.py: added short & long description, copyright, keywords

    FIXES

    • visuals.wavelet_heatmap: string scales now functional
    • visuals: w overreached into negative frequencies for odd N in wavelet_tf, wavelet_tf_anim, & wavelet_heatmap
    • icwt: padtype now functional

    FILE CHANGES

    • ssqueezepy/ added: _gmw.py, _test_signals.py, ridge_extraction.py, configs.ini, README.md
    • ssqueezepy/ added utils/, split utils.py into common.py, cwt_utils.py, stft_utils.py, __init__.py, & moved to utils/.
    • tests/ added: gmw_test.py, test_signals_test.py, ridge_extraction_test.py
    • examples/ added: extracting_ridges.py, scales_selection.py, ridge_extract_readme/: README.md, imgs/*
    • Created MANIFEST.in
    Source code(tar.gz)
    Source code(zip)
  • 0.5.5(Jan 14, 2021)

    FEATURES:

    • stft, istft, ssq_stft, and issq_stft implemented and validated
    • Added to utils.py: buffer, unbuffer, window_norm, window_resolution, and window_area
    • Replaced numba.njit with numba.jit(nopython=True, cache=True), accelerating recomputing

    BREAKING:

    • cwt() no longer returns x_mean
    • padsignal now only returns padded input by default; get_params=True for old behavior
    • Moved methods: phase_cwt & phase_cwt_num from ssqueezing to _ssq_cwt
    • In future release: return order of cwt and stft will be changed to have Wx, dWx and Sx, dSx, and ssq_cwt and ssq_stft to have Tx, Wx and Tx, Sx

    MISC:

    • wavelet positional argument in cwt is now a keyword argument that defaults to 'morlet'
    • Support for padsignal(padtype='wrap')
    • Added CHANGELOG.md
    • Docstring, comment cleanups
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Dec 19, 2020)

    Synchrosqueezing arrives to Python:

    • Continuous Wavelet Transform, forward & inverse, beating PyWavelets' & scipy's
    • CWT-based synchrosqueezing, forward & inverse
    • Wavelet visualizations
    • Docs/comments explaining relevant concepts
    • Several important fixes and performance optimizations relative to original MATLAB repository
    • Greater flexibility and improved edge-case handling relative to latest MATLAB implementations

    Planned for v0.6.0:

    • Short-time Fourier Transform, forward & inverse
    • STFT-based synchrosqueezing, forward & inverse
    • Generalized Morse Wavelets

    Existing users: please review code anew; too many changes to note between Prerelease 2 and v0.5.0. This changes onward, with every change explicitly tracked.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.0rc2(Nov 8, 2020)

  • 0.5.0rc(Nov 5, 2020)

    At last, SYNCRHOSQUEEZING is here.

    Relative to MATLAB repo:

    • Several important fixes
    • Possible performance improvements**
    • Formula clarity in code and comments; correct quantity placement prioritized over saving code space
    • Forward CWT and synchrosqueezing fully* fixed & validated
    • Inverse synchrosqueezing fully* fixed & validated
    • Inverse CWT and helper methods ported, partly fixed & validated
    • Added linear scale support to CWT
    • Added support for custom scales
    • Replaced opts with Pythonic argument handling

    *: not every argument config works. I tested every option, and marked in comments what fails to deliver "good" results (marked with # !!! and sometimes # TODO). Unless explicitly stating otherwise, there may be nothing to 'fix' - simply the method is flawed, or thrives in specific settings. **: I initially didn't realize the MATLAB code was jit-compiled; will run tests to compare speed & memory use.

    To-do for first release:

    • Complete docstrings
    • Add examples
    • Revamp README
    • Set license

    Note that majority of code organization is subject to change by v0.6.0. This includes args placement and defaults, variable, function, and module names, and whether wavelets are functions or class instances.


    Not reviewed/validated: synsq_stft.py, stft_transforms.py. I don't plan on reviewing these; others are welcome to, and I'll validate changes.

    Source code(tar.gz)
    Source code(zip)
  • 0.05(Oct 11, 2020)

    Nothing new, just creating tag for sharing persistent URL's.

    To any watchers, I'm actively working on the repo, and CWT should be done soon.

    Source code(tar.gz)
    Source code(zip)
Owner
John Muradeli
John Muradeli
Canim1 - Simple python tool to search for packages without m1 wheels in poetry lockfiles

canim1 Usage Clone the repo. Run poetry install. Then you can use the tool: ❯ po

Korijn van Golen 1 Jan 25, 2022
Ant Colony Optimization for Traveling Salesman Problem

tsp-aco Ant Colony Optimization for Traveling Salesman Problem Dependencies Python 3.8 tqdm numpy matplotlib To run the solver run main.py from the p

Baha Eren YALDIZ 4 Feb 03, 2022
Criando um jogo de naves espaciais com Pygame. Para iniciantes em Python

Curso de Programação de Jogos com Pygame Criando um jogo de naves espaciais com Pygame. Para iniciantes em Python Pré-requisitos Antes de começar este

Flávio Codeço Coelho 33 Dec 02, 2022
Amazon SageMaker Delta Sharing Examples

This repository contains examples and related resources showing you how to preprocess, train, and serve your models using Amazon SageMaker with data fetched from Delta Lake.

Eitan Sela 5 May 02, 2022
A Python package that provides astronomical constants.

AstroConst A Python package that provides astronomical constants. The code is being developed by Marc van der Sluys of the department of Astrophysics

Marc van der Sluys 1 Jan 10, 2022
Simple web application, which has a single endpoint, dedicated to annotation parsing and convertion.

Simple web application, which has a single endpoint, dedicated to annotation parsing and conversion.

Pavel Paranin 1 Nov 01, 2021
Easy, clean, reliable Python 2/3 compatibility

Overview: Easy, clean, reliable Python 2/3 compatibility python-future is the missing compatibility layer between Python 2 and Python 3. It allows you

Python Charmers 1.2k Jan 08, 2023
Python Script to add OpenGapps, Magisk, libhoudini translation library and libndk translation library to waydroid !

Waydroid Extras Script Script to add gapps and other stuff to waydroid ! Installation/Usage "lzip" is required for this script to work, install it usi

Casu Al Snek 331 Jan 02, 2023
Launcher program to select which version of the Q-Sys software to launch.

QSC-QSYS Launcher Launcher program to select which version of the Q-Sys software to launch. Instructions To use the application simply save the "Q-Sys

Zach Lisko 2 Sep 28, 2022
Context-free grammar to Sublime-syntax file

Generate a sublime-syntax file from a non-left-recursive, follow-determined, context-free grammar

Haggai Nuchi 8 Nov 17, 2022
Hashcrack - A non-object oriented open source, Software for Windows/Linux made in Python 3

Multi Force This project is a non-object oriented open source, Software for Wind

Radiationbolt 3 Jan 02, 2023
Age of Empires II recorded game parsing and summarization in Python 3.

mgz Age of Empires II recorded game parsing and summarization in Python 3. Supported Versions Age of Kings (.mgl) The Conquerors (.mgx) Userpatch 1.4

148 Dec 11, 2022
🙌Kart of 210+ projects based on machine learning, deep learning, computer vision, natural language processing and all. Show your support by ✨ this repository.

ML-ProjectKart 📌 Repository This kart showcases the finest collection of all projects based on machine learning, deep learning, computer vision, natu

Prathima Kadari 203 Dec 28, 2022
🤞 Website-Survival-Detection

- 🤞 Website-Survival-Detection It can help you to detect the survival status of the website in batches and return the status code! - 📜 Instructions

B0kd1 4 Nov 14, 2022
Cloud Native sample microservices showcasing Full Stack Observability using AppDynamics and ThousandEyes

Cloud Native Sample Bookinfo App Observability Bookinfo is a sample application composed of four Microservices written in different languages.

Cisco DevNet 13 Jul 21, 2022
Plugin to generate BOM + CPL files for JLCPCB

KiCAD JLCPCB tools Plugin to generate all files necessary for JLCPCB board fabrication and assembly Gerber files Excellon files BOM file CPL file Furt

bouni 566 Dec 29, 2022
An ultra fast cross-platform multiple screenshots module in pure Python using ctypes.

Python MSS from mss import mss # The simplest use, save a screen shot of the 1st monitor with mss() as sct: sct.shot() An ultra fast cross-platfo

Mickaël Schoentgen 799 Dec 30, 2022
Pyrmanent - Make all your classes permanent in a flash 💾

Pyrmanent A base class to make your Python classes permanent in a flash. Features Easy to use. Great compatibility. No database needed. Ask for new fe

Sergio Abad 4 Jan 07, 2022
Kellogg bad | Union good | Support strike funds

KelloggBot Credit to SeanDaBlack for the basis of the script. req.py is selenium python bot. sc.js is a the base of the ios shortcut [COMING SOON] Set

407 Nov 17, 2022
A discord group chat creator just made it because i saw people selling this stuff for like up to 40 bucks

gccreator some discord group chat tools just made it because i saw people selling this stuff for like up to 40 bucks (im currently working on a faster

baum1810 6 Oct 03, 2022