├── .coveragerc ├── .git-blame-ignore-revs ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── emscripten.yml │ ├── lint.yml │ ├── tests.yml │ └── wheel_tests_and_release.yml ├── .gitignore ├── .mailmap ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── CONTRIBUTING.rst ├── LICENSE ├── LICENSES_bundled.txt ├── README.rst ├── appveyor.yml ├── benchmarks ├── README.rst ├── asv.conf.json └── benchmarks │ ├── __init__.py │ ├── cwt_benchmarks.py │ ├── dwt_benchmarks.py │ └── swt_benchmarks.py ├── community_guidelines.rst ├── demo ├── _dwt_decompose.c ├── batch_processing.py ├── benchmark.py ├── cwt_analysis.py ├── dwt2_dwtn_image.py ├── dwt_signal_decomposition.py ├── dwt_swt_show_coeffs.py ├── fswavedecn.py ├── fswavedecn_mondrian.py ├── image_blender.py ├── mra2d.py ├── mra_vs_swt.py ├── plot_demo_signals.py ├── plot_wavelets.py ├── plot_wavelets_pyqtgraph.py ├── swt2.py ├── swt_variance.py ├── waveinfo.py ├── wp_2d.py ├── wp_nd.py ├── wp_scalogram.py └── wp_visualize_coeffs_distribution.py ├── doc ├── Makefile ├── doc2html.bat ├── make.bat ├── paper │ ├── paper.bib │ └── paper.md ├── release │ ├── 0.3.0-notes.rst │ ├── 0.4.0-notes.rst │ ├── 0.5.0-notes.rst │ ├── 0.5.1-notes.rst │ ├── 0.5.2-notes.rst │ ├── 1.0.0-notes.rst │ ├── 1.0.1-notes.rst │ ├── 1.0.2-notes.rst │ ├── 1.0.3-notes.rst │ ├── 1.1.0-notes.rst │ ├── 1.1.1-notes.rst │ ├── 1.2.0-notes.rst │ ├── 1.3.0-notes.rst │ ├── 1.4.0-notes.rst │ ├── 1.4.1-notes.rst │ ├── 1.5.0-notes.rst │ ├── 1.6.0-notes.rst │ ├── 1.7.0-notes.rst │ └── 1.8.0-notes.rst └── source │ ├── _static │ ├── comments.png │ ├── favicon.ico │ ├── myst-nb.css │ ├── page_edit.png │ ├── pywavelets.css │ └── wave.png │ ├── common_refs.rst │ ├── conf.py │ ├── contributing.rst │ ├── dev │ ├── building_extension.rst │ ├── conduct │ │ ├── code_of_conduct.rst │ │ └── report_handling_manual.rst │ ├── how_to_build_the_docs.rst │ ├── how_to_release.rst │ ├── index.rst │ ├── installing_build_dependencies.rst │ ├── preparing_linux_build_environment.rst │ ├── preparing_windows_build_environment.rst │ └── testing.rst │ ├── index.rst │ ├── install.rst │ ├── pyplots │ ├── camera_approx_detail.py │ ├── cwt_scaling_demo.py │ ├── cwt_wavelet_frequency_bandwidth_demo.py │ ├── plot_2d_bases.py │ ├── plot_boundary_modes.py │ ├── plot_cwt_scaleogram.py │ ├── plot_mallat_2d.py │ ├── plot_thresholds.py │ └── plot_wavelets.py │ ├── ref │ ├── 2d-decompositions-overview.rst │ ├── 2d-dwt-and-idwt.rst │ ├── cwt.rst │ ├── dwt-coefficient-handling.rst │ ├── dwt-discrete-wavelet-transform.rst │ ├── idwt-inverse-discrete-wavelet-transform.rst │ ├── index.rst │ ├── iswt-inverse-stationary-wavelet-transform.rst │ ├── mra.rst │ ├── nd-dwt-and-idwt.rst │ ├── other-functions.rst │ ├── signal-extension-modes.rst │ ├── swt-stationary-wavelet-transform.rst │ ├── thresholding-functions.rst │ ├── wavelet-packets.rst │ └── wavelets.rst │ ├── regression │ ├── README.md │ ├── dwt-idwt.md │ ├── gotchas.md │ ├── header.md │ ├── index.rst │ ├── modes.md │ ├── multilevel.md │ ├── wavelet.md │ ├── wp.md │ └── wp2d.md │ ├── release.0.3.0.rst │ ├── release.0.4.0.rst │ ├── release.0.5.0.rst │ ├── release.0.5.1.rst │ ├── release.0.5.2.rst │ ├── release.1.0.0.rst │ ├── release.1.0.1.rst │ ├── release.1.0.2.rst │ ├── release.1.0.3.rst │ ├── release.1.1.0.rst │ ├── release.1.1.1.rst │ ├── release.1.2.0.rst │ ├── release.1.3.0.rst │ ├── release.1.4.0.rst │ ├── release.1.4.1.rst │ ├── release.1.5.0.rst │ ├── release.1.6.0.rst │ ├── release.1.7.0.rst │ ├── release.1.8.0.rst │ ├── releasenotes.rst │ ├── substitutions.rst │ └── try_examples.json ├── meson.build ├── pyproject.toml ├── pytest.ini ├── pywt ├── __init__.py ├── _c99_config.py.in ├── _cwt.py ├── _doc_utils.py ├── _dwt.py ├── _extensions │ ├── __init__.py │ ├── _cwt.pxd │ ├── _cwt.pyx │ ├── _dwt.pxd │ ├── _dwt.pyx │ ├── _pywt.pxd │ ├── _pywt.pyx │ ├── _swt.pyx │ ├── c │ │ ├── common.c │ │ ├── common.h │ │ ├── convolution.c │ │ ├── convolution.h │ │ ├── convolution.template.c │ │ ├── convolution.template.h │ │ ├── cwt.c │ │ ├── cwt.h │ │ ├── cwt.template.c │ │ ├── cwt.template.h │ │ ├── templating.h │ │ ├── wavelets.c │ │ ├── wavelets.h │ │ ├── wavelets_coeffs.h │ │ ├── wavelets_coeffs.template.h │ │ ├── wt.c │ │ ├── wt.h │ │ ├── wt.template.c │ │ └── wt.template.h │ ├── c_wt.pxd │ ├── common.pxd │ ├── config.pxi.in │ ├── meson.build │ ├── wavelet.pxd │ └── wavelets_list.pxi ├── _functions.py ├── _mra.py ├── _multidim.py ├── _multilevel.py ├── _pytest.py ├── _pytesttester.py ├── _swt.py ├── _thresholding.py ├── _utils.py ├── _wavelet_packets.py ├── conftest.py ├── data │ ├── __init__.py │ ├── _readers.py │ ├── _wavelab_signals.py │ ├── aero.npz │ ├── ascent.npz │ ├── camera.npz │ ├── ecg.npz │ └── sst_nino3.npz ├── meson.build └── tests │ ├── data │ ├── cwt_matlabR2015b_result.npz │ ├── dwt_matlabR2012a_result.npz │ ├── generate_matlab_data.py │ ├── generate_matlab_data_cwt.py │ └── wavelab_test_signals.npz │ ├── test__pywt.py │ ├── test_concurrent.py │ ├── test_cwt_wavelets.py │ ├── test_data.py │ ├── test_deprecations.py │ ├── test_doc.py │ ├── test_dwt_idwt.py │ ├── test_functions.py │ ├── test_matlab_compatibility.py │ ├── test_matlab_compatibility_cwt.py │ ├── test_modes.py │ ├── test_mra.py │ ├── test_multidim.py │ ├── test_multilevel.py │ ├── test_perfect_reconstruction.py │ ├── test_swt.py │ ├── test_thresholding.py │ ├── test_wavelet.py │ ├── test_wp.py │ ├── test_wp2d.py │ └── test_wpnd.py ├── tox.ini └── util ├── authors.py ├── create_dat.py ├── gh_lists.py ├── readthedocs └── requirements.txt └── version_utils.py /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | # Not sure what stringsource is 4 | omit = 5 | */version.py 6 | */pywt/tests/* 7 | */pywt/_doc_utils.py* 8 | */pywt/_pytesttester.py* 9 | */pywt/_pytest.py* 10 | *.pxd 11 | stringsource 12 | plugins = Cython.Coverage 13 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # .git-blame-ignore-revs 2 | # Applied codespell to the codebase 3 | 5ce73c91800829950474aaa4f4036b2a589a2418 4 | d531f668d60503d55387d7d0ffae4afd199c5f80 5 | bb1d1888fd63381ce35805e0cb3623a8bd47163c 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | tidelift: "pypi/PyWavelets" 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Keep GitHub Actions up to date with GitHub's Dependabot... 2 | # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot 3 | # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem 4 | version: 2 5 | updates: 6 | - package-ecosystem: github-actions 7 | directory: / 8 | groups: 9 | github-actions: 10 | patterns: 11 | - "*" # Group all Actions updates into a single larger pull request 12 | schedule: 13 | interval: monthly 14 | -------------------------------------------------------------------------------- /.github/workflows/emscripten.yml: -------------------------------------------------------------------------------- 1 | name: Test Pyodide build 2 | 3 | on: 4 | push: 5 | branches: 6 | # Runs on every merge to main to upload .dev0 wheels to anaconda.org 7 | - main 8 | - v1.** 9 | pull_request: 10 | branches: 11 | - main 12 | - v1.** 13 | # Make it possible to upload wheels manually if needed 14 | workflow_dispatch: 15 | inputs: 16 | push_wheels: 17 | description: > 18 | 'Push wheels to Anaconda if "true". Default is "false". Warning: this will overwrite existing wheels.' 19 | required: false 20 | default: "false" 21 | # Upload wheels to anaconda.org on a schedule 22 | schedule: 23 | # Run at 0300 hours on days 3 and 17 of the month 24 | - cron: "0 3 3,17 * *" 25 | 26 | env: 27 | FORCE_COLOR: 3 28 | 29 | jobs: 30 | build_wasm_emscripten: 31 | name: Build PyWavelets for Pyodide 32 | runs-on: ubuntu-22.04 33 | # Comment out the following line to test changes on a fork 34 | if: github.repository == 'PyWavelets/pywt' 35 | steps: 36 | - name: Check out repository 37 | uses: actions/checkout@v4 38 | 39 | - name: Build and test PyWavelets 40 | uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3 41 | env: 42 | CIBW_PLATFORM: pyodide 43 | CIBW_TEST_REQUIRES: pytest matplotlib 44 | CIBW_TEST_COMMAND: python -c "import pywt; pywt.test(extra_argv=['-m', 'not slow'])" 45 | 46 | # https://anaconda.org/scientific-python-nightly-wheels/pywavelets 47 | # WARNING: this job will overwrite existing wheels. 48 | - name: Push wheels to Anaconda PyPI index 49 | if: >- 50 | (github.repository == 'PyWavelets/pywt') && 51 | (github.event_name == 'push' && github.ref == 'refs/heads/main') || 52 | (github.event_name == 'workflow_dispatch' && github.event.inputs.push_wheels == 'true') || 53 | (github.event_name == 'schedule') 54 | uses: scientific-python/upload-nightly-action@b36e8c0c10dbcfd2e05bf95f17ef8c14fd708dbf # v0.6.2 55 | with: 56 | artifacts_path: wheelhouse/ 57 | anaconda_nightly_upload_token: ${{ secrets.ANACONDA_ORG_UPLOAD_TOKEN }} 58 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Style checks 2 | 3 | on: 4 | push: 5 | branches: 6 | - v1.** 7 | pull_request: 8 | branches: 9 | - main 10 | - v1.** 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | format: 18 | runs-on: ubuntu-latest 19 | strategy: 20 | matrix: 21 | python-version: ["3.11"] 22 | 23 | steps: 24 | - uses: actions/checkout@v4 25 | 26 | - name: Set up Python ${{ matrix.python-version }} 27 | uses: actions/setup-python@v5 28 | with: 29 | python-version: ${{ matrix.python-version }} 30 | 31 | - name: Install packages 32 | run: | 33 | pip install --upgrade pip 34 | pip install pre-commit 35 | pip list 36 | 37 | - name: Lint 38 | run: pre-commit run --all-files --show-diff-on-failure --color always 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.py[co] 3 | *.pyd 4 | *.so 5 | .DS_Store 6 | .pytest_cache/ 7 | 8 | # Packages 9 | *.egg 10 | *.egg-info 11 | dist 12 | build 13 | _build 14 | .installed.cfg 15 | 16 | # Installer logs 17 | pip-log.txt 18 | 19 | # Unit test / coverage reports 20 | .coverage 21 | .tox 22 | 23 | # Sphinx documentation 24 | doc/_build/ 25 | doc/build/ 26 | .jupyterlite.doit.db 27 | /doc/jupyter_execute/ 28 | doc/source/regression/*.ipynb 29 | 30 | # Editors 31 | .idea 32 | .project 33 | .pydevproject 34 | .settings 35 | 36 | # Project working files 37 | # Expanded Cython 38 | pywt/_extensions/*.[ch] 39 | pywt/_extensions/_c99_config.py 40 | pywt/_extensions/config.pxi 41 | cythonize.dat 42 | pywt/version.py 43 | build.log 44 | 45 | # Virtual environments 46 | .env/ 47 | env/ 48 | venv/ 49 | .venv/ 50 | 51 | # asv files 52 | asv/env 53 | asv/html 54 | asv/pywt 55 | asv/results 56 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Aaron O'Leary 2 | Alexandre Saint asnt 3 | Arthur Roullier <36152494+0-tree@users.noreply.github.com> 0-tree <36152494+0-tree@users.noreply.github.com> 4 | Daniel M. Pelt Daniel M Pelt 5 | Gregory R. Lee Gregory R. Lee 6 | Gregory R. Lee Gregory Lee 7 | Helder Oliveira Helder 8 | Holger Nahrstaedt Holger Nahrstaedt 9 | Kai Wohlfahrt 10 | Kai Wohlfahrt 11 | Kai Wohlfahrt Kai 12 | Pavle Boškoski pavleb 13 | Ralf Gommers 14 | Sylvain Lannuzel SylvainLan 15 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # pre-commit install 2 | 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: f71fa2c1f9cf5cb705f73dffe4b21f7c61470ba9 # v4.4.0 6 | hooks: 7 | - id: trailing-whitespace 8 | - id: end-of-file-fixer 9 | - id: debug-statements 10 | - id: check-ast 11 | - id: mixed-line-ending 12 | - id: check-yaml 13 | args: [--allow-multiple-documents] 14 | - id: check-added-large-files 15 | 16 | - repo: https://github.com/pre-commit/mirrors-prettier 17 | rev: fc260393cc4ec09f8fc0a5ba4437f481c8b55dc1 # frozen: v3.0.3 18 | hooks: 19 | - id: prettier 20 | files: \.(md|rst|toml|yml|yaml) 21 | args: [--prose-wrap=preserve] 22 | 23 | - repo: https://github.com/charliermarsh/ruff-pre-commit 24 | rev: 0431f238e57190b696d22a57a87eb3d0b22c0036 # frozen: v0.3.1 25 | hooks: 26 | - id: ruff 27 | args: [--fix, --exit-non-zero-on-fix] 28 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | build: 3 | os: "ubuntu-22.04" 4 | tools: 5 | python: "3.11" 6 | 7 | python: 8 | install: 9 | - requirements: util/readthedocs/requirements.txt 10 | - method: pip 11 | path: . 12 | 13 | sphinx: 14 | configuration: doc/source/conf.py 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | ================================== 2 | PyWavelets pull request guidelines 3 | ================================== 4 | 5 | Pull requests are always welcome, and the PyWavelets community appreciates 6 | any help you give. 7 | 8 | When submitting a pull request, we ask you check the following: 9 | 10 | 1. **Unit tests**, **documentation**, and **code style** are in order. 11 | See below for details. 12 | 13 | It's also OK to submit work in progress if you're unsure of what 14 | this exactly means, in which case you'll likely be asked to make 15 | some further changes. 16 | 17 | 2. The contributed code will be **licensed under PyWavelets's license**, 18 | (the MIT license, https://github.com/PyWavelets/pywt/blob/main/LICENSE). 19 | If you did not write the code yourself, you ensure the existing 20 | license is compatible and include the license information in the 21 | contributed files, or obtain a permission from the original 22 | author to relicense the contributed code. 23 | 24 | 25 | Coding guidelines 26 | ================= 27 | 28 | 1. Unit tests 29 | In principle you should aim to create unit tests that exercise all the code 30 | that you are adding. This gives some degree of confidence that your code 31 | runs correctly, also on Python versions and hardware or OSes that you don't 32 | have available yourself. An extensive description of how to write unit 33 | tests is given in the NumPy `testing guidelines`_. 34 | 35 | 2. Documentation 36 | Clear and complete documentation is essential in order for users to be able 37 | to find and understand the code. Documentation for individual functions 38 | and classes -- which includes at least a basic description, type and 39 | meaning of all parameters and returns values, and usage examples in 40 | `doctest`_ format -- is put in docstrings. Those docstrings can be read 41 | within the interpreter, and are compiled into a reference guide in html and 42 | pdf format. Higher-level documentation for key (areas of) functionality is 43 | provided in tutorial format and/or in module docstrings. A guide on how to 44 | write documentation is given in the `numpydoc docstring guide`_. 45 | 46 | Looking for `how to build the docs`_? 47 | 48 | 3. Code style 49 | Uniformity of style in which code is written is important to others trying 50 | to understand the code. PyWavelets follows the standard Python guidelines 51 | for code style, `PEP8`_. In order to check that your code conforms to 52 | PEP8, you can use the `pep8 package`_ style checker. Most IDEs and text 53 | editors have settings that can help you follow PEP8, for example by 54 | translating tabs by four spaces. Using `pyflakes`_ to check your code is 55 | also a good idea. 56 | 57 | 58 | .. _PEP8: http://www.python.org/dev/peps/pep-0008/ 59 | 60 | .. _pep8 package: http://pypi.python.org/pypi/pep8 61 | 62 | .. _numpydoc docstring guide: https://numpydoc.readthedocs.io/en/latest/ 63 | 64 | .. _doctest: http://www.doughellmann.com/PyMOTW/doctest/ 65 | 66 | .. _pyflakes: http://pypi.python.org/pypi/pyflakes 67 | 68 | .. _testing guidelines: https://github.com/numpy/numpy/blob/main/doc/TESTS.rst.txt 69 | 70 | .. _how to build the docs: ./doc/source/dev/how_to_build_the_docs.rst 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2012 Filip Wasilewski 2 | Copyright (c) 2012-2020 The PyWavelets Developers 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8 | of the Software, and to permit persons to whom the Software is furnished to do 9 | so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /LICENSES_bundled.txt: -------------------------------------------------------------------------------- 1 | The PyWavelets repository and source distributions bundle some code that is 2 | adapted from compatibly licensed projects. We list these here. 3 | 4 | Name: NumPy 5 | Files: pywt/_pytesttester.py 6 | License: 3-clause BSD 7 | 8 | Name: SciPy 9 | Files: meson.build, util/* 10 | License: 3-clause BSD 11 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # https://ci.appveyor.com/project/PyWavelets/pywt 2 | image: Visual Studio 2022 3 | 4 | # Ensure we don't default to MSBuild 5 | build: off 6 | 7 | environment: 8 | matrix: 9 | - arch: x64 10 | PY_PYTHON: 3.11 11 | - arch: x86 12 | PY_PYTHON: 3.11-32 13 | - arch: x64 14 | PY_PYTHON: 3.13 15 | 16 | # From https://mesonbuild.com/Continuous-Integration.html#appveyor-for-windows 17 | install: 18 | - "py -VV" # Also, `py --list` 19 | - "py -m pip install --upgrade pip build" 20 | - "py -m pip install numpy --cache-dir c:\\tmp\\pip-cache" 21 | - "py -m pip install --only-binary :all: Cython pytest matplotlib --cache-dir c:\\tmp\\pip-cache" 22 | 23 | test_script: 24 | - cmd: call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" %arch% 25 | - "py -m pip install . -v --config-settings=setup-args=--vsenv" 26 | - "cd demo" 27 | - "py -m pytest --pyargs pywt" 28 | - "cd .." 29 | 30 | artifacts: 31 | # Archive the generated wheel package in the ci.appveyor.com build report. 32 | - path: dist\* 33 | 34 | cache: 35 | # Cache can be manually cleared like this: 36 | # https://github.com/appveyor/ci/issues/207 37 | - "c:\\tmp\\pip-cache" 38 | -------------------------------------------------------------------------------- /benchmarks/README.rst: -------------------------------------------------------------------------------- 1 | .. -*- rst -*- 2 | 3 | ===================== 4 | PyWavelets benchmarks 5 | ===================== 6 | 7 | Benchmarking PyWavelets with Airspeed Velocity. 8 | 9 | 10 | Usage 11 | ----- 12 | 13 | Airspeed Velocity manages building and Python virtualenvs (or conda 14 | environments) by itself, unless told otherwise. To run the benchmarks, you do 15 | not need to install a development version of PyWavelets to your current Python environment. 16 | 17 | First navigate to the benchmarks subfolder of the repository. 18 | 19 | cd benchmarks 20 | 21 | To run all benchmarks against the current build of PyWavelets:: 22 | 23 | asv run --python=same --quick 24 | 25 | The following notation (tag followed by ^!) can be used to run only on a 26 | specific tag or commit. (In this case, a python version for the virtualenv 27 | must be provided) 28 | 29 | asv run --python=3.5 --quick v0.4.0^! 30 | 31 | To record the results use: 32 | 33 | asv publish 34 | 35 | And to see the results via a web browser, run: 36 | 37 | asv preview 38 | 39 | More on how to use ``asv`` can be found in `ASV documentation`_ 40 | Command-line help is available as usual via ``asv --help`` and 41 | ``asv run --help``. 42 | 43 | .. _ASV documentation: https://asv.readthedocs.io/ 44 | 45 | 46 | Writing benchmarks 47 | ------------------ 48 | 49 | See `ASV documentation`_ for basics on how to write benchmarks. 50 | 51 | Some things to consider: 52 | 53 | - The benchmark files need to be importable when benchmarking old versions 54 | of PyWavelets. So if anything from PyWavelets is imported at the top level, 55 | it should be done as: 56 | 57 | try: 58 | from pywt import cwt 59 | except ImportError: 60 | pass 61 | 62 | The benchmarks themselves don't need any guarding against missing features 63 | --- only the top-level imports. 64 | 65 | To allow tests of newer functions to be marked as "n/a" (not available) 66 | rather than "failed" for older versions, the setup method itself can raise a NotImplemented error. See the following example for the CWT: 67 | 68 | try: 69 | from pywt import cwt 70 | except ImportError: 71 | raise NotImplementedError("cwt not available") 72 | 73 | - Try to keep the runtime of the benchmark reasonable. 74 | 75 | - Use ASV's ``time_`` methods for benchmarking times rather than cooking up 76 | time measurements via ``time.clock``, even if it requires some juggling when 77 | writing the benchmark. 78 | 79 | - Preparing arrays etc. should generally be put in the ``setup`` method rather 80 | than the ``time_`` methods, to avoid counting preparation time together with 81 | the time of the benchmarked operation. 82 | -------------------------------------------------------------------------------- /benchmarks/asv.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | // The version of the config file format. Do not change, unless 3 | // you know what you are doing. 4 | "version": 1, 5 | 6 | // The name of the project being benchmarked 7 | "project": "pywt", 8 | 9 | // The project's homepage 10 | "project_url": "https://github.com/PyWavelets/pywt/", 11 | 12 | // The URL or local path of the source code repository for the 13 | // project being benchmarked 14 | //"repo": "https://github.com/PyWavelets/pywt.git", 15 | "repo": "..", 16 | 17 | // List of branches to benchmark. If not provided, defaults to "main" 18 | // (for git) or "tip" (for mercurial). 19 | "branches": ["main"], // for git 20 | // "branches": ["tip"], // for mercurial 21 | 22 | // The DVCS being used. If not set, it will be automatically 23 | // determined from "repo" by looking at the protocol in the URL 24 | // (if remote), or by looking for special directories, such as 25 | // ".git" (if local). 26 | "dvcs": "git", 27 | 28 | // The tool to use to create environments. May be "conda", 29 | // "virtualenv" or other value depending on the plugins in use. 30 | // If missing or the empty string, the tool will be automatically 31 | // determined by looking for tools on the PATH environment 32 | // variable. 33 | // "environment_type": "virtualenv", 34 | 35 | // the base URL to show a commit for the project. 36 | "show_commit_url": "http://github.com/PyWavelets/pywt/commit/", 37 | 38 | // The Pythons you'd like to test against. If not provided, defaults 39 | // to the current version of Python used to run `asv`. 40 | // "pythons": ["2.7", "3.4"], 41 | 42 | // The matrix of dependencies to test. Each key is the name of a 43 | // package (in PyPI) and the values are version numbers. An empty 44 | // list indicates to just test against the default (latest) 45 | // version. 46 | "matrix": { 47 | "numpy": [], 48 | "Cython": [], 49 | }, 50 | 51 | // The directory (relative to the current directory) that benchmarks are 52 | // stored in. If not provided, defaults to "benchmarks" 53 | // "benchmark_dir": "benchmarks", 54 | 55 | // The directory (relative to the current directory) to cache the Python 56 | // environments in. If not provided, defaults to "env" 57 | // "env_dir": "env", 58 | 59 | 60 | // The directory (relative to the current directory) that raw benchmark 61 | // results are stored in. If not provided, defaults to "results". 62 | // "results_dir": "results", 63 | 64 | // The directory (relative to the current directory) that the html tree 65 | // should be written to. If not provided, defaults to "html". 66 | // "html_dir": "html", 67 | 68 | // The number of characters to retain in the commit hashes. 69 | // "hash_length": 8, 70 | 71 | // `asv` will cache wheels of the recent builds in each 72 | // environment, making them faster to install next time. This is 73 | // number of builds to keep, per environment. 74 | // "wheel_cache_size": 0 75 | } 76 | -------------------------------------------------------------------------------- /benchmarks/benchmarks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/benchmarks/benchmarks/__init__.py -------------------------------------------------------------------------------- /benchmarks/benchmarks/cwt_benchmarks.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | import pywt 4 | 5 | 6 | class CwtTimeSuiteBase: 7 | """ 8 | Set-up for CWT timing. 9 | """ 10 | params = ([32, 128, 512, 2048], 11 | ['cmor', 'cgau4', 'fbsp', 'gaus4', 'mexh', 'morl', 'shan'], 12 | [16, 64, 256], 13 | [np.float32, np.float64], 14 | ['conv', 'fft'], 15 | ) 16 | param_names = ('n', 'wavelet', 'max_scale', 'dtype', 'method') 17 | 18 | def setup(self, n, wavelet, max_scale, dtype, method): 19 | try: 20 | from pywt import cwt 21 | except ImportError: 22 | raise NotImplementedError("cwt not available") 23 | self.data = np.ones(n, dtype=dtype) 24 | self.batch_data = np.ones((5, n), dtype=dtype) 25 | self.scales = np.arange(1, max_scale + 1) 26 | 27 | 28 | class CwtTimeSuite(CwtTimeSuiteBase): 29 | def time_cwt(self, n, wavelet, max_scale, dtype, method): 30 | try: 31 | pywt.cwt(self.data, self.scales, wavelet, method=method) 32 | except TypeError: 33 | # older PyWavelets does not support use of the method argument 34 | if method == 'fft': 35 | raise NotImplementedError( 36 | "fft-based convolution not available.") 37 | pywt.cwt(self.data, self.scales, wavelet) 38 | 39 | def time_cwt_batch(self, n, wavelet, max_scale, dtype, method): 40 | try: 41 | pywt.cwt(self.batch_data, self.scales, wavelet, method=method, 42 | axis=-1) 43 | except TypeError: 44 | # older PyWavelets does not support the axis argument 45 | raise NotImplementedError( 46 | "axis argument not available.") 47 | -------------------------------------------------------------------------------- /benchmarks/benchmarks/swt_benchmarks.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | import pywt 4 | 5 | 6 | class SwtTimeSuiteBase: 7 | """ 8 | Set-up for (I)SWT timing. 9 | """ 10 | params = ([16, 64, 256, 1024, 4096], 11 | ['haar', 'db4', 'sym8'],) 12 | param_names = ('n', 'wavelet') 13 | 14 | def setup(self, n, wavelet): 15 | self.data = np.ones(n, dtype='float') 16 | 17 | 18 | class SwtTimeSuite(SwtTimeSuiteBase): 19 | def time_swt(self, n, wavelet): 20 | pywt.swt(self.data, wavelet) 21 | 22 | 23 | class IswtTimeSuite(SwtTimeSuiteBase): 24 | def setup(self, n, wavelet): 25 | try: 26 | from pywt import iswt 27 | except ImportError: 28 | raise NotImplementedError("iswt not available") 29 | super().setup(n, wavelet) 30 | self.coeffs = pywt.swt(self.data, wavelet) 31 | 32 | def time_iswt(self, n, wavelet): 33 | pywt.iswt(self.coeffs, wavelet) 34 | 35 | 36 | class Swt2TimeSuiteBase: 37 | """ 38 | Set-up for (I)SWT2 timing. 39 | """ 40 | params = ([16, 64, 256], 41 | ['haar', 'db4'],) 42 | param_names = ('n', 'wavelet') 43 | 44 | def setup(self, n, wavelet): 45 | try: 46 | from pywt import swt2 47 | except ImportError: 48 | raise NotImplementedError("swt2 not available") 49 | self.data = np.ones((n, n), dtype='float') 50 | self.level = pywt.swt_max_level(n) 51 | 52 | 53 | class Swt2TimeSuite(Swt2TimeSuiteBase): 54 | def time_swt2(self, n, wavelet): 55 | pywt.swt2(self.data, wavelet, self.level) 56 | 57 | 58 | class Iswt2TimeSuite(Swt2TimeSuiteBase): 59 | def setup(self, n, wavelet): 60 | try: 61 | from pywt import iswt2 62 | except ImportError: 63 | raise NotImplementedError("iswt2 not available") 64 | super().setup(n, wavelet) 65 | self.data = pywt.swt2(self.data, wavelet, self.level) 66 | 67 | def time_iswt2(self, n, wavelet): 68 | pywt.iswt2(self.data, wavelet) 69 | 70 | 71 | class SwtnTimeSuiteBase: 72 | """ 73 | Set-up for (I)SWTN timing. 74 | """ 75 | params = ([1, 2, 3], 76 | [16, 64], 77 | ['haar', 'db4'], 78 | [np.float32, np.float64, np.complex64]) 79 | param_names = ('D', 'n', 'wavelet', 'dtype') 80 | 81 | def setup(self, D, n, wavelet, dtype): 82 | try: 83 | from pywt import swtn 84 | except ImportError: 85 | raise NotImplementedError("swtn not available") 86 | self.data = np.ones((n,) * D, dtype=dtype) 87 | self.level = 4 # run 4 levels in all cases 88 | 89 | 90 | class SwtnTimeSuite(SwtnTimeSuiteBase): 91 | def time_swtn(self, D, n, wavelet, dtype): 92 | pywt.swtn(self.data, wavelet, self.level) 93 | 94 | 95 | class IswtnTimeSuite(SwtnTimeSuiteBase): 96 | def setup(self, D, n, wavelet, dtype): 97 | try: 98 | from pywt import iswtn 99 | except ImportError: 100 | raise NotImplementedError("iswtn not available") 101 | super().setup(D, n, wavelet, dtype) 102 | self.data = pywt.swtn(self.data, wavelet, self.level) 103 | 104 | def time_iswtn(self, D, n, wavelet, dtype): 105 | pywt.iswtn(self.data, wavelet) 106 | -------------------------------------------------------------------------------- /community_guidelines.rst: -------------------------------------------------------------------------------- 1 | Community Guidelines 2 | ==================== 3 | 4 | or How We Work (Together) 5 | ------------------------- 6 | 7 | PyWavelets has adopted a set of community guidelines in common with the 8 | scikit-image project. 9 | 10 | We welcome each and every contributor to PyWavelets. Our aim is 11 | enthusiastic and productive collaboration, to build an excellent 12 | software library, and to have a ton of fun doing it. We encourage one 13 | another to be gentle in criticism of others' work, humble in 14 | acknowledging our own mistakes, and generous in our praise. 15 | 16 | If you ever feel like you are not being treated as well as you should, please 17 | get in touch with one of the project leads (our email addresses are available 18 | through our GitHub profiles). We are committed to making this community a 19 | safe and welcome space. 20 | 21 | You can learn more about contributing to PyWavelets at 22 | https://pywavelets.readthedocs.io/en/latest/contributing.html 23 | -------------------------------------------------------------------------------- /demo/_dwt_decompose.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Note: this currently doesn't get installed. There's also no way to query 3 | * the location of wt.h. Conclusion: there is no C API. 4 | */ 5 | 6 | #include 7 | 8 | #include "wt.h" 9 | 10 | int main(){ 11 | 12 | // Using C API to decompose 1D signal. 13 | // Results equivalent to pywt.dwt([1,2,3,4,5,6,7,8], 'db2', 'zpd'). 14 | // Compile: gcc -I../src dwt_decompose.c ../src/wt.c ../src/wavelets.c ../src/common.c ../src/convolution.c 15 | 16 | Wavelet *w = wavelet('d', 2); 17 | MODE mode = MODE_ZEROPAD; 18 | 19 | int i; 20 | float input[] = {1,2,3,4,5,6,7,8,9}; 21 | float *cA, *cD; 22 | pywt_index_t input_len, output_len; 23 | 24 | input_len = sizeof input / sizeof input[0]; 25 | output_len = dwt_buffer_length(input_len, w->dec_len, mode); 26 | 27 | cA = wtcalloc(output_len, sizeof(float)); 28 | cD = wtcalloc(output_len, sizeof(float)); 29 | 30 | printf("Wavelet: %s %d\n\n", w->family_name, w->vanishing_moments_psi); 31 | 32 | float_dec_a(input, input_len, w, cA, output_len, mode); 33 | float_dec_d(input, input_len, w, cD, output_len, mode); 34 | 35 | for(i=0; i' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " pickle to make pickle files" 22 | @echo " json to make JSON files" 23 | @echo " htmlhelp to make HTML files and a HTML help project" 24 | @echo " qthelp to make HTML files and a qthelp project" 25 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 26 | @echo " changes to make an overview of all changed/added/deprecated items" 27 | @echo " linkcheck to check all external links for integrity" 28 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 29 | 30 | clean: 31 | -rm -rf $(BUILDDIR)/* 32 | 33 | html: 34 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 35 | @echo 36 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 37 | 38 | dirhtml: 39 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 40 | @echo 41 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 42 | 43 | pickle: 44 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 45 | @echo 46 | @echo "Build finished; now you can process the pickle files." 47 | 48 | json: 49 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 50 | @echo 51 | @echo "Build finished; now you can process the JSON files." 52 | 53 | htmlhelp: 54 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 55 | @echo 56 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 57 | ".hhp project file in $(BUILDDIR)/htmlhelp." 58 | 59 | qthelp: 60 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 61 | @echo 62 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 63 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 64 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PyWavelets.qhcp" 65 | @echo "To view the help file:" 66 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PyWavelets.qhc" 67 | 68 | latex: 69 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 70 | @echo 71 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 72 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ 73 | "run these through (pdf)latex." 74 | 75 | changes: 76 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 77 | @echo 78 | @echo "The overview file is in $(BUILDDIR)/changes." 79 | 80 | linkcheck: 81 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 82 | @echo 83 | @echo "Link check complete; look for any errors in the above output " \ 84 | "or in $(BUILDDIR)/linkcheck/output.txt." 85 | 86 | doctest: 87 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 88 | @echo "Testing of doctests in the sources finished, look at the " \ 89 | "results in $(BUILDDIR)/doctest/output.txt." 90 | -------------------------------------------------------------------------------- /doc/doc2html.bat: -------------------------------------------------------------------------------- 1 | sphinx-build -b html -a -E source build\html 2 | -------------------------------------------------------------------------------- /doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | set SPHINXBUILD=sphinx-build 6 | set BUILDDIR=build 7 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source 8 | if NOT "%PAPER%" == "" ( 9 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 10 | ) 11 | 12 | if "%1" == "" goto help 13 | 14 | if "%1" == "help" ( 15 | :help 16 | echo.Please use `make ^` where ^ is one of 17 | echo. html to make standalone HTML files 18 | echo. dirhtml to make HTML files named index.html in directories 19 | echo. pickle to make pickle files 20 | echo. json to make JSON files 21 | echo. htmlhelp to make HTML files and a HTML help project 22 | echo. qthelp to make HTML files and a qthelp project 23 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 24 | echo. changes to make an overview over all changed/added/deprecated items 25 | echo. linkcheck to check all external links for integrity 26 | echo. doctest to run all doctests embedded in the documentation if enabled 27 | goto end 28 | ) 29 | 30 | if "%1" == "clean" ( 31 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 32 | del /q /s %BUILDDIR%\* 33 | goto end 34 | ) 35 | 36 | if "%1" == "html" ( 37 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 38 | echo. 39 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 40 | goto end 41 | ) 42 | 43 | if "%1" == "dirhtml" ( 44 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 45 | echo. 46 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 47 | goto end 48 | ) 49 | 50 | if "%1" == "pickle" ( 51 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 52 | echo. 53 | echo.Build finished; now you can process the pickle files. 54 | goto end 55 | ) 56 | 57 | if "%1" == "json" ( 58 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 59 | echo. 60 | echo.Build finished; now you can process the JSON files. 61 | goto end 62 | ) 63 | 64 | if "%1" == "htmlhelp" ( 65 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 66 | echo. 67 | echo.Build finished; now you can run HTML Help Workshop with the ^ 68 | .hhp project file in %BUILDDIR%/htmlhelp. 69 | goto end 70 | ) 71 | 72 | if "%1" == "qthelp" ( 73 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 74 | echo. 75 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 76 | .qhcp project file in %BUILDDIR%/qthelp, like this: 77 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PyWavelets.qhcp 78 | echo.To view the help file: 79 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PyWavelets.ghc 80 | goto end 81 | ) 82 | 83 | if "%1" == "latex" ( 84 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 85 | echo. 86 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 87 | goto end 88 | ) 89 | 90 | if "%1" == "changes" ( 91 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 92 | echo. 93 | echo.The overview file is in %BUILDDIR%/changes. 94 | goto end 95 | ) 96 | 97 | if "%1" == "linkcheck" ( 98 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 99 | echo. 100 | echo.Link check complete; look for any errors in the above output ^ 101 | or in %BUILDDIR%/linkcheck/output.txt. 102 | goto end 103 | ) 104 | 105 | if "%1" == "doctest" ( 106 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 107 | echo. 108 | echo.Testing of doctests in the sources finished, look at the ^ 109 | results in %BUILDDIR%/doctest/output.txt. 110 | goto end 111 | ) 112 | 113 | :end 114 | -------------------------------------------------------------------------------- /doc/release/0.5.1-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 0.5.1 Release Notes 3 | ============================== 4 | 5 | PyWavelets 0.5.1 is a bug-fix release with no new features compared to 0.5.0 6 | 7 | 8 | Bugs Fixed 9 | ========== 10 | 11 | In release 0.5.0 the wrong edge mode was used for the following three 12 | deprecated modes: ``ppd``, ``sp1``, and ``per``. All deprecated edge mode 13 | names are now correctly converted to the corresponding new names. 14 | 15 | One-dimensional discrete wavelet transforms did not properly respect the 16 | ``axis`` argument for complex-valued data. Prior to this release, the last 17 | axis was always transformed for arrays with complex dtype. This fix affects 18 | ``dwt``, ``idwt``, ``wavedec``, ``waverec``. 19 | 20 | Authors 21 | ======= 22 | 23 | * Gregory R. Lee 24 | 25 | Issues closed for v0.5.1 26 | ------------------------ 27 | 28 | - `#245 `__: Keyword "per" for dwt extension mode 29 | 30 | Pull requests for v0.5.1 31 | ------------------------ 32 | 33 | - `#244 `__: FIX: dwt, idwt with complex data now pass axis argument properly 34 | - `#246 `__: fix bug in deprecated mode name conversion 35 | -------------------------------------------------------------------------------- /doc/release/0.5.2-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 0.5.2 Release Notes 3 | ============================== 4 | 5 | PyWavelets 0.5.2 is a bug-fix release with no new features compared to 0.5.1. 6 | 7 | 8 | Bugs Fixed 9 | ========== 10 | 11 | The ``pywt.data.nino`` data reader is now compatible with numpy 1.12. (#273) 12 | 13 | The ``wp_scalogram.py`` demo is now compatible with matplotlib 2.0. (#276) 14 | 15 | Fixed a sporadic segmentation fault affecting stationary wavelet transforms of 16 | multi-dimensional data. (#289) 17 | 18 | ``idwtn`` now treats coefficients set to None to be treated as zeros (#291). 19 | This makes the behavior consistent with its docstring as well as idwt2. 20 | Previously this raised an error. 21 | 22 | The tests are now included when installing from wheels or when running 23 | ``python setup.py install``. (#292) 24 | 25 | A bug leading to a potential ``RuntimeError`` was fixed in ``waverec``. 26 | This bug only affected transforms where the data was >1D and the transformed 27 | axis was not the first axis of the array. (#294). 28 | 29 | Authors 30 | ======= 31 | 32 | * Ralf Gommers 33 | * Gregory R. Lee 34 | 35 | Issues closed for v0.5.2 36 | ------------------------ 37 | 38 | - `#280 `__: No tests found from installed version 39 | - `#288 `__: RuntimeErrors and segfaults from swt2() in threaded environments 40 | - `#290 `__: idwtn should treat coefficients set to None as zeros 41 | - `#293 `__: bug in waverec of n-dimensional data when axis != 0 42 | 43 | Pull requests for v0.5.2 44 | ------------------------ 45 | 46 | - `#273 `__: fix non-integer index error 47 | - `#276 `__: update wp_scalogram demo work with matplotlib 2.0 48 | - `#289 `__: fix memory leak in swt_axis 49 | - `#291 `__: idwtn should allow coefficients to be set as None 50 | - `#292 `__: MAINT: ensure tests are included in wheels 51 | - `#294 `__: FIX: shape adjustment in waverec should not assume a transform along … 52 | - `#295 `__: MAINT: fix readthedocs build issue, update numpy version specifier 53 | -------------------------------------------------------------------------------- /doc/release/1.0.1-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.0.1 Release Notes 3 | ============================== 4 | 5 | PyWavelets 1.0.1 is a bug-fix release with no new features compared to 1.0.0. 6 | 7 | 8 | Bugs Fixed 9 | ========== 10 | 11 | Key-based assignment of coefficients to a ``FswavedecnResult`` object (i.e. via 12 | its __setitem__ method) has been fixed. 13 | 14 | The order that the individual subband coefficients were stacked by the 15 | function ``pywt.ravel_coeffs`` is now guaranteed to be consistent across all 16 | supported Python versions. Explicit alphabetic ordering of subband coefficient 17 | names is used for consistent ordering regardless of Python version. 18 | 19 | Authors 20 | ======= 21 | 22 | * Gregory R. Lee 23 | 24 | Issues closed for v1.0.1 25 | ------------------------ 26 | 27 | - `#426 `__: Ordering of the coefficients stacked in pywt.ravel_coeffs can vary across Python versions 28 | - `#425 `__: error when trying to assign modified coefficients to a FswavedecnResults object 29 | 30 | Pull requests for v1.0.1 31 | ------------------------ 32 | 33 | - `#423 `__: fix bug in FswavedecnResult.__setitem__ and improve docstrings 34 | - `#427 `__: fix: enforce consistent coefficient order for ravel_coeffs 35 | -------------------------------------------------------------------------------- /doc/release/1.0.2-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.0.2 Release Notes 3 | ============================== 4 | 5 | PyWavelets 1.0.2 is a bug-fix and maintenance release with no new features 6 | compared to 1.0.1. 7 | 8 | Bugs Fixed 9 | ========== 10 | 11 | A bug in `iswtn` when using some combinations of user-specified axes was fixed. 12 | 13 | A potential error related to coefficient shape mismatch during WaveletPacket 14 | or WaveletPacket2D reconstruction was fixed. 15 | 16 | Other Changes 17 | ============= 18 | 19 | A deprecated import of ``Iterable`` was fixed. 20 | 21 | The spelling of "Garrote" was fixed in the wavelet thresholding documentation. 22 | For backwards compatibility with 1.0.0, the incorrect ("garotte") 23 | spelling is also accepted for the ``mode`` parameter of ``pywt.threshold``. 24 | 25 | The spelling of "supported" was fixed in one of the ValueError messages that 26 | can be returned by ``pywt.cwt``. 27 | 28 | Cython language compatibility has been pinned to ``language_level = '2'``. This 29 | is in contrast to the `master` branch which is now using 30 | ``language_level = '3'``. To support this, the minimum supported Cython version 31 | has been raised to 0.23.5. 32 | 33 | Authors 34 | ======= 35 | 36 | Four authors contributed PRs for the 1.0.2 release. 37 | 38 | Thomas A. Caswell 39 | Corey Goldberg 40 | Gregory R. Lee 41 | Lokesh Ravindranathan 42 | 43 | Thanks also goes to Ralf Gommers as a reviewer of most of these. 44 | 45 | Issues closed for v1.0.2 46 | ------------------------ 47 | 48 | - `#447 `__: Issue using pywt.WaveletPacket2D 49 | - `#449 `__: Coefficients arrays must have the same dtype error in iswt function 50 | - `#460 `__: iswtn error when using axes and excluded dim is doesn't comply to the level 51 | 52 | Pull requests for v1.0.2 53 | ------------------------ 54 | 55 | - `#454 `__: BLD: 1.0.x pin cython language level to '2' 56 | - `#455 `__: backport of #448 (fix coefficient shape mismatch in WaveletPacket reconstruction) 57 | - `#456 `__: MAINT: 1.0.x: Spelling correction 58 | - `#457 `__: MAINT: 1.0.x Fix spelling of "Garrote" 59 | - `#458 `__: MAINT: 1.0.x Fix deprecated import for Iterable 60 | - `#464 `__: backport of #448 (fix coefficient shape mismatch in WaveletPacket reconstruction) 61 | - `#465 `__: backport of gh-462 (iswtn axis fix) 62 | - `#469 `__: MAINT 1.0.x backport #452 (bump minimum supported Cython version) 63 | 64 | The backports listed above correspond to the following PRs from the master branch 65 | 66 | - `#436 `__: Fix deprecated import for Iterable 67 | - `#438 `__: Fix spelling of "Garrote" 68 | - `#446 `__: Spelling correction 69 | - `#448 `__: Properly trim wavelet packet node coefficients during reconstruction 70 | - `#450 `__: handle mixed dtype coefficients correctly across inverse transforms 71 | - `#452 `__: bump minimum supported Cython version 72 | - `#462 `__: fix bug in iswtn for data of arbitrary shape when using user-specified axes 73 | -------------------------------------------------------------------------------- /doc/release/1.0.3-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.0.3 Release Notes 3 | ============================== 4 | 5 | PyWavelets 1.0.3 is functionally equivalent to the 1.0.2 release. It was made 6 | to add the add an archive of the JOSS paper to the 1.0.x branch and serve as a 7 | reference corresponding to the version of the software reviewed that was peer 8 | reviewed. 9 | -------------------------------------------------------------------------------- /doc/release/1.1.1-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.1.1 Release Notes 3 | ============================== 4 | 5 | .. contents:: 6 | 7 | This release is identical in functionality to 1.1.0. 8 | 9 | It fixes setup.py to prevent pip from trying to install from PyPI for 10 | Python < 3.5. 11 | -------------------------------------------------------------------------------- /doc/release/1.3.0-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.3.0 Release Notes 3 | ============================== 4 | 5 | .. contents:: 6 | 7 | We are very pleased to announce the release of PyWavelets 1.3. This release 8 | is functionally the same as 1.2.0, but we have updated the set of binary wheels 9 | provided. Specifically we have added `aarch64` wheels for Python 3.7 that were 10 | missing in 1.2.0 and have updated the versions of `manylinux` used for the 11 | linux wheels in a manner consistent with NumPy and SciPy. We have also dropped 12 | `musllinux` wheels which were present for some architectures in 1.2.0. We may 13 | add them again in the future if they are adopted by NumPy and there is a 14 | demand for this architecture. 15 | 16 | Authors 17 | ======= 18 | 19 | * Gregory R. Lee 20 | * Naoto Ishikawa + 21 | 22 | Reviewers 23 | ========= 24 | 25 | * Ralf Gommers 26 | 27 | A total of 3 people contributed to this release. 28 | People with a "+" by their names contributed a patch for the first time. 29 | 30 | 31 | Issues closed for v1.3 32 | ----------------------- 33 | 34 | * `#625 `__: No aarch64 wheels for python3.7 35 | 36 | 37 | Pull requests for v1.3 38 | ---------------------- 39 | 40 | * `#613 `__: DOC: Update the developer docs on how to make a release 41 | * `#614 `__: MAINT: Fix bugs in automated wheel deployment 42 | * `#620 `__: DOC: Fix level of headers 43 | * `#627 `__: Add aarch64 wheels for Python 3.7 and fix manylinux versions 44 | -------------------------------------------------------------------------------- /doc/release/1.4.0-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.4.0 Release Notes 3 | ============================== 4 | 5 | .. contents:: 6 | 7 | We are very pleased to announce the release of PyWavelets 1.4. This release 8 | is a minor update to 1.3.0. It adds wheels for Python 3.11 and drops support 9 | for Python 3.7. 10 | 11 | There is one new utility function, `pywt.frequency2scale`, that can be used to 12 | determine CWT scale factors corresponding to a given (normalized) frequency. 13 | It is the inverse of the existing `pywt.scale2frequency`. 14 | 15 | A detailed change log is provided below. 16 | 17 | Authors 18 | ======= 19 | 20 | * Christian Clauss + 21 | * Gregory R. Lee 22 | * Orion Poplawski + 23 | * Trevor Clark + 24 | 25 | Reviewers 26 | ========= 27 | 28 | * Gregory R. Lee 29 | * Ralf Gommers 30 | 31 | A total of 5 people contributed to this release. 32 | People with a "+" by their names contributed a patch for the first time. 33 | 34 | 35 | Issues closed for v1.4 36 | ----------------------- 37 | 38 | * `#640 `__: test_accuracy_precomputed_cwt fails on aarch64 39 | 40 | Pull requests for v1.4 41 | ---------------------- 42 | 43 | * `#629 `__: Fix twine-based uploads to PyPI 44 | * `#635 `__: added a frequency2scale function as the dual to scale2frequency 45 | * `#641 `__: test_cwt_batch can have small differences on some arches (resolves #640) 46 | * `#647 `__: provide setuptools upper bound for robustness against future changes 47 | * `#648 `__: Run GitHub actions test cases using Python 3.11 48 | * `#649 `__: Update wheel building workflow to include Python 3.11 49 | * `#650 `__: Upgrade GitHub Actions 50 | * `#651 `__: Fix typos discovered by codespell 51 | * `#654 `__: Remove string_types, which is a remnant of Python 2 support 52 | -------------------------------------------------------------------------------- /doc/release/1.4.1-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.4.1 Release Notes 3 | ============================== 4 | 5 | .. contents:: 6 | 7 | This patch release updates setup.py to use `python_requires>=3.8` and adds 3.11 to the trove classifiers. 8 | -------------------------------------------------------------------------------- /doc/release/1.5.0-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.5.0 Release Notes 3 | ============================== 4 | 5 | .. contents:: 6 | 7 | We are very pleased to announce the release of PyWavelets 1.5.0. This release 8 | is a minor update to 1.4.x. It adds support for Python 3.12 and drops support 9 | for Python 3.8. It also adds support for Cython 3.0. 10 | 11 | PyWavelets now uses Meson as its build system, and meson-python 12 | as the build backend. This requires no changes from users, a 13 | ``pip install pywavelets`` will now use ``meson-python`` under 14 | the hood. 15 | 16 | 17 | Authors 18 | ======= 19 | 20 | * Christian Clauss 21 | * Ralf Gommers 22 | * Gregory R. Lee 23 | * Jarrod Millman + 24 | * Evans Doe Ocansey + 25 | * Ahmet Can Solak + 26 | * Stefan van der Walt + 27 | 28 | A total of 7 people contributed to this release. 29 | People with a "+" by their names contributed a patch for the first time. 30 | This list of names is automatically generated, and may not be fully complete. 31 | 32 | 33 | Issues closed for v1.5 34 | ----------------------- 35 | 36 | * `#621 `__: distutils was deprecated in Python 3.10 37 | 38 | 39 | Pull requests for v1.5 40 | ---------------------- 41 | 42 | * `#667 `__: BLD: switch to using Meson as the build system for PyWavelets 43 | * `#669 `__: DOC: update docs for setup.py removal, and fix ReadTheDocs build 44 | * `#679 `__: MAINT: fix warnings emitted by loading npy/npz data files 45 | * `#680 `__: CI: limit contourpy to <1.1, to avoid building win32 from source 46 | * `#681 `__: Update dependencies per SPEC 0 47 | * `#682 `__: Remove old travis references 48 | * `#683 `__: Test on Python 3.12 49 | * `#685 `__: Add spin as developer UI to meson 50 | * `#688 `__: AppVeyor: Upgrade to Visual Studio 2022 and use python-launcher 51 | * `#690 `__: Build Python 3.12 wheels 52 | * `#691 `__: Test on final releases on Python 3.12 53 | -------------------------------------------------------------------------------- /doc/release/1.6.0-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.6.0 Release Notes 3 | ============================== 4 | 5 | We are very pleased to announce the release of PyWavelets 1.6.0. This release 6 | is a minor update to 1.6.x. It adds support for NumPy 2.0, which also keeping 7 | compatibility with NumPy 1.22-1.26. It requires Cython 3.0; support for 0.29.x 8 | is dropped. 9 | 10 | Other noteworthy improvements: 11 | 12 | - Improved documentation for ``pywt.cwt`` 13 | - The documentation was migrated to the PyData Sphinx Theme and the content 14 | organization improved 15 | - Releases on PyPI now include wheels for ``musllinux`` (x86-64 and aarch64) 16 | - The test suite is now passing and tested in CI with Emscripten/Pyodide 17 | - Nightly builds will be available at 18 | https://anaconda.org/scientific-python-nightly-wheels/PyWavelets/ going 19 | forward 20 | 21 | 22 | Authors 23 | ======= 24 | 25 | * Christian Clauss 26 | * Ralf Gommers 27 | * Agriya Khetarpal + 28 | * Jarrod Millman 29 | * Cora Schneck + 30 | * Daniel Stephan + 31 | 32 | A total of 6 people contributed to this release. 33 | People with a "+" by their names contributed a patch for the first time. 34 | This list of names is automatically generated, and may not be fully complete. 35 | 36 | 37 | Issues closed for v1.6.0 38 | ------------------------ 39 | 40 | * `#623 `__: pywavelets fails to install on Alpine Linux v3.15 ARM 41 | * `#676 `__: Enhanced documentation for CWT 42 | * `#712 `__: Upload dev builds for all supported platforms to anaconda.org 43 | * `#718 `__: Publish musllinux wheels again, and natively compile macOS arm64... 44 | 45 | 46 | Pull requests for v1.6.0 47 | ------------------------ 48 | 49 | * `#678 `__: Additional documentation for cwt (issue #676) 50 | * `#684 `__: Rename master branch to main 51 | * `#687 `__: Add linter 52 | * `#701 `__: Build and test PyWavelets Pyodide wheels in CI 53 | * `#703 `__: MAINT: add input validation to \`scales\` argument to \`cwt\` 54 | * `#704 `__: DOC: Migrate to \`pydata-sphinx-theme\` 55 | * `#708 `__: Keep GitHub Actions up to date with GitHub's Dependabot 56 | * `#709 `__: mymindstorm/setup-emscripten --> mymindstorm/setup-emsdk 57 | * `#711 `__: CI: tweaks to CI job triggers and names 58 | * `#713 `__: Bump the github-actions group with 5 updates 59 | * `#714 `__: Upload dev wheels to Anaconda.org + revamp wheels publishing... 60 | * `#715 `__: BLD: update build and runtime dependencies for numpy 2.0 61 | * `#716 `__: TST/CI: mark some tests as slow and avoid running them in wheel... 62 | * `#717 `__: CI: fix patterns for artifact downloads in Anaconda nightly wheels... 63 | * `#719 `__: CI: Build \`musllinux\` aarch64 and x86_64 wheels, and native... 64 | * `#720 `__: BLD: avoid warnings from including deprecated NumPy API 65 | * `#721 `__: Bump the github-actions group with 1 update 66 | * `#723 `__: MAINT: use \`numpy-config\` and fix support for numpy 2.0 67 | -------------------------------------------------------------------------------- /doc/release/1.7.0-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.7.0 Release Notes 3 | ============================== 4 | 5 | We are very pleased to announce the release of PyWavelets 1.7.0. This release 6 | is a minor update to 1.6.x. It adds support for Python 3.13, including for 7 | free-threaded CPython. The supported NumPy and Cython versions are unchanged 8 | from 1.6.x. 9 | 10 | Note that building from source with free-threaded CPython requires a recent 11 | development version of Cython (>=3.1.0a0). 12 | 13 | Other noteworthy improvements: 14 | 15 | - Most examples in the documentation are now interactive, powered by 16 | JupyterLite and Pyodide. 17 | - The ``musllinux`` wheels were upgraded from ``musllinux_1_1`` to 18 | ``musllinux_1_2`` (for both x86-64 and aarch64). 19 | 20 | 21 | Authors 22 | ======= 23 | 24 | * Evgeni Burovski + 25 | * Ralf Gommers 26 | * Agriya Khetarpal 27 | * Jarrod Millman 28 | * Edgar Andrés Margffoy Tuay + 29 | 30 | A total of 5 people contributed to this release. 31 | People with a "+" by their names contributed a patch for the first time. 32 | This list of names is automatically generated, and may not be fully complete. 33 | 34 | 35 | Issues closed for v1.7.0 36 | ------------------------ 37 | 38 | * `#742 `__: Start building WASM wheels against newer Pyodide (version 0.26.0) 39 | 40 | 41 | Pull requests for v1.7.0 42 | ------------------------ 43 | 44 | * `#702 `__: BLD: Test editable installations for PyWavelets in CI 45 | * `#722 `__: Drop support for older dependencies (see SPEC 0) 46 | * `#726 `__: MAINT: set version to 1.7.0.dev0 47 | * `#734 `__: DOC: Fix incorrect indentations for a few interactive examples 48 | * `#737 `__: DOC, DEP: Remove custom \`:button_text\` directive option, bump... 49 | * `#739 `__: DEP: Remove \`docutils\` upper-pin, bump \`sphinx\` 50 | * `#743 `__: FIX, CI: Temporarily disable \`pytest\`'s caching in Pyodide... 51 | * `#744 `__: CI, BLD: Use \`cibuildwheel\` to build and test Pyodide/WASM... 52 | * `#745 `__: Bump the github-actions group with 2 updates 53 | * `#747 `__: Use \`scipy-doctest\` instead of \`refguide-check\` 54 | * `#748 `__: DOC: easy_install is no longer a thing 55 | * `#753 `__: CI: Add CI to test on free-threaded Python 56 | * `#756 `__: CI: Add CI to release nightly wheels against free-threaded Python... 57 | * `#757 `__: CI: add macOS nightly wheels for free-threaded CPython 58 | * `#759 `__: Bump softprops/action-gh-release from 2.0.5 to 2.0.6 in the github-actions... 59 | * `#761 `__: BLD: mark extension modules as compatible to run without the... 60 | * `#762 `__: BLD: fix a few install tags for generated .py files 61 | * `#763 `__: Bump the github-actions group with 4 updates 62 | * `#764 `__: BLD/CI: support Python 3.13 (cp313/cp313t) in pyproject.toml... 63 | -------------------------------------------------------------------------------- /doc/release/1.8.0-notes.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | PyWavelets 1.8.0 Release Notes 3 | ============================== 4 | 5 | We are very pleased to announce the release of PyWavelets 1.8.0. This release 6 | is a minor update to 1.7.x. It adds support for free-threaded Python 3.13 on 7 | Windows. The supported Python, NumPy and Cython versions are unchanged from 8 | 1.7.x. 9 | 10 | Note that building from source with free-threaded CPython requires a recent 11 | development version of Cython (>=3.1.0a0). 12 | 13 | 14 | Authors 15 | ======= 16 | 17 | * Ralf Gommers 18 | * Marco Meyer-Conde + 19 | * Omer Sayli + 20 | 21 | A total of 3 people contributed to this release. 22 | People with a "+" by their names contributed a patch for the first time. 23 | 24 | 25 | Issues closed for v1.8.0 26 | ------------------------ 27 | 28 | * `#780 `__: Pip install PyWavelets does not work with GIL disabled version... 29 | 30 | 31 | Pull requests for v1.8.0 32 | ------------------------ 33 | 34 | * `#766 `__: Bump actions/upload-artifact from 4.3.4 to 4.4.0 in the github-actions... 35 | * `#769 `__: DOC: improve figures in \`demo/wp_scalogram.py\` 36 | * `#771 `__: CI: build free-threaded Windows wheels 37 | * `#775 `__: CI: fix Windows wheels, clean up cp313/cp313t build config 38 | * `#778 `__: DOC: highlighted deprecations with backward compatibility information 39 | * `#779 `__: Bump the github-actions group with 2 updates 40 | -------------------------------------------------------------------------------- /doc/source/_static/comments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/doc/source/_static/comments.png -------------------------------------------------------------------------------- /doc/source/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/doc/source/_static/favicon.ico -------------------------------------------------------------------------------- /doc/source/_static/myst-nb.css: -------------------------------------------------------------------------------- 1 | /* MyST-NB 2 | 3 | This stylesheet targets elements output by MyST-NB that represent notebook 4 | cells. 5 | 6 | In some cases these rules override MyST-NB. In some cases they override PyData 7 | Sphinx Theme or Sphinx. And in some cases they do not override existing styling 8 | but add new styling. */ 9 | 10 | /* Set up a few variables for this stylesheet */ 11 | .cell, 12 | .pywt-handcoded-cell-output { 13 | --pywt-cell-input-border-left-width: .2rem; 14 | 15 | /* This matches the padding applied to
 elements by PyData Sphinx Theme */
16 |   --pywt-code-block-padding: 1rem;
17 | 
18 |   /* override mystnb */
19 |   --mystnb-source-border-radius: .25rem; /* match PyData Sphinx Theme */
20 | }
21 | 
22 | .cell .cell_input::before {
23 |   content: "In";
24 |   border-bottom: var(--mystnb-source-border-width) solid var(--pst-color-border);
25 |   font-weight: var(--pst-font-weight-caption);
26 | 
27 |   /* Left-aligns the text in this box and the one that follows it */
28 |   padding-left: var(--pywt-code-block-padding);
29 | }
30 | 
31 | /* Cannot use `.cell .cell_input` selector because the stylesheet from MyST-NB
32 |    uses `div.cell div.cell_input` and we want to override those rules */
33 | div.cell div.cell_input {
34 |   background-color: inherit;
35 |   border-color: var(--pst-color-border);
36 |   border-left-width: var(--pywt-cell-input-border-left-width);
37 |   background-clip: padding-box;
38 |   overflow: hidden;
39 | }
40 | 
41 | .cell .cell_output,
42 | .pywt-handcoded-cell-output {
43 |   border: var(--mystnb-source-border-width) solid var(--pst-color-surface);
44 |   border-radius: var(--mystnb-source-border-radius);
45 |   background-clip: padding-box;
46 |   overflow: hidden;
47 | }
48 | 
49 | .cell .cell_output::before,
50 | .pywt-handcoded-cell-output::before {
51 |   content: "Out";
52 |   display: block;
53 |   font-weight: var(--pst-font-weight-caption);
54 | 
55 |   /* Left-aligns the text in this box and the one that follows it */
56 |   padding-left: var(--pywt-code-block-padding);
57 | }
58 | 
59 | .cell .cell_output .output {
60 |   background-color: inherit;
61 |   border: none;
62 |   margin-top: 0;
63 | }
64 | 
65 | .cell .cell_output,
66 | /* must prefix the following selector with `div.` to override Sphinx margin rule on div[class*=highlight-] */
67 | div.pywt-handcoded-cell-output {
68 |   /* Left-align the text in the output with the text in the input */
69 |   margin-left: calc(var(--pywt-cell-input-border-left-width) - var(--mystnb-source-border-width));
70 | }
71 | 
72 | .cell .cell_output .output,
73 | .cell .cell_input pre,
74 | .cell .cell_output pre,
75 | .pywt-handcoded-cell-output .highlight,
76 | .pywt-handcoded-cell-output pre {
77 |   border-radius: 0;
78 | }
79 | 
80 | .pywt-handcoded-cell-output pre {
81 |   border: none; /* MyST-NB sets border to none for 
 tags inside div.cell */
82 | }
83 | 


--------------------------------------------------------------------------------
/doc/source/_static/page_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/doc/source/_static/page_edit.png


--------------------------------------------------------------------------------
/doc/source/_static/pywavelets.css:
--------------------------------------------------------------------------------
 1 | /* Custom CSS rules for the interactive documentation button */
 2 | 
 3 | .try_examples_button {
 4 |   color: white;
 5 |   background-color: #0054a6;
 6 |   border: none;
 7 |   padding: 5px 10px;
 8 |   border-radius: 10px;
 9 |   margin-bottom: 5px;
10 |   box-shadow: 0 2px 5px rgba(108,108,108,0.2);
11 |   font-weight: bold;
12 |   font-size: small;
13 | }
14 | 
15 | .try_examples_button:hover {
16 |   background-color: #0066cc;
17 |   transform: scale(1.02);
18 |   box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
19 |   cursor: pointer;
20 | }
21 | 
22 | .try_examples_button_container {
23 |   display: flex;
24 |   justify-content: flex-start;
25 |   gap: 10px;
26 |   margin-bottom: 20px;
27 | }
28 | 
29 | /*
30 | Admonitions on this site are styled with some top margin. This makes sense when
31 | the admonition appears within the flow of the article. But when it is the very
32 | first child of an article, its top margin gets added to the article's top
33 | padding, resulting in too much whitespace.
34 | */
35 | .admonition.pywt-margin-top-0 {
36 |   margin-top: 0;
37 | }
38 | 


--------------------------------------------------------------------------------
/doc/source/_static/wave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/doc/source/_static/wave.png


--------------------------------------------------------------------------------
/doc/source/common_refs.rst:
--------------------------------------------------------------------------------
 1 | .. _built-in wavelet filters: http://wavelets.pybytes.com/
 2 | .. _Cython: http://cython.org/
 3 | .. _demo: https://github.com/PyWavelets/pywt/tree/main/demo
 4 | .. _Anaconda: https://www.continuum.io
 5 | .. _GitHub: https://github.com/PyWavelets/pywt
 6 | .. _GitHub repository: https://github.com/PyWavelets/pywt
 7 | .. _GitHub Issues: https://github.com/PyWavelets/pywt/issues
 8 | .. _NumPy: https://www.numpy.org
 9 | .. _SciPy: https://www.scipy.org
10 | .. _original developer: http://en.ig.ma
11 | .. _Python: http://python.org/
12 | .. _Python Package Index: http://pypi.python.org/pypi/PyWavelets/
13 | .. _PyPI: http://pypi.python.org/pypi/PyWavelets/
14 | .. _PyWavelets discussions group: http://groups.google.com/group/pywavelets
15 | .. _Releases Page: https://github.com/PyWavelets/pywt/releases
16 | .. _Matplotlib: http://matplotlib.org
17 | .. _guidelines for pull requests: https://github.com/PyWavelets/pywt/tree/main/CONTRIBUTING.rst
18 | .. _community guidelines: https://github.com/PyWavelets/pywt/tree/main/community_guidelines.rst
19 | .. _code of conduct: https://github.com/PyWavelets/pywt/tree/main/doc/source/dev/conduct/community_guidelines.rst
20 | .. _StackOverflow: https://stackoverflow.com
21 | .. _wavelets.pybytes.com: http://wavelets.pybytes.com/
22 | 


--------------------------------------------------------------------------------
/doc/source/contributing.rst:
--------------------------------------------------------------------------------
 1 | Contributing
 2 | ============
 3 | 
 4 | All contributions including bug reports, bug fixes, new feature implementations
 5 | and documentation improvements are welcome.  Moreover, developers with an
 6 | interest in PyWavelets are very welcome to join the development team! Please
 7 | see our `guidelines for pull requests`_ for more information.
 8 | 
 9 | Contributors are expected to behave in a productive and respectful manner in
10 | accordance with our `community guidelines`_ and :ref:`CoC`.
11 | 
12 | 
13 | History
14 | -------
15 | 
16 | PyWavelets started in 2006 as an academic project for a masters thesis
17 | on `Analysis and Classification of Medical Signals using Wavelet Transforms`
18 | and was maintained until 2012 by its `original developer`_.  In 2013
19 | maintenance was taken over in a `new repo `_)
20 | by a larger development team - a move supported by the original developer.
21 | The repo move doesn't mean that this is a fork - the package continues to be
22 | developed under the name "PyWavelets", and released on PyPI and Github (see
23 | `this issue `_ for the discussion
24 | where that was decided).
25 | 
26 | .. include:: common_refs.rst
27 | 


--------------------------------------------------------------------------------
/doc/source/dev/building_extension.rst:
--------------------------------------------------------------------------------
 1 | .. _dev-building-extension:
 2 | 
 3 | Building and installing PyWavelets
 4 | ==================================
 5 | 
 6 | Installing from source code
 7 | ---------------------------
 8 | 
 9 | Go to https://github.com/PyWavelets/pywt GitHub project page, fork and clone the
10 | repository or use the upstream repository to get the source code::
11 | 
12 |     git clone https://github.com/PyWavelets/pywt.git PyWavelets
13 | 
14 | Activate your Python virtual environment, go to the cloned source directory
15 | and type the following commands to build and install the package::
16 | 
17 |     pip install .
18 | 
19 | To verify the installation run the following command::
20 | 
21 |     pytest .
22 | 
23 | 
24 | Installing a development version
25 | --------------------------------
26 | 
27 | You can also install directly from the source repository::
28 | 
29 |     pip install -e git+https://github.com/PyWavelets/pywt.git#egg=PyWavelets
30 | 
31 | or::
32 | 
33 |     pip install PyWavelets==dev
34 | 
35 | 
36 | Installing a regular release from PyPi
37 | --------------------------------------
38 | 
39 | A regular release can be installed with pip::
40 | 
41 |     pip install PyWavelets
42 | 


--------------------------------------------------------------------------------
/doc/source/dev/how_to_build_the_docs.rst:
--------------------------------------------------------------------------------
 1 | .. _dev-building-docs:
 2 | 
 3 | How to build the docs locally
 4 | =============================
 5 | 
 6 | After preparing your Windows or Linux environment, install Spin and Ninja::
 7 | 
 8 |     pip install spin ninja
 9 | 
10 | Then install the documentation-related dependencies::
11 | 
12 |     pip install -r util/readthedocs/requirements.txt
13 | 
14 | Then tell Spin to build the Sphinx documentation::
15 | 
16 |     spin docs
17 | 
18 | Then open a webserver to serve the built HTML files::
19 | 
20 |     python -m http.server -d doc/build/html 8000
21 | 
22 | And open your local docs in a web browser by visiting http://localhost:8000/.
23 | 
24 | If it's your first time building the docs, it will take a while but should go
25 | faster on subsequent re-builds.
26 | 


--------------------------------------------------------------------------------
/doc/source/dev/index.rst:
--------------------------------------------------------------------------------
 1 | .. _dev-index:
 2 | 
 3 | 
 4 | Development guide
 5 | =================
 6 | 
 7 | This section contains information on building and installing PyWavelets
 8 | from source code as well as instructions for preparing the build environment
 9 | on Windows and Linux.
10 | 
11 | .. toctree::
12 |    :maxdepth: 2
13 | 
14 |    conduct/code_of_conduct
15 |    preparing_windows_build_environment
16 |    preparing_linux_build_environment
17 |    installing_build_dependencies
18 |    building_extension
19 |    testing
20 |    how_to_build_the_docs
21 |    how_to_release
22 | 
23 | Something not working?
24 | ----------------------
25 | 
26 | If these instructions are not clear or you need help setting up your
27 | development environment, go ahead and ask on the PyWavelets discussion
28 | group at http://groups.google.com/group/pywavelets or open a ticket on GitHub_.
29 | 
30 | .. _GitHub: https://github.com/PyWavelets/pywt
31 | 


--------------------------------------------------------------------------------
/doc/source/dev/installing_build_dependencies.rst:
--------------------------------------------------------------------------------
 1 | .. _dev-installing-build-dependencies:
 2 | 
 3 | Installing build dependencies
 4 | =============================
 5 | 
 6 | Setting up Python virtual environment
 7 | -------------------------------------
 8 | 
 9 | A good practice is to create a separate Python virtual environment for each
10 | project. If you don't have `virtualenv`_ yet, install and activate it using::
11 | 
12 |     curl -O https://raw.github.com/pypa/virtualenv/master/virtualenv.py
13 |     python virtualenv.py 
14 |     . /bin/activate
15 | 
16 | 
17 | Installing Cython
18 | -----------------
19 | 
20 | Use ``pip`` (http://pypi.python.org/pypi/pip) to install Cython_::
21 | 
22 | 
23 |     pip install Cython
24 | 
25 | 
26 | Installing numpy
27 | ----------------
28 | 
29 | Use ``pip`` to install numpy_::
30 | 
31 |     pip install numpy
32 | 
33 | Numpy can also be obtained via scientific python distributions such as:
34 | 
35 | - Anaconda_
36 | - `Enthought Canopy`_
37 | - `Python(x,y) `_
38 | 
39 | .. note::
40 | 
41 |   You can find binaries for 64-bit Windows on http://www.lfd.uci.edu/~gohlke/pythonlibs/.
42 | 
43 | 
44 | Installing Sphinx
45 | -----------------
46 | 
47 | Sphinx_ is a documentation tool that converts reStructuredText files into
48 | nicely looking html documentation. Install it with::
49 | 
50 |     pip install Sphinx
51 | 
52 | numpydoc_ is used to format the API docmentation appropriately.  Install it
53 | via::
54 | 
55 |     pip install numpydoc
56 | 
57 | 
58 | .. _virtualenv: http://pypi.python.org/pypi/virtualenv
59 | .. _numpy: http://numpy.org/
60 | .. _Cython: http://cython.org/
61 | .. _Sphinx: http://sphinx.pocoo.org
62 | .. _numpydoc: https://github.com/numpy/numpydoc
63 | .. _Anaconda: https://www.continuum.io/downloads
64 | .. _Enthought Canopy: https://www.enthought.com/products/canopy/
65 | 


--------------------------------------------------------------------------------
/doc/source/dev/preparing_linux_build_environment.rst:
--------------------------------------------------------------------------------
 1 | .. _dev-preparing-linux-build-environment:
 2 | 
 3 | 
 4 | Preparing Linux build environment
 5 | =================================
 6 | 
 7 | There is a good chance that you already have a working build environment.
 8 | Just skip steps that you don't need to execute.
 9 | 
10 | 
11 | Installing basic build tools
12 | ----------------------------
13 | 
14 | Note that the example below uses ``aptitude`` package manager, which is
15 | specific to Debian and Ubuntu Linux distributions. Use your favourite package
16 | manager to install these packages on your OS.
17 | 
18 | ::
19 | 
20 |     aptitude install build-essential gcc python-dev git-core
21 | 
22 | 
23 | Next steps
24 | ----------
25 | 
26 | After completing these steps continue with
27 | :ref:`Installing build dependencies `.
28 | 


--------------------------------------------------------------------------------
/doc/source/dev/preparing_windows_build_environment.rst:
--------------------------------------------------------------------------------
 1 | .. _dev-building-on-windows:
 2 | 
 3 | 
 4 | Preparing Windows build environment
 5 | ===================================
 6 | 
 7 | To start developing PyWavelets code on Windows you will have to install a C
 8 | compiler and prepare the build environment. PyWavelets can be built with all
 9 | commonly used compilers on Windows (MSVC, Clang-cl, MinGW-w64, Intel C
10 | compilers). PyWavelets' own CI jobs use MSVC; the ``appveyor.yml``
11 | configuration file may be a helpful reference if you want to use MSVC locally.
12 | 
13 | After completing these steps continue with
14 | :ref:`Installing build dependencies `.
15 | 
16 | 
17 | .. _Python: http://python.org/
18 | .. _numpy: http://numpy.org/
19 | .. _Cython: http://cython.org/
20 | .. _Sphinx: http://sphinx.pocoo.org/
21 | .. _MinGW C compiler: http://sourceforge.net/projects/mingwbuilds/
22 | 


--------------------------------------------------------------------------------
/doc/source/dev/testing.rst:
--------------------------------------------------------------------------------
 1 | .. _dev-testing:
 2 | 
 3 | Testing
 4 | =======
 5 | 
 6 | Continuous integration with GitHub Actions
 7 | ------------------------------------------
 8 | 
 9 | The project is using GitHub Actions for continuous integration and testing.
10 | 
11 | Current build status is:
12 | 
13 | .. image:: https://github.com/PyWavelets/pywt/actions/workflows/tests.yml/badge.svg?branch=main
14 |     :alt: Build Status
15 |     :target: https://github.com/PyWavelets/pywt/actions/workflows/tests.yml?query=branch%3Amain
16 | 
17 | If you are submitting a patch or pull request please make sure it
18 | does not break the build.
19 | 
20 | 
21 | Running tests locally
22 | ---------------------
23 | 
24 | Tests are implemented with `pytest`_, so use one of:
25 | 
26 | .. code-block:: bash
27 | 
28 |     pytest --pyargs pywt -v
29 | 
30 | There are also older doctests that can be run by performing the following from
31 | the root of the project source.
32 | 
33 | .. code-block:: bash
34 | 
35 |     python pywt/tests/test_doc.py
36 |     cd doc
37 |     make doctest
38 | 
39 | Additionally the examples in the demo subfolder can be checked by running:
40 | 
41 | .. code-block:: bash
42 | 
43 |     python util/refguide_check.py
44 | 
45 | Note: doctests require `Matplotlib`_ in addition to the usual dependencies.
46 | 
47 | 
48 | Running tests with Tox
49 | ----------------------
50 | 
51 | There's also a config file for running tests with `Tox`_ (``pip install tox``).
52 | For example, to run tests for Python 3.10, Python 3.11, and 3.12, use
53 | 
54 | .. code-block:: bash
55 | 
56 |     tox -e py310,py311,py312
57 | 
58 | For more information see the `Tox`_ documentation.
59 | 
60 | .. _pytest: https://pytest.org
61 | .. _Tox: https://tox.readthedocs.io/en/latest/
62 | .. _Matplotlib: https://matplotlib.org
63 | 


--------------------------------------------------------------------------------
/doc/source/index.rst:
--------------------------------------------------------------------------------
 1 | PyWavelets - Wavelet Transforms in Python
 2 | =========================================
 3 | 
 4 | Contents
 5 | --------
 6 | 
 7 | .. toctree::
 8 |     :maxdepth: 1
 9 | 
10 |     install
11 |     ref/index
12 |     regression/index
13 |     contributing
14 |     dev/index
15 |     releasenotes
16 | 
17 | .. include:: common_refs.rst
18 | 
19 | PyWavelets is open source wavelet transform software for Python_. It combines
20 | a simple high level interface with low level C and Cython performance.
21 | 
22 | PyWavelets is very easy to use and get started with. Just install the package,
23 | open the Python interactive shell and type:
24 | 
25 | .. code-block:: python
26 | 
27 |   import pywt
28 |   cA, cD = pywt.dwt([1, 2, 3, 4], 'db1')
29 | 
30 | Voilà! Computing wavelet transforms has never been so simple :)
31 | 
32 | Here is a slightly more involved example of applying a digital wavelet
33 | transform to an image:
34 | 
35 | .. plot:: pyplots/camera_approx_detail.py
36 | 
37 | Main features
38 | -------------
39 | 
40 | The main features of PyWavelets are:
41 | 
42 | * 1D, 2D and nD Forward and Inverse Discrete Wavelet Transform (DWT and IDWT)
43 | * 1D, 2D and nD Multilevel DWT and IDWT
44 | * 1D, 2D and nD Stationary Wavelet Transform (Undecimated Wavelet Transform)
45 | * 1D and 2D Wavelet Packet decomposition and reconstruction
46 | * 1D Continuous Wavelet Transform
47 | * Computing Approximations of wavelet and scaling functions
48 | * Over 100 `built-in wavelet filters`_ and support for custom wavelets
49 | * Single and double precision calculations
50 | * Real and complex calculations
51 | * Results compatible with Matlab Wavelet Toolbox (TM)
52 | 
53 | 
54 | Getting help
55 | ------------
56 | 
57 | Use `GitHub Issues`_, `StackOverflow`_, or the `PyWavelets discussions group`_
58 | to post your comments or questions.
59 | 
60 | License
61 | -------
62 | 
63 | PyWavelets is a free Open Source software released under the MIT license.
64 | 
65 | Citing
66 | ------
67 | 
68 | If you use PyWavelets in a scientific publication, we would appreciate
69 | citations of the project via the following
70 | JOSS publication:
71 | 
72 |   Gregory R. Lee, Ralf Gommers, Filip Wasilewski, Kai Wohlfahrt, Aaron
73 |   O'Leary (2019). PyWavelets: A Python package for wavelet analysis. Journal
74 |   of Open Source Software, 4(36), 1237, https://doi.org/10.21105/joss.01237.
75 | 
76 | .. image:: http://joss.theoj.org/papers/10.21105/joss.01237/status.svg
77 |    :target: https://doi.org/10.21105/joss.01237
78 | 
79 | Specific releases can also be cited via Zenodo. The DOI below will correspond
80 | to the most recent release. DOIs for past versions can be found by following
81 | the link in the badge below to Zenodo:
82 | 
83 | .. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.1407171.svg
84 |    :target: https://doi.org/10.5281/zenodo.1407171
85 | 


--------------------------------------------------------------------------------
/doc/source/install.rst:
--------------------------------------------------------------------------------
 1 | Installing
 2 | ==========
 3 | 
 4 | The latest release, including binary packages for Windows, macOS and Linux,
 5 | is available for download from `PyPI`_.  You can also find source releases at
 6 | the `Releases Page`_.
 7 | 
 8 | You can install PyWavelets with::
 9 | 
10 |     pip install PyWavelets
11 | 
12 | Users of the Anaconda_ Python distribution may wish to obtain pre-built
13 | Windows, Intel Linux or macOS / OSX binaries from the main or conda-forge
14 | channel::
15 | 
16 |     conda install pywavelets
17 | 
18 | Several Linux distributions have their own packages for PyWavelets, but these
19 | tend to be moderately out of date.  Query your Linux package manager tool for
20 | ``python-pywavelets``, ``python-wavelets``, ``python-pywt`` or a similar
21 | package name.
22 | 
23 | 
24 | Building from source
25 | --------------------
26 | 
27 | The most recent *development* version can be found on GitHub at
28 | https://github.com/PyWavelets/pywt.
29 | 
30 | The latest release, is available for download from `PyPI`_ or on the
31 | `Releases Page`_.
32 | 
33 | If you want or need to install from source, you will need a working C compiler
34 | (any common one will work) installed on your system.  Navigate to the
35 | PyWavelets source code directory (containing ``pyproject.toml.py``) and type::
36 | 
37 |     pip install .
38 | 
39 | For the requirements needed to build from source are (Python, NumPy and Cython
40 | minimum versions in particular), see ``pyproject.toml``.
41 | 
42 | To run all the tests for PyWavelets, you will also need to install the
43 | Matplotlib_ package.
44 | 
45 | .. seealso::  The :ref:`Development guide ` section contains more
46 |               information on building and installing from source code.
47 | 
48 | .. include:: common_refs.rst
49 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/camera_approx_detail.py:
--------------------------------------------------------------------------------
 1 | import matplotlib.pyplot as plt
 2 | import numpy as np
 3 | 
 4 | import pywt
 5 | import pywt.data
 6 | 
 7 | # Load image
 8 | original = pywt.data.camera()
 9 | 
10 | # Wavelet transform of image, and plot approximation and details
11 | titles = ['Approximation', ' Horizontal detail',
12 |           'Vertical detail', 'Diagonal detail']
13 | coeffs2 = pywt.dwt2(original, 'bior1.3')
14 | LL, (LH, HL, HH) = coeffs2
15 | fig = plt.figure(figsize=(12, 3))
16 | for i, a in enumerate([LL, LH, HL, HH]):
17 |     ax = fig.add_subplot(1, 4, i + 1)
18 |     ax.imshow(a, interpolation="nearest", cmap=plt.cm.gray)
19 |     ax.set_title(titles[i], fontsize=10)
20 |     ax.set_xticks([])
21 |     ax.set_yticks([])
22 | 
23 | fig.tight_layout()
24 | plt.show()
25 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/cwt_scaling_demo.py:
--------------------------------------------------------------------------------
 1 | import matplotlib.pyplot as plt
 2 | import numpy as np
 3 | 
 4 | import pywt
 5 | 
 6 | wav = pywt.ContinuousWavelet('cmor1.5-1.0')
 7 | 
 8 | # print the range over which the wavelet will be evaluated
 9 | print("Continuous wavelet will be evaluated over the range "
10 |       f"[{wav.lower_bound}, {wav.upper_bound}]")
11 | 
12 | width = wav.upper_bound - wav.lower_bound
13 | 
14 | scales = [1, 2, 3, 4, 10, 15]
15 | 
16 | max_len = int(np.max(scales)*width + 1)
17 | t = np.arange(max_len)
18 | fig, axes = plt.subplots(len(scales), 2, figsize=(12, 6))
19 | for n, scale in enumerate(scales):
20 | 
21 |     # The following code is adapted from the internals of cwt
22 |     int_psi, x = pywt.integrate_wavelet(wav, precision=10)
23 |     step = x[1] - x[0]
24 |     j = np.floor(
25 |         np.arange(scale * width + 1) / (scale * step))
26 |     if np.max(j) >= np.size(int_psi):
27 |         j = np.delete(j, np.where(j >= np.size(int_psi))[0])
28 |     j = j.astype(np.int_)
29 | 
30 |     # normalize int_psi for easier plotting
31 |     int_psi /= np.abs(int_psi).max()
32 | 
33 |     # discrete samples of the integrated wavelet
34 |     filt = int_psi[j][::-1]
35 | 
36 |     # The CWT consists of convolution of filt with the signal at this scale
37 |     # Here we plot this discrete convolution kernel at each scale.
38 | 
39 |     nt = len(filt)
40 |     t = np.linspace(-nt//2, nt//2, nt)
41 |     axes[n, 0].plot(t, filt.real, t, filt.imag)
42 |     axes[n, 0].set_xlim([-max_len//2, max_len//2])
43 |     axes[n, 0].set_ylim([-1, 1])
44 |     axes[n, 0].text(50, 0.35, f'scale = {scale}')
45 | 
46 |     f = np.linspace(-np.pi, np.pi, max_len)
47 |     filt_fft = np.fft.fftshift(np.fft.fft(filt, n=max_len))
48 |     filt_fft /= np.abs(filt_fft).max()
49 |     axes[n, 1].plot(f, np.abs(filt_fft)**2)
50 |     axes[n, 1].set_xlim([-np.pi, np.pi])
51 |     axes[n, 1].set_ylim([0, 1])
52 |     axes[n, 1].set_xticks([-np.pi, 0, np.pi])
53 |     axes[n, 1].set_xticklabels([r'$-\pi$', '0', r'$\pi$'])
54 |     axes[n, 1].grid(True, axis='x')
55 |     axes[n, 1].text(np.pi/2, 0.5, f'scale = {scale}')
56 | 
57 | axes[n, 0].set_xlabel('time (samples)')
58 | axes[n, 1].set_xlabel('frequency (radians)')
59 | axes[0, 0].legend(['real', 'imaginary'], loc='upper left')
60 | axes[0, 1].legend(['Power'], loc='upper left')
61 | axes[0, 0].set_title('filter')
62 | axes[0, 1].set_title(r'|FFT(filter)|$^2$')
63 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/cwt_wavelet_frequency_bandwidth_demo.py:
--------------------------------------------------------------------------------
 1 | import matplotlib.pyplot as plt
 2 | import numpy as np
 3 | 
 4 | import pywt
 5 | 
 6 | # plot complex morlet wavelets with different center frequencies and bandwidths
 7 | wavelets = [f"cmor{x:.1f}-{y:.1f}" for x in [0.5, 1.5, 2.5] for y in [0.5, 1.0, 1.5]]
 8 | fig, axs = plt.subplots(3, 3, figsize=(10, 10), sharex=True, sharey=True)
 9 | for ax, wavelet in zip(axs.flatten(), wavelets):
10 |     [psi, x] = pywt.ContinuousWavelet(wavelet).wavefun(10)
11 |     ax.plot(x, np.real(psi), label="real")
12 |     ax.plot(x, np.imag(psi), label="imag")
13 |     ax.set_title(wavelet)
14 |     ax.set_xlim([-5, 5])
15 |     ax.set_ylim([-0.8, 1])
16 | ax.legend()
17 | plt.suptitle("Complex Morlet Wavelets with different center frequencies and bandwidths")
18 | plt.show()
19 | 
20 | 
21 | def gaussian(x, x0, sigma):
22 |     return np.exp(-np.power((x - x0) / sigma, 2.0) / 2.0)
23 | 
24 | 
25 | def make_chirp(t, t0, a):
26 |     frequency = (a * (t + t0)) ** 2
27 |     chirp = np.sin(2 * np.pi * frequency * t)
28 |     return chirp, frequency
29 | 
30 | 
31 | def plot_wavelet(time, data, wavelet, title, ax):
32 |     widths = np.geomspace(1, 1024, num=75)
33 |     cwtmatr, freqs = pywt.cwt(
34 |         data, widths, wavelet, sampling_period=np.diff(time).mean()
35 |     )
36 |     cwtmatr = np.abs(cwtmatr[:-1, :-1])
37 |     pcm = ax.pcolormesh(time, freqs, cwtmatr)
38 |     ax.set_yscale("log")
39 |     ax.set_xlabel("Time (s)")
40 |     ax.set_ylabel("Frequency (Hz)")
41 |     ax.set_title(title)
42 |     plt.colorbar(pcm, ax=ax)
43 |     return ax
44 | 
45 | 
46 | # generate signal
47 | time = np.linspace(0, 1, 1000)
48 | chirp1, frequency1 = make_chirp(time, 0.2, 9)
49 | chirp2, frequency2 = make_chirp(time, 0.1, 5)
50 | chirp = chirp1 + 0.6 * chirp2
51 | chirp *= gaussian(time, 0.5, 0.2)
52 | 
53 | # perform CWT with different wavelets on same signal and plot results
54 | wavelets = [f"cmor{x:.1f}-{y:.1f}" for x in [0.5, 1.5, 2.5] for y in [0.5, 1.0, 1.5]]
55 | fig, axs = plt.subplots(3, 3, figsize=(10, 10), sharex=True)
56 | for ax, wavelet in zip(axs.flatten(), wavelets):
57 |     plot_wavelet(time, chirp, wavelet, wavelet, ax)
58 | plt.tight_layout(rect=[0, 0.03, 1, 0.95])
59 | plt.suptitle("Scaleograms of the same signal with different wavelets")
60 | plt.show()
61 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/plot_2d_bases.py:
--------------------------------------------------------------------------------
 1 | from itertools import product
 2 | 
 3 | import numpy as np
 4 | from matplotlib import pyplot as plt
 5 | 
 6 | from pywt._doc_utils import (
 7 |     draw_2d_fswavedecn_basis,
 8 |     draw_2d_wp_basis,
 9 |     wavedec2_keys,
10 |     wavedec_keys,
11 | )
12 | 
13 | shape = (512, 512)
14 | 
15 | max_lev = 4       # how many levels of decomposition to draw
16 | label_levels = 2  # how many levels to explicitly label on the plots
17 | 
18 | if False:
19 |     fig, axes = plt.subplots(1, 4, figsize=[16, 4])
20 |     axes = axes.ravel()
21 | else:
22 |     fig, axes = plt.subplots(2, 2, figsize=[8, 8])
23 |     axes = axes.ravel()
24 | 
25 | # plot a 5-level standard DWT basis
26 | draw_2d_wp_basis(shape, wavedec2_keys(max_lev), ax=axes[0],
27 |                  label_levels=label_levels)
28 | axes[0].set_title(f'wavedec2 ({max_lev} level)')
29 | 
30 | # plot for the fully separable case
31 | draw_2d_fswavedecn_basis(shape, max_lev, ax=axes[1], label_levels=label_levels)
32 | axes[1].set_title(f'fswavedecn ({max_lev} level)')
33 | 
34 | # get all keys corresponding to a full wavelet packet decomposition
35 | wp_keys = list(product(['a', 'd', 'h', 'v'], repeat=max_lev))
36 | draw_2d_wp_basis(shape, wp_keys, ax=axes[2])
37 | axes[2].set_title(f'wavelet packet\n(full: {max_lev} level)')
38 | 
39 | # plot an example of a custom wavelet packet basis
40 | keys = ['aaaa', 'aaad', 'aaah', 'aaav', 'aad', 'aah', 'aava', 'aavd',
41 |         'aavh', 'aavv', 'ad', 'ah', 'ava', 'avd', 'avh', 'avv', 'd', 'h',
42 |         'vaa', 'vad', 'vah', 'vav', 'vd', 'vh', 'vv']
43 | draw_2d_wp_basis(shape, keys, ax=axes[3], label_levels=label_levels)
44 | axes[3].set_title('wavelet packet\n(custom)')
45 | 
46 | plt.tight_layout()
47 | plt.show()
48 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/plot_boundary_modes.py:
--------------------------------------------------------------------------------
 1 | """A visual illustration of the various signal extension modes supported in
 2 | PyWavelets. For efficiency, in the C routines the array is not actually
 3 | extended as is done here. This is just a demo for easier visual explanation of
 4 | the behavior of the various boundary modes.
 5 | 
 6 | In practice, which signal extension mode is beneficial will depend on the
 7 | signal characteristics.  For this particular signal, some modes such as
 8 | "periodic",  "antisymmetric" and "zero" result in large discontinuities that
 9 | would lead to large amplitude boundary coefficients in the detail coefficients
10 | of a discrete wavelet transform.
11 | """
12 | import numpy as np
13 | from matplotlib import pyplot as plt
14 | 
15 | from pywt._doc_utils import boundary_mode_subplot
16 | 
17 | # synthetic test signal
18 | x = 5 - np.linspace(-1.9, 1.1, 9)**2
19 | 
20 | # Create a figure with one subplots per boundary mode
21 | fig, axes = plt.subplots(3, 3, figsize=(10, 6))
22 | plt.subplots_adjust(hspace=0.5)
23 | axes = axes.ravel()
24 | boundary_mode_subplot(x, 'symmetric', axes[0], symw=False)
25 | boundary_mode_subplot(x, 'reflect', axes[1], symw=True)
26 | boundary_mode_subplot(x, 'periodic', axes[2], symw=False)
27 | boundary_mode_subplot(x, 'antisymmetric', axes[3], symw=False)
28 | boundary_mode_subplot(x, 'antireflect', axes[4], symw=True)
29 | boundary_mode_subplot(x, 'periodization', axes[5], symw=False)
30 | boundary_mode_subplot(x, 'smooth', axes[6], symw=False)
31 | boundary_mode_subplot(x, 'constant', axes[7], symw=False)
32 | boundary_mode_subplot(x, 'zero', axes[8], symw=False)
33 | plt.show()
34 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/plot_cwt_scaleogram.py:
--------------------------------------------------------------------------------
 1 | import matplotlib.pyplot as plt
 2 | import numpy as np
 3 | 
 4 | import pywt
 5 | 
 6 | 
 7 | def gaussian(x, x0, sigma):
 8 |     return np.exp(-np.power((x - x0) / sigma, 2.0) / 2.0)
 9 | 
10 | 
11 | def make_chirp(t, t0, a):
12 |     frequency = (a * (t + t0)) ** 2
13 |     chirp = np.sin(2 * np.pi * frequency * t)
14 |     return chirp, frequency
15 | 
16 | 
17 | # generate signal
18 | time = np.linspace(0, 1, 2000)
19 | chirp1, frequency1 = make_chirp(time, 0.2, 9)
20 | chirp2, frequency2 = make_chirp(time, 0.1, 5)
21 | chirp = chirp1 + 0.6 * chirp2
22 | chirp *= gaussian(time, 0.5, 0.2)
23 | 
24 | # plot signal
25 | fig, axs = plt.subplots(2, 1, sharex=True)
26 | axs[0].plot(time, chirp)
27 | axs[1].plot(time, frequency1)
28 | axs[1].plot(time, frequency2)
29 | axs[1].set_yscale("log")
30 | axs[1].set_xlabel("Time (s)")
31 | axs[0].set_ylabel("Signal")
32 | axs[1].set_ylabel("True frequency (Hz)")
33 | plt.suptitle("Input signal")
34 | plt.show()
35 | 
36 | # perform CWT
37 | wavelet = "cmor1.5-1.0"
38 | # logarithmic scale for scales, as suggested by Torrence & Compo:
39 | widths = np.geomspace(1, 1024, num=100)
40 | sampling_period = np.diff(time).mean()
41 | cwtmatr, freqs = pywt.cwt(chirp, widths, wavelet, sampling_period=sampling_period)
42 | # absolute take absolute value of complex result
43 | cwtmatr = np.abs(cwtmatr[:-1, :-1])
44 | 
45 | # plot result using matplotlib's pcolormesh (image with annoted axes)
46 | fig, axs = plt.subplots(2, 1)
47 | pcm = axs[0].pcolormesh(time, freqs, cwtmatr)
48 | axs[0].set_yscale("log")
49 | axs[0].set_xlabel("Time (s)")
50 | axs[0].set_ylabel("Frequency (Hz)")
51 | axs[0].set_title("Continuous Wavelet Transform (Scaleogram)")
52 | fig.colorbar(pcm, ax=axs[0])
53 | 
54 | # plot fourier transform for comparison
55 | from numpy.fft import rfft, rfftfreq
56 | 
57 | yf = rfft(chirp)
58 | xf = rfftfreq(len(chirp), sampling_period)
59 | plt.semilogx(xf, np.abs(yf))
60 | axs[1].set_xlabel("Frequency (Hz)")
61 | axs[1].set_title("Fourier Transform")
62 | plt.tight_layout()
63 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/plot_mallat_2d.py:
--------------------------------------------------------------------------------
 1 | import numpy as np
 2 | from matplotlib import pyplot as plt
 3 | 
 4 | import pywt
 5 | from pywt._doc_utils import draw_2d_wp_basis, wavedec2_keys
 6 | 
 7 | x = pywt.data.camera().astype(np.float32)
 8 | shape = x.shape
 9 | 
10 | max_lev = 3       # how many levels of decomposition to draw
11 | label_levels = 3  # how many levels to explicitly label on the plots
12 | 
13 | fig, axes = plt.subplots(2, 4, figsize=[14, 8])
14 | for level in range(max_lev + 1):
15 |     if level == 0:
16 |         # show the original image before decomposition
17 |         axes[0, 0].set_axis_off()
18 |         axes[1, 0].imshow(x, cmap=plt.cm.gray)
19 |         axes[1, 0].set_title('Image')
20 |         axes[1, 0].set_axis_off()
21 |         continue
22 | 
23 |     # plot subband boundaries of a standard DWT basis
24 |     draw_2d_wp_basis(shape, wavedec2_keys(level), ax=axes[0, level],
25 |                      label_levels=label_levels)
26 |     axes[0, level].set_title(f'{level} level\ndecomposition')
27 | 
28 |     # compute the 2D DWT
29 |     c = pywt.wavedec2(x, 'db2', mode='periodization', level=level)
30 |     # normalize each coefficient array independently for better visibility
31 |     c[0] /= np.abs(c[0]).max()
32 |     for detail_level in range(level):
33 |         c[detail_level + 1] = [d/np.abs(d).max() for d in c[detail_level + 1]]
34 |     # show the normalized coefficients
35 |     arr, slices = pywt.coeffs_to_array(c)
36 |     axes[1, level].imshow(arr, cmap=plt.cm.gray)
37 |     axes[1, level].set_title(f'Coefficients\n({level} level)')
38 |     axes[1, level].set_axis_off()
39 | 
40 | plt.tight_layout()
41 | plt.show()
42 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/plot_thresholds.py:
--------------------------------------------------------------------------------
 1 | import matplotlib.pyplot as plt
 2 | import numpy as np
 3 | 
 4 | import pywt
 5 | 
 6 | s = np.linspace(-4, 4, 1000)
 7 | 
 8 | s_soft = pywt.threshold(s, value=0.5, mode='soft')
 9 | s_hard = pywt.threshold(s, value=0.5, mode='hard')
10 | s_garrote = pywt.threshold(s, value=0.5, mode='garrote')
11 | s_firm1 = pywt.threshold_firm(s, value_low=0.5, value_high=1)
12 | s_firm2 = pywt.threshold_firm(s, value_low=0.5, value_high=2)
13 | s_firm3 = pywt.threshold_firm(s, value_low=0.5, value_high=4)
14 | 
15 | fig, ax = plt.subplots(1, 2, figsize=(10, 4))
16 | ax[0].plot(s, s_soft)
17 | ax[0].plot(s, s_hard)
18 | ax[0].plot(s, s_garrote)
19 | ax[0].legend(['soft (0.5)', 'hard (0.5)', 'non-neg. garrote (0.5)'])
20 | ax[0].set_xlabel('input value')
21 | ax[0].set_ylabel('thresholded value')
22 | 
23 | ax[1].plot(s, s_soft)
24 | ax[1].plot(s, s_hard)
25 | ax[1].plot(s, s_firm1)
26 | ax[1].plot(s, s_firm2)
27 | ax[1].plot(s, s_firm3)
28 | ax[1].legend(['soft (0.5)', 'hard (0.5)', 'firm(0.5, 1)', 'firm(0.5, 2)',
29 |               'firm(0.5, 4)'])
30 | ax[1].set_xlabel('input value')
31 | ax[1].set_ylabel('thresholded value')
32 | plt.show()
33 | 


--------------------------------------------------------------------------------
/doc/source/pyplots/plot_wavelets.py:
--------------------------------------------------------------------------------
 1 | import matplotlib.pyplot as plt
 2 | import numpy as np
 3 | 
 4 | import pywt
 5 | 
 6 | wavlist = pywt.wavelist(kind="continuous")
 7 | cols = 3
 8 | rows = (len(wavlist) + cols - 1) // cols
 9 | fig, axs = plt.subplots(rows, cols, figsize=(10, 10),
10 |                         sharex=True, sharey=True)
11 | for ax, wavelet in zip(axs.flatten(), wavlist):
12 |     # A few wavelet families require parameters in the string name
13 |     if wavelet in ['cmor', 'shan']:
14 |         wavelet += '1-1'
15 |     elif wavelet == 'fbsp':
16 |         wavelet += '1-1.5-1.0'
17 | 
18 |     [psi, x] = pywt.ContinuousWavelet(wavelet).wavefun(10)
19 |     ax.plot(x, np.real(psi), label="real")
20 |     ax.plot(x, np.imag(psi), label="imag")
21 |     ax.set_title(wavelet)
22 |     ax.set_xlim([-5, 5])
23 |     ax.set_ylim([-0.8, 1])
24 | 
25 | ax.legend(loc="upper right")
26 | plt.suptitle("Available wavelets for CWT")
27 | plt.tight_layout()
28 | plt.show()
29 | 


--------------------------------------------------------------------------------
/doc/source/ref/2d-dwt-and-idwt.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-dwt2:
 2 | 
 3 | .. currentmodule:: pywt
 4 | 
 5 | =================================================
 6 | 2D Forward and Inverse Discrete Wavelet Transform
 7 | =================================================
 8 | 
 9 | 
10 | Single level ``dwt2``
11 | ~~~~~~~~~~~~~~~~~~~~~
12 | 
13 | .. autofunction:: dwt2
14 | 
15 | The relation to the other common data layout where all the approximation and
16 | details coefficients are stored in one big 2D array is as follows:
17 | 
18 |   ::
19 | 
20 |                                 -------------------
21 |                                 |        |        |
22 |                                 | cA(LL) | cH(LH) |
23 |                                 |        |        |
24 |     (cA, (cH, cV, cD))  <--->   -------------------
25 |                                 |        |        |
26 |                                 | cV(HL) | cD(HH) |
27 |                                 |        |        |
28 |                                 -------------------
29 | 
30 | PyWavelets does not follow this pattern because of pure practical reasons of simple
31 | access to particular type of the output coefficients.
32 | 
33 | 
34 | Single level ``idwt2``
35 | ~~~~~~~~~~~~~~~~~~~~~~
36 | 
37 | .. autofunction:: idwt2
38 | 
39 | 2D multilevel decomposition using ``wavedec2``
40 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41 | 
42 | .. autofunction:: wavedec2
43 | 
44 | 2D multilevel reconstruction using ``waverec2``
45 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46 | 
47 | .. autofunction:: waverec2
48 | 
49 | 
50 | 2D coordinate conventions
51 | ~~~~~~~~~~~~~~~~~~~~~~~~~
52 | 
53 | The labels for "horizontal" and "vertical" used by ``dwt2`` and ``idwt2``
54 | follow the common mathematical convention that coordinate axis 0
55 | is horizontal while axis 1 is vertical::
56 | 
57 |     dwt2, idwt2 convention
58 |     ----------------------
59 | 
60 |     axis 1 ^
61 |            |
62 |            |
63 |            |
64 |            |--------->
65 |                    axis 0
66 | 
67 | Note that this is different from another common convention used in computer
68 | graphics and image processing (e.g. by matplotlib's ``imshow`` and functions in
69 | ``scikit-image``).  In those packages axis 0 is a vertical axis and axis 1 is
70 | horizontal as follows::
71 | 
72 |      imshow convention
73 |     -------------------
74 |                  axis 1
75 |            |--------->
76 |            |
77 |            |
78 |            |
79 |     axis 0 v
80 | 


--------------------------------------------------------------------------------
/doc/source/ref/dwt-coefficient-handling.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-dwt-coef:
 2 | 
 3 | =========================
 4 | Handling DWT Coefficients
 5 | =========================
 6 | 
 7 | Convenience routines are available for converting the outputs of the multilevel
 8 | dwt functions (``wavedec``, ``wavedec2`` and ``wavedecn``) to and from a
 9 | single, concatenated coefficient array.
10 | 
11 | .. currentmodule:: pywt
12 | 
13 | Concatenating all coefficients into a single n-d array
14 | ------------------------------------------------------
15 | .. autofunction:: coeffs_to_array
16 | 
17 | Splitting concatenated coefficient array back into its components
18 | -----------------------------------------------------------------
19 | .. autofunction:: array_to_coeffs
20 | 
21 | Raveling and unraveling coefficients to/from a 1D array
22 | -------------------------------------------------------
23 | .. autofunction:: ravel_coeffs
24 | .. autofunction:: unravel_coeffs
25 | 
26 | Multilevel: Total size of all coefficients - ``wavedecn_size``
27 | --------------------------------------------------------------
28 | .. autofunction:: wavedecn_size
29 | 
30 | Multilevel: n-d coefficient shapes - ``wavedecn_shapes``
31 | --------------------------------------------------------
32 | .. autofunction:: wavedecn_shapes
33 | 


--------------------------------------------------------------------------------
/doc/source/ref/dwt-discrete-wavelet-transform.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-dwt:
 2 | 
 3 | .. currentmodule:: pywt
 4 | 
 5 | ================================
 6 | Discrete Wavelet Transform (DWT)
 7 | ================================
 8 | 
 9 | Wavelet transform has recently become a very popular when it comes to analysis,
10 | de-noising and compression of signals and images. This section describes
11 | functions used to perform single- and multilevel Discrete Wavelet Transforms.
12 | 
13 | 
14 | Single level ``dwt``
15 | --------------------
16 | 
17 | .. autofunction:: dwt
18 | 
19 | See the :ref:`signal extension modes ` section for the list of
20 | available options and the :func:`dwt_coeff_len` function for information on
21 | getting the expected result length.
22 | 
23 | The transform can be performed over one axis of multi-dimensional
24 | data. By default this is the last axis. For multi-dimensional transforms
25 | see the :ref:`2D transforms ` section.
26 | 
27 | 
28 | Multilevel decomposition using ``wavedec``
29 | ------------------------------------------
30 | 
31 | .. autofunction:: wavedec
32 | 
33 | 
34 | Partial Discrete Wavelet Transform data decomposition ``downcoef``
35 | ------------------------------------------------------------------
36 | 
37 | .. autofunction:: downcoef
38 | 
39 | 
40 | Maximum decomposition level - ``dwt_max_level``, ``dwtn_max_level``
41 | -------------------------------------------------------------------
42 | 
43 | .. autofunction:: dwt_max_level
44 | .. autofunction:: dwtn_max_level
45 | 
46 | 
47 | .. _`dwt_coeff_len`:
48 | 
49 | Result coefficients length - ``dwt_coeff_len``
50 | ----------------------------------------------
51 | 
52 | .. autofunction:: dwt_coeff_len
53 | 
54 | Based on the given input data length (``data_len``), wavelet decomposition
55 | filter length (``filter_len``) and :ref:`signal extension mode `, the
56 | :func:`dwt_coeff_len` function calculates the length of the resulting
57 | coefficients arrays that would be created while performing :func:`dwt`
58 | transform.
59 | 
60 | ``filter_len`` can be either an ``int`` or :class:`Wavelet` object for
61 | convenience.
62 | 


--------------------------------------------------------------------------------
/doc/source/ref/idwt-inverse-discrete-wavelet-transform.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-idwt:
 2 | 
 3 | .. currentmodule:: pywt
 4 | 
 5 | =========================================
 6 | Inverse Discrete Wavelet Transform (IDWT)
 7 | =========================================
 8 | 
 9 | 
10 | Single level ``idwt``
11 | ---------------------
12 | 
13 | .. autofunction:: idwt
14 | 
15 | 
16 | Multilevel reconstruction using ``waverec``
17 | -------------------------------------------
18 | 
19 | .. autofunction:: waverec
20 | 
21 | 
22 | Direct reconstruction with ``upcoef``
23 | -------------------------------------
24 | 
25 | .. autofunction:: upcoef
26 | 


--------------------------------------------------------------------------------
/doc/source/ref/index.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-index:
 2 | 
 3 | API Reference
 4 | =============
 5 | 
 6 | .. toctree::
 7 |    :maxdepth: 2
 8 | 
 9 |    wavelets
10 |    signal-extension-modes
11 |    dwt-discrete-wavelet-transform
12 |    idwt-inverse-discrete-wavelet-transform
13 |    2d-decompositions-overview
14 |    2d-dwt-and-idwt
15 |    nd-dwt-and-idwt
16 |    dwt-coefficient-handling
17 |    swt-stationary-wavelet-transform
18 |    iswt-inverse-stationary-wavelet-transform
19 |    mra
20 |    wavelet-packets
21 |    cwt
22 |    thresholding-functions
23 |    other-functions
24 | 


--------------------------------------------------------------------------------
/doc/source/ref/iswt-inverse-stationary-wavelet-transform.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-iswt:
 2 | 
 3 | .. currentmodule:: pywt
 4 | 
 5 | Inverse Stationary Wavelet Transform
 6 | ------------------------------------
 7 | 
 8 | Inverse :ref:`stationary wavelet transforms ` are provided.
 9 | 
10 | **Note**: These inverse transforms are not yet optimized for speed.  Only, the
11 | n-dimensional inverse transform currently has ``axes`` support.
12 | 
13 | Multilevel 1D ``iswt``
14 | ~~~~~~~~~~~~~~~~~~~~~~
15 | 
16 | .. autofunction:: iswt
17 | 
18 | Multilevel 2D ``iswt2``
19 | ~~~~~~~~~~~~~~~~~~~~~~~
20 | 
21 | .. autofunction:: iswt2
22 | 
23 | Multilevel n-dimensional ``iswtn``
24 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 | 
26 | .. autofunction:: iswtn
27 | 


--------------------------------------------------------------------------------
/doc/source/ref/mra.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-mra:
 2 | 
 3 | .. currentmodule:: pywt
 4 | 
 5 | Multiresolution Analysis
 6 | ------------------------
 7 | 
 8 | The functions in this module can be used to project a signal onto wavelet
 9 | subspaces and an approximation subspace. This is an additive decomposition such
10 | that the sum of the coefficients equals the original signal. The projected
11 | signal coefficients remains temporally aligned with the original, regardless
12 | of the symmetry of the wavelet used for the analysis.
13 | 
14 | Multilevel 1D ``mra``
15 | ~~~~~~~~~~~~~~~~~~~~~
16 | 
17 | .. autofunction:: mra
18 | 
19 | Multilevel 2D ``mra2``
20 | ~~~~~~~~~~~~~~~~~~~~~~
21 | 
22 | .. autofunction:: mra2
23 | 
24 | Multilevel n-dimensional ``mran``
25 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 | 
27 | .. autofunction:: mran
28 | 
29 | Inverse Multilevel 1D ``imra``
30 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31 | 
32 | .. autofunction:: imra
33 | 
34 | Inverse Multilevel 2D ``imra2``
35 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36 | 
37 | .. autofunction:: imra2
38 | 
39 | Inverse Multilevel n-dimensional ``imran``
40 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41 | 
42 | .. autofunction:: imran
43 | 


--------------------------------------------------------------------------------
/doc/source/ref/nd-dwt-and-idwt.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-dwtn:
 2 | 
 3 | =================================================
 4 | nD Forward and Inverse Discrete Wavelet Transform
 5 | =================================================
 6 | 
 7 | .. currentmodule:: pywt
 8 | 
 9 | .. autosummary:: _multilevel
10 | 
11 | Single level - ``dwtn``
12 | -----------------------
13 | .. autofunction:: dwtn
14 | 
15 | Single level - ``idwtn``
16 | ------------------------
17 | .. autofunction:: idwtn
18 | 
19 | Multilevel decomposition - ``wavedecn``
20 | ---------------------------------------
21 | .. autofunction:: wavedecn
22 | 
23 | Multilevel reconstruction - ``waverecn``
24 | ----------------------------------------
25 | .. autofunction:: waverecn
26 | 
27 | Multilevel fully separable decomposition - ``fswavedecn``
28 | ---------------------------------------------------------
29 | .. autofunction:: fswavedecn
30 | 
31 | Multilevel fully separable reconstruction - ``fswaverecn``
32 | ----------------------------------------------------------
33 | .. autofunction:: fswaverecn
34 | 
35 | Multilevel fully separable reconstruction coeffs - ``FswavedecnResult``
36 | -----------------------------------------------------------------------
37 | .. autoclass:: FswavedecnResult
38 | 


--------------------------------------------------------------------------------
/doc/source/ref/other-functions.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-other:
 2 | 
 3 | .. currentmodule:: pywt
 4 | 
 5 | ===============
 6 | Other functions
 7 | ===============
 8 | 
 9 | 
10 | Integrating wavelet functions
11 | -----------------------------
12 | 
13 | .. autofunction:: integrate_wavelet
14 | 
15 | The result of the call depends on the ``wavelet`` argument:
16 | 
17 | * for orthogonal and continuous wavelets - an integral of the
18 |   wavelet function specified on an x-grid::
19 | 
20 |     [int_psi, x_grid] = integrate_wavelet(wavelet, precision)
21 | 
22 | * for other wavelets - integrals of decomposition and
23 |   reconstruction wavelet functions and a corresponding x-grid::
24 | 
25 |     [int_psi_d, int_psi_r, x_grid] = integrate_wavelet(wavelet, precision)
26 | 
27 | 
28 | Central frequency of ``psi`` wavelet function
29 | ---------------------------------------------
30 | 
31 | .. autofunction:: central_frequency
32 | 
33 | .. autofunction:: scale2frequency
34 | 
35 | 
36 | Quadrature Mirror Filter
37 | ------------------------
38 | 
39 | .. autofunction:: qmf
40 | 
41 | Orthogonal Filter Banks
42 | -----------------------
43 | 
44 | .. autofunction:: orthogonal_filter_bank
45 | 
46 | 
47 | Example Datasets
48 | ----------------
49 | 
50 | The following example datasets are available in the module ``pywt.data``:
51 | 
52 |   ============  =======================================
53 |     **name**               **description**
54 |   ============  =======================================
55 |    ecg           ECG waveform (1024 samples)
56 |    aero          grayscale image (512x512)
57 |    ascent        grayscale image (512x512)
58 |    camera        grayscale image (512x512)
59 |    nino          sea surface temperature (264 samples)
60 |    demo_signal   various synthetic 1d test signals
61 |   ============  =======================================
62 | 
63 | Each can be loaded via a function of the same name.
64 | 
65 | .. currentmodule:: pywt.data
66 | .. autofunction:: demo_signal
67 | 


--------------------------------------------------------------------------------
/doc/source/ref/swt-stationary-wavelet-transform.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-swt:
 2 | 
 3 | .. currentmodule:: pywt
 4 | 
 5 | Stationary Wavelet Transform
 6 | ----------------------------
 7 | 
 8 | `Stationary Wavelet Transform (SWT)
 9 | `_,
10 | also known as *Undecimated wavelet transform* or *Algorithme à trous* is a translation-invariance modification of the *Discrete Wavelet Transform* that
11 | does not decimate coefficients at every transformation level.
12 | 
13 | Multilevel 1D ``swt``
14 | ~~~~~~~~~~~~~~~~~~~~~
15 | 
16 | .. autofunction:: swt
17 | 
18 | Multilevel 2D ``swt2``
19 | ~~~~~~~~~~~~~~~~~~~~~~
20 | 
21 | .. autofunction:: swt2
22 | 
23 | Multilevel n-dimensional ``swtn``
24 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 | 
26 | .. autofunction:: swtn
27 | 
28 | Maximum decomposition level - ``swt_max_level``
29 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30 | 
31 | .. autofunction:: swt_max_level
32 | 


--------------------------------------------------------------------------------
/doc/source/ref/thresholding-functions.rst:
--------------------------------------------------------------------------------
 1 | .. _ref-thresholding:
 2 | .. currentmodule:: pywt
 3 | 
 4 | Thresholding functions
 5 | ======================
 6 | 
 7 | The :mod:`~pywt.thresholding` helper module implements the most popular signal
 8 | thresholding functions.
 9 | 
10 | Thresholding
11 | ------------
12 | 
13 | .. autofunction:: threshold
14 | .. autofunction:: threshold_firm
15 | 
16 | The left panel of the figure below illustrates that non-negative Garotte
17 | thresholding is intermediate between soft and hard thresholding.  Firm
18 | thresholding transitions between soft and hard thresholding behavior. It
19 | requires a pair of threshold values that define the width of the transition
20 | region.
21 | 
22 | .. plot:: pyplots/plot_thresholds.py
23 | 
24 | .. include:: ../common_refs.rst
25 | 


--------------------------------------------------------------------------------
/doc/source/regression/README.md:
--------------------------------------------------------------------------------
 1 | # Regression folder
 2 | 
 3 | This folder contains various useful examples illustrating how to use and how not
 4 | to use PyWavelets.
 5 | 
 6 | The examples are written in the [MyST markdown notebook
 7 | format](https://myst-nb.readthedocs.io/en/v0.13.2/use/markdown.html). This
 8 | allows each .md file to function simultaneously as documentation that can be fed
 9 | into Sphinx and as a source file that can be converted to the Jupyter notebook
10 | format (.ipynb), which can then be opened in notebook applications such as
11 | JupyterLab. For this reason, each example page in this folder includes a header template
12 | that adds a blurb to the top of each page about how the page can be
13 | run or downloaded as a Jupyter notebook.
14 | 
15 | There are a few shortcomings to this approach of generating the code cell outputs in
16 | the documentation pages at build time rather than hand editing them into the
17 | document source file. One is that we can no longer compare the generated outputs
18 | with the expected outputs as we used to do with doctest. Another is that we
19 | lose some control over how we want the outputs to appear, unless we use a workaround.
20 | 
21 | Here is the workaround we created. First we tell MyST-NB to remove the generated
22 | cell output from the documentation page by adding the `remove-output` tag to the
23 | `code-cell` directive in the markdown file. Then we hand code the output in a
24 | `code-block` directive, not to be confused with `code-cell`! The `code-cell`
25 | directive says "I am notebook code cell input, run me!" The `code-block`
26 | directive says, "I am just a block of code for documentation purposes, don't run
27 | me!" To the code block, we add the `.pywt-handcoded-cell-output` class so that
28 | we can style it to look the same as other cell outputs on the same HTML page.
29 | Finally, we tag the handcoded output with `jupyterlite_sphinx_strip` so that we
30 | can exclude it when converting from .md to .ipynb. That way only generated
31 | output appears in the .ipynb notebook.
32 | 
33 | To recap:
34 | 
35 | - We use the `remove-output` tag to remove the **generated** code cell output
36 |   during .md to .html conversion (this conversion is done by MyST-NB).
37 | - We use the `jupyterlite_sphinx_strip` tag to remove the **handcoded** output
38 |   during .md to .ipynb conversion (this conversion is done by Jupytext).
39 | 
40 | Example markdown:
41 | 
42 |     ```{code-cell}
43 |     :tags: [raises-exception, remove-output]
44 |     1 / 0
45 |     ```
46 | 
47 |     +++ {"tags" ["jupyterlite_sphinx_strip"]}
48 | 
49 |     ```{code-block} python
50 |     :class: pywt-handcoded-cell-output
51 |     Traceback (most recent call last):
52 |     ...
53 |     ZeroDivisionError: division by zero
54 |     ```
55 | 


--------------------------------------------------------------------------------
/doc/source/regression/gotchas.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | jupytext:
 3 |   text_representation:
 4 |     extension: .md
 5 |     format_name: myst
 6 |     format_version: 1.0.0
 7 |     jupytext_version: 1.16.1
 8 | kernelspec:
 9 |   display_name: Python 3 (ipykernel)
10 |   language: python
11 |   name: python3
12 | ---
13 | 
14 | +++ {"tags": ["jupyterlite_sphinx_strip"]}
15 | 
16 | ```{include} header.md
17 | 
18 | ```
19 | 
20 | # Gotchas
21 | 
22 | PyWavelets utilizes `NumPy` under the hood. That's why handling the data
23 | that contains `None` values can be surprising. `None` values are converted to
24 | 'not a number' (`numpy.nan`) values:
25 | 
26 | ```{code-cell}
27 | import numpy, pywt
28 | x = [None, None]
29 | mode = 'symmetric'
30 | wavelet = 'db1'
31 | cA, cD = pywt.dwt(x, wavelet, mode)
32 | ```
33 | 
34 | The results are:
35 | 
36 | ```{code-cell}
37 | numpy.all(numpy.isnan(cA))
38 | ```
39 | 
40 | 
41 | 
42 | ```{code-cell}
43 | numpy.all(numpy.isnan(cD))
44 | ```
45 | 
46 | 
47 | 
48 | ```{code-cell}
49 | rec = pywt.idwt(cA, cD, wavelet, mode)
50 | numpy.all(numpy.isnan(rec))
51 | ```
52 | 
53 | 
54 | 


--------------------------------------------------------------------------------
/doc/source/regression/header.md:
--------------------------------------------------------------------------------
 1 | ````{tip}
 2 | :class: pywt-margin-top-0
 3 | 
 4 | This page can also be run or downloaded as a Jupyter notebook.
 5 | 
 6 | - Run in a new tab using JupyterLite[^what-is-lite]:
 7 |   ```{notebooklite} {{ parent_docname }}.ipynb
 8 |   :new_tab: True
 9 |   ```
10 | - Download:
11 |   - Jupyter notebook: {download}`{{ parent_docname }}.ipynb <{{ parent_docname }}.ipynb>`
12 |   - MyST markdown: {download}`{{ parent_docname }}.md <{{ parent_docname }}.md>`
13 | 
14 | [^what-is-lite]: [JupyterLite](https://jupyterlite.readthedocs.io) is a distribution of JupyterLab that runs entirely within a web browser. All computations run in the browser; none are sent to a server.
15 | ````
16 | 


--------------------------------------------------------------------------------
/doc/source/regression/index.rst:
--------------------------------------------------------------------------------
 1 | .. _reg-index:
 2 | 
 3 | .. currentmodule:: pywt
 4 | 
 5 | Usage examples
 6 | ==============
 7 | 
 8 | The following pages contain various useful examples illustrating how to use and
 9 | how not to use PyWavelets.
10 | 
11 | .. toctree::
12 |    :maxdepth: 1
13 | 
14 |    wavelet
15 |    modes
16 |    dwt-idwt
17 |    multilevel
18 |    wp
19 |    wp2d
20 |    gotchas
21 | 
22 | The examples in this section are written in the `MyST markdown notebook format`_. This allows
23 | each .md file to function simultaneously as documentation that can be fed into
24 | Sphinx and as a source file that can be converted to the Jupyter notebook format
25 | (.ipynb), which can then be opened in notebook applications such as JupyterLab.
26 | For this reason, each example page in this folder includes a header template
27 | that adds a blurb to the top of each page about how the page can be run or
28 | downloaded as a Jupyter notebook. This is explained in greater detail in the
29 | `regression folder README`_.
30 | 
31 | For more usage examples see the `demo`_ directory in the source package.
32 | 
33 | 
34 | .. include:: ../common_refs.rst
35 | 
36 | .. _MyST markdown notebook format: https://myst-nb.readthedocs.io/en/v0.13.2/use/markdown.html
37 | .. _regression folder readme: https://github.com/PyWavelets/pywt/blob/main/doc/source/regression/README.md
38 | 


--------------------------------------------------------------------------------
/doc/source/regression/modes.md:
--------------------------------------------------------------------------------
  1 | ---
  2 | jupytext:
  3 |   text_representation:
  4 |     extension: .md
  5 |     format_name: myst
  6 |     format_version: 1.0.0
  7 |     jupytext_version: 1.16.1
  8 | kernelspec:
  9 |   display_name: Python 3 (ipykernel)
 10 |   language: python
 11 |   name: python3
 12 | ---
 13 | 
 14 | +++ {"tags": ["jupyterlite_sphinx_strip"]}
 15 | 
 16 | ```{include} header.md
 17 | 
 18 | ```
 19 | 
 20 | # Signal Extension Modes
 21 | 
 22 | Import `pywt` first:
 23 | 
 24 | ```{code-cell}
 25 | import pywt
 26 | ```
 27 | 
 28 | and construct a helper function that can format arrays in a consistent manner
 29 | across different systems. Please note that this function is just for the purpose of
 30 | this example and is not part of the PyWavelets library, and it is not necessary or
 31 | required to use it in your own code:
 32 | 
 33 | ```{code-cell}
 34 | def format_array(a):
 35 |     """Consistent array representation across different systems"""
 36 |     import numpy
 37 |     a = numpy.where(numpy.abs(a) < 1e-5, 0, a)
 38 |     return numpy.array2string(a, precision=5, separator=' ', suppress_small=True)
 39 | ```
 40 | 
 41 | A list of available signal extension [modes](Modes):
 42 | 
 43 | ```{code-cell}
 44 | pywt.Modes.modes
 45 | ```
 46 | 
 47 | An invalid mode name should raise a `ValueError`:
 48 | 
 49 | ```{code-cell}
 50 | ---
 51 | tags: [raises-exception, remove-output]
 52 | ---
 53 | pywt.dwt([1,2,3,4], 'db2', 'invalid')
 54 | ```
 55 | 
 56 | ```{code-block} python
 57 | :class: pywt-handcoded-cell-output
 58 | Traceback (most recent call last):
 59 | ...
 60 | ValueError: Unknown mode name 'invalid'.
 61 | ```
 62 | 
 63 | You can also refer to modes via the attributes of the `Modes` class:
 64 | 
 65 | ```{code-cell}
 66 | x = [1, 2, 1, 5, -1, 8, 4, 6]
 67 | for mode_name in ['zero', 'constant', 'symmetric', 'reflect', 'periodic', 'smooth', 'periodization']:
 68 |     mode = getattr(pywt.Modes, mode_name)
 69 |     cA, cD = pywt.dwt(x, 'db2', mode)
 70 |     print("Mode: %d (%s)" % (mode, mode_name))
 71 | ```
 72 | 
 73 | The default mode is [symmetric](Modes.symmetric):
 74 | 
 75 | ```{code-cell}
 76 | cA, cD = pywt.dwt(x, 'db2')
 77 | cA
 78 | ```
 79 | 
 80 | ```{code-cell}
 81 | cD
 82 | ```
 83 | 
 84 | ```{code-cell}
 85 | pywt.idwt(cA, cD, 'db2')
 86 | ```
 87 | 
 88 | Specify the mode using a keyword argument:
 89 | 
 90 | ```{code-cell}
 91 | cA, cD = pywt.dwt(x, 'db2', mode='symmetric')
 92 | cA
 93 | ```
 94 | 
 95 | ```{code-cell}
 96 | cD
 97 | ```
 98 | 
 99 | ```{code-cell}
100 | pywt.idwt(cA, cD, 'db2')
101 | ```
102 | 


--------------------------------------------------------------------------------
/doc/source/regression/multilevel.md:
--------------------------------------------------------------------------------
  1 | ---
  2 | jupytext:
  3 |   text_representation:
  4 |     extension: .md
  5 |     format_name: myst
  6 |     format_version: 1.0.0
  7 |     jupytext_version: 1.16.1
  8 | kernelspec:
  9 |   display_name: Python 3 (ipykernel)
 10 |   language: python
 11 |   name: python3
 12 | ---
 13 | 
 14 | +++ {"tags": ["jupyterlite_sphinx_strip"]}
 15 | 
 16 | ```{include} header.md
 17 | 
 18 | ```
 19 | 
 20 | # Multilevel DWT, IDWT and SWT
 21 | 
 22 | ## Multilevel DWT decomposition
 23 | 
 24 | Here is an example of multilevel DWT decomposition using the `db1` wavelet into
 25 | approximation and detail coefficients:
 26 | 
 27 | ```{code-cell}
 28 | import pywt
 29 | x = [3, 7, 1, 1, -2, 5, 4, 6]
 30 | db1 = pywt.Wavelet('db1')
 31 | cA3, cD3, cD2, cD1 = pywt.wavedec(x, db1)
 32 | ```
 33 | 
 34 | ```{code-cell}
 35 | cA3
 36 | ```
 37 | 
 38 | ```{code-cell}
 39 | cD3
 40 | ```
 41 | 
 42 | ```{code-cell}
 43 | cD2
 44 | ```
 45 | 
 46 | ```{code-cell}
 47 | cD1
 48 | ```
 49 | 
 50 | The number of levels in the decomposition can be determined as well:
 51 | 
 52 | ```{code-cell}
 53 | pywt.dwt_max_level(len(x), db1)
 54 | ```
 55 | 
 56 | or decompose to a specific level:
 57 | 
 58 | ```{code-cell}
 59 | cA2, cD2, cD1 = pywt.wavedec(x, db1, mode='constant', level=2)
 60 | ```
 61 | 
 62 | ## Multilevel IDWT reconstruction
 63 | 
 64 | ```{code-cell}
 65 | coeffs = pywt.wavedec(x, db1)
 66 | pywt.waverec(coeffs, db1)
 67 | ```
 68 | 
 69 | ## Multilevel SWT decomposition
 70 | 
 71 | ```{code-cell}
 72 | x = [3, 7, 1, 3, -2, 6, 4, 6]
 73 | (cA2, cD2), (cA1, cD1) = pywt.swt(x, db1, level=2)
 74 | ```
 75 | 
 76 | ```{code-cell}
 77 | cA1
 78 | ```
 79 | 
 80 | ```{code-cell}
 81 | cD1
 82 | ```
 83 | 
 84 | ```{code-cell}
 85 | cA2
 86 | ```
 87 | 
 88 | ```{code-cell}
 89 | cD2
 90 | ```
 91 | 
 92 | ```{code-cell}
 93 | [(cA2, cD2)] = pywt.swt(cA1, db1, level=1, start_level=1)
 94 | ```
 95 | 
 96 | ```{code-cell}
 97 | cA2
 98 | ```
 99 | 
100 | ```{code-cell}
101 | cD2
102 | ```
103 | 
104 | ```{code-cell}
105 | coeffs = pywt.swt(x, db1)
106 | len(coeffs)
107 | ```
108 | 
109 | ```{code-cell}
110 | pywt.swt_max_level(len(x))
111 | ```
112 | 


--------------------------------------------------------------------------------
/doc/source/release.0.3.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/0.3.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.0.4.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/0.4.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.0.5.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/0.5.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.0.5.1.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/0.5.1-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.0.5.2.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/0.5.2-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.0.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.0.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.0.1.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.0.1-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.0.2.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.0.2-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.0.3.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.0.3-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.1.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.1.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.1.1.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.1.1-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.2.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.2.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.3.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.3.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.4.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.4.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.4.1.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.4.1-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.5.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.5.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.6.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.6.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.7.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.7.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/release.1.8.0.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../release/1.8.0-notes.rst
2 | 


--------------------------------------------------------------------------------
/doc/source/releasenotes.rst:
--------------------------------------------------------------------------------
 1 | Release Notes
 2 | =============
 3 | 
 4 | .. toctree::
 5 |    :maxdepth: 1
 6 | 
 7 |    release.1.8.0
 8 |    release.1.7.0
 9 |    release.1.6.0
10 |    release.1.5.0
11 |    release.1.4.1
12 |    release.1.4.0
13 |    release.1.3.0
14 |    release.1.2.0
15 |    release.1.1.1
16 |    release.1.0.0
17 |    release.1.0.3
18 |    release.1.0.2
19 |    release.1.0.1
20 |    release.1.1.0
21 |    release.0.5.2
22 |    release.0.5.1
23 |    release.0.5.0
24 |    release.0.4.0
25 |    release.0.3.0
26 | 


--------------------------------------------------------------------------------
/doc/source/substitutions.rst:
--------------------------------------------------------------------------------
1 | .. |wavelet| replace::
2 |    Wavelet to use in the transform. This can be a name of the wavelet from the :func:`wavelist` list or a :class:`Wavelet` object instance.
3 | 


--------------------------------------------------------------------------------
/doc/source/try_examples.json:
--------------------------------------------------------------------------------
1 | {
2 |     "global_min_height": "600px"
3 | }
4 | 


--------------------------------------------------------------------------------
/meson.build:
--------------------------------------------------------------------------------
 1 | project(
 2 |   'PyWavelets',
 3 |   'c', 'cython',
 4 |   version: '1.9.0.dev0',
 5 |   license: 'MIT',
 6 |   meson_version: '>= 1.1.0',
 7 |   default_options: [
 8 |     'buildtype=debugoptimized',
 9 |     'b_ndebug=if-release',
10 |     'c_std=c17',
11 |   ],
12 | )
13 | 
14 | cython = find_program('cython')
15 | 
16 | py = import('python').find_installation(pure: false)
17 | py_dep = py.dependency()
18 | 
19 | subdir('pywt')
20 | 


--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
 1 | # Note that in maintenance branches, all build dependencies should
 2 | # have an upper bound equal to the most recent already-released version
 3 | # of the dependency. This to prevent that a future backwards-incompatible
 4 | # release will break the source build of a PyWavelets release.
 5 | # Do accept micro (bug-fix) releases.
 6 | 
 7 | [build-system]
 8 | build-backend = "mesonpy"
 9 | requires = [
10 |     "meson-python>=0.16.0",
11 |     "Cython>=3.0.4",
12 | 
13 |     # numpy requirement for wheel builds for distribution on PyPI - building
14 |     # against 2.x yields wheels that are also compatible with numpy 1.x at
15 |     # runtime.
16 |     # Note that building against numpy 1.x works fine too - users and
17 |     # redistributors can do this by installing the numpy version they like and
18 |     # disabling build isolation.
19 |     "numpy>=2.0.0; python_version<'3.13'",
20 |     "numpy>=2.1.0; python_version>='3.13'",
21 | ]
22 | 
23 | [project]
24 | name = "PyWavelets"
25 | version = "1.9.0.dev0"
26 | # TODO: add `license-files` once PEP 639 is accepted (see meson-python#88)
27 | #       at that point, no longer include them in `py3.install_sources()`
28 | license = {file = "LICENSE"}
29 | maintainers = [
30 |     {name = "The PyWavelets Developers", email = "pywavelets@googlegroups.com"}
31 | ]
32 | description = "PyWavelets, wavelet transform module"
33 | requires-python = ">=3.11"
34 | dependencies = ["numpy>=1.25,<3"]
35 | readme = "README.rst"
36 | classifiers = [
37 |     "Development Status :: 5 - Production/Stable",
38 |     "Intended Audience :: Developers",
39 |     "Intended Audience :: Education",
40 |     "Intended Audience :: Science/Research",
41 |     "License :: OSI Approved :: MIT License",
42 |     "Operating System :: OS Independent",
43 |     "Programming Language :: C",
44 |     "Programming Language :: Python",
45 |     "Programming Language :: Python :: 3",
46 |     "Programming Language :: Python :: 3.11",
47 |     "Programming Language :: Python :: 3.12",
48 |     "Programming Language :: Python :: 3.13",
49 |     "Topic :: Software Development :: Libraries :: Python Modules"
50 | ]
51 | 
52 | [project.urls]
53 | homepage = "https://github.com/PyWavelets/pywt"
54 | source = "https://github.com/PyWavelets/pywt"
55 | documentation = "https://pywavelets.readthedocs.io/"
56 | 
57 | [tool.ruff]
58 | line-length = 88
59 | target-version = 'py310'
60 | lint.select = [
61 |     "I",
62 |     "UP",
63 |     "C4",
64 |     "E713",
65 |     "NPY201",
66 |     "PIE",
67 |     "PGH003",
68 |     "PLR0402",
69 |     "SIM101",
70 |     "SIM109",
71 |     "SIM110",
72 |     "SIM118",
73 |     "SIM2",
74 | ]
75 | lint.ignore = [
76 |      "UP038", # https://github.com/astral-sh/ruff/issues/7871
77 | ]
78 | 
79 | [tool.spin]
80 | package = "pywt"
81 | 
82 | [tool.spin.commands]
83 | "Build" = [
84 |   "spin.cmds.meson.build",
85 |   "spin.cmds.meson.test",
86 |   "spin.cmds.build.sdist"
87 | ]
88 | Environments = [
89 |     'spin.cmds.meson.run',
90 |     'spin.cmds.meson.ipython',
91 |     'spin.cmds.meson.python',
92 | ]
93 | Documentation = ["spin.cmds.meson.docs"]
94 | 


--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
 1 | [pytest]
 2 | addopts = -l
 3 | norecursedirs = doc tools pywt/_extensions
 4 | doctest_optionflags = NORMALIZE_WHITESPACE ELLIPSIS ALLOW_UNICODE ALLOW_BYTES
 5 | 
 6 | filterwarnings =
 7 |     error
 8 | # Filter out annoying import messages.
 9 |     ignore:Not importing directory
10 |     ignore:numpy.dtype size changed
11 |     ignore:numpy.ufunc size changed
12 |     ignore::UserWarning:cpuinfo,
13 | 


--------------------------------------------------------------------------------
/pywt/__init__.py:
--------------------------------------------------------------------------------
 1 | # flake8: noqa
 2 | 
 3 | # Copyright (c) 2006-2012 Filip Wasilewski 
 4 | # Copyright (c) 2012-2020 The PyWavelets Developers
 5 | #                         
 6 | # See LICENSE for more details.
 7 | 
 8 | """
 9 | Discrete forward and inverse wavelet transform, stationary wavelet transform,
10 | wavelet packets signal decomposition and reconstruction module.
11 | """
12 | 
13 | from ._extensions._pywt import *
14 | from ._functions import *
15 | from ._multilevel import *
16 | from ._multidim import *
17 | from ._thresholding import *
18 | from ._wavelet_packets import *
19 | from ._dwt import *
20 | from ._swt import *
21 | from ._cwt import *
22 | from ._mra import *
23 | 
24 | from . import data
25 | 
26 | __all__ = [s for s in dir() if not s.startswith('_')]
27 | try:
28 |     # In Python 2.x the name of the tempvar leaks out of the list
29 |     # comprehension.  Delete it to not make it show up in the main namespace.
30 |     del s
31 | except NameError:
32 |     pass
33 | 
34 | from pywt.version import version as __version__
35 | 
36 | from ._pytesttester import PytestTester
37 | test = PytestTester(__name__)
38 | del PytestTester
39 | 


--------------------------------------------------------------------------------
/pywt/_c99_config.py.in:
--------------------------------------------------------------------------------
1 | # Autogenerated file containing compile-time definitions
2 | 
3 | _have_c99_complex = @have_c99_complex@
4 | 


--------------------------------------------------------------------------------
/pywt/_extensions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/_extensions/__init__.py


--------------------------------------------------------------------------------
/pywt/_extensions/_cwt.pxd:
--------------------------------------------------------------------------------
1 | from ._pywt cimport ContinuousWavelet, data_t
2 | 
3 | 
4 | cpdef cwt_psi_single(data_t[::1] data, ContinuousWavelet wavelet, size_t output_len)
5 | 


--------------------------------------------------------------------------------
/pywt/_extensions/_dwt.pxd:
--------------------------------------------------------------------------------
1 | from ._pywt cimport Wavelet, cdata_t
2 | 
3 | 
4 | cpdef upcoef(bint do_rec_a, cdata_t[::1] coeffs, Wavelet wavelet, int level,
5 |              size_t take)
6 | 


--------------------------------------------------------------------------------
/pywt/_extensions/_pywt.pxd:
--------------------------------------------------------------------------------
 1 | from . cimport wavelet
 2 | cimport numpy as np
 3 | 
 4 | np.import_array()
 5 | 
 6 | include "config.pxi"
 7 | 
 8 | ctypedef Py_ssize_t pywt_index_t
 9 | 
10 | ctypedef fused data_t:
11 |     np.float32_t
12 |     np.float64_t
13 | 
14 | cdef int have_c99_complex
15 | IF HAVE_C99_CPLX:
16 |     ctypedef fused cdata_t:
17 |         np.float32_t
18 |         np.float64_t
19 |         np.complex64_t
20 |         np.complex128_t
21 |     have_c99_complex = 1
22 | ELSE:
23 |     ctypedef data_t cdata_t
24 |     have_c99_complex = 0
25 | 
26 | cdef public class Wavelet [type WaveletType, object WaveletObject]:
27 |     cdef wavelet.DiscreteWavelet* w
28 | 
29 |     cdef readonly name
30 |     cdef readonly number
31 | 
32 | cdef public class ContinuousWavelet [type ContinuousWaveletType, object ContinuousWaveletObject]:
33 |     cdef wavelet.ContinuousWavelet* w
34 | 
35 |     cdef readonly name
36 |     cdef readonly number
37 |     cdef readonly dt
38 | 
39 | cpdef np.dtype _check_dtype(data)
40 | 
41 | # FIXME: To be removed
42 | cdef c_wavelet_from_object(wavelet)
43 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/common.c:
--------------------------------------------------------------------------------
 1 | /* Copyright (c) 2006-2012 Filip Wasilewski 
 2 |  * Copyright (c) 2012-2016 The PyWavelets Developers
 3 |  *                         
 4 |  * See COPYING for license details.
 5 |  */
 6 | 
 7 | #include "common.h"
 8 | #include  // for U*_MAX
 9 | 
10 | // MSVC <= 2008 does not have stdint.h, but defines SIZE_MAX in limits.h
11 | #if (!defined(_MSC_VER)) || (_MSC_VER > 1500)
12 | #include  // for SIZE_MAX
13 | #endif /* _MSC_VER */
14 | 
15 | /* Returns the floor of the base-2 log of it's input
16 |  *
17 |  * Undefined for x = 0
18 |  */
19 | unsigned char size_log2(size_t x){
20 | #if defined(_MSC_VER)
21 |     unsigned long i;
22 | #if SIZE_MAX == 0xFFFFFFFF
23 |     _BitScanReverse(&i, x);
24 | #elif SIZE_MAX == 0xFFFFFFFFFFFFFFFF
25 |     _BitScanReverse64(&i, x);
26 | #else
27 | #error "Unrecognized SIZE_MAX"
28 | #endif /* SIZE_MAX */
29 |     return i;
30 | #else
31 |     // GCC and clang
32 |     // Safe cast: 0 <= clzl < arch_bits (64) where result is defined
33 | #if SIZE_MAX == UINT_MAX
34 |     unsigned char leading_zeros = (unsigned char) __builtin_clz(x);
35 | #elif SIZE_MAX == ULONG_MAX
36 |     unsigned char leading_zeros = (unsigned char) __builtin_clzl(x);
37 | #elif SIZE_MAX == ULLONG_MAX
38 |     unsigned char leading_zeros = (unsigned char) __builtin_clzll(x);
39 | #else
40 | #error "Unrecognized SIZE_MAX"
41 | #endif /* SIZE_MAX */
42 |     return sizeof(size_t) * 8 - leading_zeros - 1;
43 | #endif /* _MSC_VER */
44 | }
45 | 
46 | /* buffers and max levels params */
47 | 
48 | size_t dwt_buffer_length(size_t input_len, size_t filter_len, MODE mode){
49 |     if(input_len < 1 || filter_len < 1)
50 |         return 0;
51 | 
52 |     switch(mode){
53 |             case MODE_PERIODIZATION:
54 |                 return input_len / 2 + ((input_len%2) ? 1 : 0);
55 |             default:
56 |                 return (input_len + filter_len - 1) / 2;
57 |     }
58 | }
59 | 
60 | size_t reconstruction_buffer_length(size_t coeffs_len, size_t filter_len){
61 |     if(coeffs_len < 1 || filter_len < 1)
62 |         return 0;
63 | 
64 |     return 2*coeffs_len+filter_len-2;
65 | }
66 | 
67 | size_t idwt_buffer_length(size_t coeffs_len, size_t filter_len, MODE mode){
68 |     switch(mode){
69 |             case MODE_PERIODIZATION:
70 |                 return 2*coeffs_len;
71 |             default:
72 |                 return 2*coeffs_len-filter_len+2;
73 |     }
74 | }
75 | 
76 | size_t swt_buffer_length(size_t input_len){
77 |     return input_len;
78 | }
79 | 
80 | unsigned char dwt_max_level(size_t input_len, size_t filter_len){
81 |     if(filter_len <= 1 || input_len < (filter_len-1))
82 |         return 0;
83 | 
84 |     return size_log2(input_len/(filter_len-1));
85 | }
86 | 
87 | unsigned char swt_max_level(size_t input_len){
88 |     /* check how many times input_len is divisible by 2 */
89 |     unsigned char j = 0;
90 |     while (input_len > 0){
91 |         if (input_len % 2)
92 |             return j;
93 |         input_len /= 2;
94 |         j++;
95 |     }
96 |     return j;
97 | }
98 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/convolution.c:
--------------------------------------------------------------------------------
 1 | #include "convolution.h"
 2 | 
 3 | #ifdef TYPE
 4 | #error TYPE should not be defined here.
 5 | #else
 6 | 
 7 | #ifdef REAL_TYPE
 8 | #error REAL_TYPE should not be defined here.
 9 | #else
10 | 
11 | #define TYPE float
12 | #define REAL_TYPE float
13 | #include "convolution.template.c"
14 | #undef REAL_TYPE
15 | #undef TYPE
16 | 
17 | #define TYPE double
18 | #define REAL_TYPE double
19 | #include "convolution.template.c"
20 | #undef REAL_TYPE
21 | #undef TYPE
22 | 
23 | #ifdef HAVE_C99_COMPLEX
24 |     #define TYPE float_complex
25 |     #define REAL_TYPE float
26 |     #include "convolution.template.c"
27 |     #undef REAL_TYPE
28 |     #undef TYPE
29 | 
30 |     #define TYPE double_complex
31 |     #define REAL_TYPE double
32 |     #include "convolution.template.c"
33 |     #undef REAL_TYPE
34 |     #undef TYPE
35 | #endif
36 | 
37 | #endif /* REAL_TYPE */
38 | #endif /* TYPE */
39 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/convolution.h:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include "common.h"
 4 | 
 5 | #ifdef TYPE
 6 | #error TYPE should not be defined here.
 7 | #else
 8 | 
 9 | #ifdef REAL_TYPE
10 | #error REAL_TYPE should not be defined here.
11 | #else
12 | 
13 | #define TYPE float
14 | #define REAL_TYPE float
15 | #include "convolution.template.h"
16 | #undef REAL_TYPE
17 | #undef TYPE
18 | 
19 | #define TYPE double
20 | #define REAL_TYPE double
21 | #include "convolution.template.h"
22 | #undef REAL_TYPE
23 | #undef TYPE
24 | 
25 | #ifdef HAVE_C99_COMPLEX
26 |     #define TYPE float_complex
27 |     #define REAL_TYPE float
28 |     #include "convolution.template.h"
29 |     #undef REAL_TYPE
30 |     #undef TYPE
31 | 
32 |     #define TYPE double_complex
33 |     #define REAL_TYPE double
34 |     #include "convolution.template.h"
35 |     #undef REAL_TYPE
36 |     #undef TYPE
37 | #endif
38 | 
39 | #endif /* REAL_TYPE */
40 | #endif /* TYPE */
41 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/convolution.template.h:
--------------------------------------------------------------------------------
  1 | /* Copyright (c) 2006-2012 Filip Wasilewski 
  2 |  * Copyright (c) 2012-2016 The PyWavelets Developers
  3 |  *                         
  4 |  * See COPYING for license details.
  5 |  */
  6 | 
  7 | #include "templating.h"
  8 | 
  9 | 
 10 | #ifndef REAL_TYPE
 11 | #error REAL_TYPE must be defined here.
 12 | #else
 13 | 
 14 | #ifndef TYPE
 15 | #error TYPE must be defined here.
 16 | #else
 17 | 
 18 | #include "common.h"
 19 | 
 20 | #if defined _MSC_VER
 21 | #define restrict __restrict
 22 | #elif defined __GNUC__
 23 | #define restrict __restrict__
 24 | #endif
 25 | 
 26 | /* Performs convolution of input with filter and downsamples by taking every
 27 |  * step-th element from the result.
 28 |  *
 29 |  * input    - input data
 30 |  * N        - input data length
 31 |  * filter   - filter data
 32 |  * F        - filter data length
 33 |  * output   - output data
 34 |  * step     - decimation step
 35 |  * mode     - signal extension mode
 36 |  */
 37 | 
 38 | /* memory efficient version */
 39 | 
 40 | int CAT(TYPE, _downsampling_convolution)(const TYPE * const restrict input, const size_t N,
 41 |                                          const REAL_TYPE * const restrict filter, const size_t F,
 42 |                                          TYPE * const restrict output, const size_t step,
 43 |                                          MODE mode);
 44 | 
 45 | 
 46 | /* downsampling convolution routine specific to periodization mode.
 47 |  *
 48 |  * input    - input data
 49 |  * N        - input data length
 50 |  * filter   - filter data
 51 |  * F        - filter data length
 52 |  * output   - output data
 53 |  * step     - decimation step
 54 |  * fstep    - step size between non-zero entries in filter
 55 |  *            (used to improve performance for the multilevel swt)
 56 |  */
 57 | int CAT(TYPE, _downsampling_convolution_periodization)(
 58 |     const TYPE * const restrict input, const size_t N,
 59 |     const REAL_TYPE * const restrict filter, const size_t F,
 60 |     TYPE * const restrict output, const size_t step,
 61 |     const size_t fstep);
 62 | 
 63 | /*
 64 |  * Performs normal (full) convolution of "upsampled" input coeffs array with
 65 |  * filter Requires zero-filled output buffer (adds values instead of
 66 |  * overwriting - can be called many times with the same output).
 67 |  *
 68 |  * input    - input data
 69 |  * N        - input data length
 70 |  * filter   - filter data
 71 |  * F        - filter data length
 72 |  * output   - output data
 73 |  * O        - output length (currently not used)
 74 |  * mode     - signal extension mode
 75 |  */
 76 | 
 77 | int CAT(TYPE, _upsampling_convolution_full)(const TYPE * const restrict input, const size_t N,
 78 |                                             const REAL_TYPE * const restrict filter, const size_t F,
 79 |                                             TYPE * const restrict output, const size_t O);
 80 | 
 81 | /* Performs valid convolution (signals must overlap)
 82 |  * Extends (virtually) input for MODE_PERIODIZATION.
 83 |  */
 84 | 
 85 | int CAT(TYPE, _upsampling_convolution_valid_sf)(const TYPE * const restrict input, const size_t N,
 86 |                                                 const REAL_TYPE * const restrict filter, const size_t F,
 87 |                                                 TYPE * const restrict output, const size_t O,
 88 |                                                 MODE mode);
 89 | 
 90 | /* TODO
 91 |  * for SWT
 92 |  * int upsampled_filter_convolution(const TYPE * const restrict input, const int N,
 93 |  *                                  const REAL_TYPE * const restrict filter, const int F,
 94 |  *                                  TYPE * const restrict output, int step, int mode);
 95 |  */
 96 | 
 97 | 
 98 | 
 99 | #undef restrict
100 | #endif /* REAL_TYPE */
101 | #endif /* TYPE */
102 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/cwt.c:
--------------------------------------------------------------------------------
 1 | #include "cwt.h"
 2 | 
 3 | #ifdef TYPE
 4 | #error TYPE should not be defined here.
 5 | #else
 6 | 
 7 | 
 8 | #define TYPE float
 9 | #include "cwt.template.c"
10 | #undef TYPE
11 | 
12 | #define TYPE double
13 | #include "cwt.template.c"
14 | #undef TYPE
15 | 
16 | #endif /* TYPE */
17 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/cwt.h:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include "common.h"
 4 | #include "convolution.h"
 5 | #include "wavelets.h"
 6 | 
 7 | 
 8 | #ifdef TYPE
 9 | #error TYPE should not be defined here.
10 | #else
11 | 
12 | 
13 | #define TYPE float
14 | #include "cwt.template.h"
15 | #undef TYPE
16 | 
17 | #define TYPE double
18 | #include "cwt.template.h"
19 | #undef TYPE
20 | 
21 | #endif /* TYPE */
22 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/cwt.template.h:
--------------------------------------------------------------------------------
 1 | /* Copyright (c) 2016 Holger Nahrstaedt */
 2 | /* See COPYING for license details. */
 3 | 
 4 | 
 5 | #include "templating.h"
 6 | 
 7 | #ifndef TYPE
 8 | #error TYPE must be defined here.
 9 | #else
10 | 
11 | #include "cwt.h"
12 | 
13 | #if defined _MSC_VER
14 | #define restrict __restrict
15 | #elif defined __GNUC__
16 | #define restrict __restrict__
17 | #endif
18 | 
19 | 
20 | void CAT(TYPE, _gaus)(const TYPE * const restrict input,
21 |                               TYPE * const restrict output, const size_t N,
22 |                               const size_t number);
23 | 
24 | 
25 | void CAT(TYPE, _mexh)(const TYPE * const restrict input, TYPE * const restrict output, const size_t N);
26 | 
27 | void CAT(TYPE, _morl)(const TYPE * const restrict input, TYPE * const restrict output, const size_t N);
28 | 
29 | void CAT(TYPE, _cgau)(const TYPE * const restrict input,
30 |                               TYPE * const restrict output_r, TYPE * const restrict output_i, const size_t N,
31 |                               const size_t number);
32 | 
33 | 
34 | void CAT(TYPE, _shan)(const TYPE * const restrict input, TYPE * const restrict output_r, TYPE * const restrict output_i, const size_t N,
35 |                               const TYPE  FB, const TYPE  FC);
36 | 
37 | void CAT(TYPE, _fbsp)(const TYPE * const restrict input, TYPE * const restrict output_r, TYPE * const restrict output_i, const size_t N,
38 |                               const unsigned int M, const TYPE  FB, const TYPE  FC);
39 | 
40 | void CAT(TYPE, _cmor)(const TYPE * const restrict input, TYPE * const restrict output_r, TYPE * const restrict output_i, const size_t N,
41 |                               const TYPE  FB, const TYPE  FC);
42 | #endif /* TYPE */
43 | #undef restrict
44 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/templating.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | 
3 | #define CAT_HELPER(A, B) A##B
4 | #define CAT(A, B) CAT_HELPER(A, B)
5 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/wavelets.h:
--------------------------------------------------------------------------------
  1 | /* Copyright (c) 2006-2012 Filip Wasilewski 
  2 |  * Copyright (c) 2012-2016 The PyWavelets Developers
  3 |  *                         
  4 |  * See COPYING for license details.
  5 |  */
  6 | 
  7 | #pragma once
  8 | 
  9 | #include "common.h"
 10 | 
 11 | /* Wavelet symmetry properties */
 12 | typedef enum {
 13 |     UNKNOWN = -1,
 14 |     ASYMMETRIC = 0,
 15 |     NEAR_SYMMETRIC = 1,
 16 |     SYMMETRIC = 2,
 17 |     ANTI_SYMMETRIC = 3
 18 | } SYMMETRY;
 19 | 
 20 | /* Wavelet name */
 21 | typedef enum {
 22 |     HAAR,
 23 |     RBIO,
 24 |     DB,
 25 |     SYM,
 26 |     COIF,
 27 |     BIOR,
 28 |     DMEY,
 29 |     GAUS,
 30 |     MEXH,
 31 |     MORL,
 32 |     CGAU,
 33 |     SHAN,
 34 |     FBSP,
 35 |     CMOR
 36 | } WAVELET_NAME;
 37 | 
 38 | 
 39 | /* Wavelet structure holding pointers to filter arrays and property attributes */
 40 | typedef struct  {
 41 |     /* Wavelet properties */
 42 | 
 43 |     pywt_index_t support_width;
 44 | 
 45 |     SYMMETRY symmetry;
 46 | 
 47 |     unsigned int orthogonal:1;
 48 |     unsigned int biorthogonal:1;
 49 |     unsigned int compact_support:1;
 50 | 
 51 |     int _builtin;
 52 |     char* family_name;
 53 |     char* short_name;
 54 | 
 55 | 
 56 | } BaseWavelet;
 57 | 
 58 | typedef struct {
 59 |     BaseWavelet base;
 60 |     double* dec_hi_double;  /* highpass decomposition */
 61 |     double* dec_lo_double;  /* lowpass decomposition */
 62 |     double* rec_hi_double;  /* highpass reconstruction */
 63 |     double* rec_lo_double;  /* lowpass reconstruction */
 64 |     float* dec_hi_float;
 65 |     float* dec_lo_float;
 66 |     float* rec_hi_float;
 67 |     float* rec_lo_float;
 68 |     size_t dec_len;   /* length of decomposition filter */
 69 |     size_t rec_len;   /* length of reconstruction filter */
 70 | 
 71 |     int vanishing_moments_psi;
 72 |     int vanishing_moments_phi;
 73 | 
 74 | } DiscreteWavelet;
 75 | 
 76 | typedef struct {
 77 | 
 78 |     BaseWavelet base;
 79 |     float lower_bound;
 80 |     float upper_bound;
 81 |     /* Parameters for shan, fbsp, cmor*/
 82 |     int complex_cwt;
 83 |     float center_frequency;
 84 |     float bandwidth_frequency;
 85 |     unsigned int fbsp_order;
 86 | 
 87 | } ContinuousWavelet;
 88 | 
 89 | 
 90 | int is_discrete_wavelet(WAVELET_NAME name);
 91 | 
 92 | /*
 93 |  * Allocate Wavelet struct and set its attributes
 94 |  * name - (currently) a character codename of a wavelet family
 95 |  * order - order of the wavelet (ie. coif3 has order 3)
 96 |  */
 97 | DiscreteWavelet* discrete_wavelet(WAVELET_NAME name, unsigned int order);
 98 | ContinuousWavelet* continuous_wavelet(WAVELET_NAME name, unsigned int order);
 99 | /*
100 |  * Allocate blank Discrete Wavelet with zero-filled filters of given length
101 |  */
102 | DiscreteWavelet* blank_discrete_wavelet(size_t filters_length);
103 | 
104 | ContinuousWavelet* blank_continuous_wavelet(void);
105 | 
106 | /* Deep copy Discrete Wavelet */
107 | DiscreteWavelet* copy_discrete_wavelet(DiscreteWavelet* base);
108 | 
109 | /*
110 |  * Free wavelet struct. Use this to free Wavelet allocated with
111 |  * wavelet(...) or blank_wavelet(...) functions.
112 |  */
113 | void free_discrete_wavelet(DiscreteWavelet *wavelet);
114 | 
115 | void free_continuous_wavelet(ContinuousWavelet *wavelet);
116 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/wavelets_coeffs.h:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #ifdef TYPE
 4 | #error TYPE should not be defined here.
 5 | #else
 6 | 
 7 | /* ignore warning about initializing floats from double values */
 8 | #if defined _MSC_VER
 9 | #pragma warning (push)
10 | #pragma warning (disable:4305)
11 | #elif defined __GNUC__
12 | #pragma GCC diagnostic push
13 | #pragma GCC diagnostic ignored "-Wconversion"
14 | #endif
15 | 
16 | #define TYPE float
17 | #include "wavelets_coeffs.template.h"
18 | #undef TYPE
19 | 
20 | #if defined _MSC_VER
21 | #pragma warning (pop)
22 | #elif defined __GNUC__
23 | #pragma GCC diagnostic pop
24 | #endif
25 | 
26 | #define TYPE double
27 | #include "wavelets_coeffs.template.h"
28 | #undef TYPE
29 | 
30 | #endif /* TYPE */
31 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/wt.c:
--------------------------------------------------------------------------------
 1 | #include "wt.h"
 2 | 
 3 | #ifdef TYPE
 4 | #error TYPE should not be defined here.
 5 | #else
 6 | 
 7 | #ifdef REAL_TYPE
 8 | #error REAL_TYPE should not be defined here.
 9 | #else
10 | 
11 | #define TYPE float
12 | #define REAL_TYPE float
13 | #include "wt.template.c"
14 | #undef REAL_TYPE
15 | #undef TYPE
16 | 
17 | #define TYPE double
18 | #define REAL_TYPE double
19 | #include "wt.template.c"
20 | #undef REAL_TYPE
21 | #undef TYPE
22 | 
23 | #ifdef HAVE_C99_COMPLEX
24 |     #define TYPE float_complex
25 |     #define REAL_TYPE float
26 |     #include "wt.template.c"
27 |     #undef REAL_TYPE
28 |     #undef TYPE
29 | 
30 |     #define TYPE double_complex
31 |     #define REAL_TYPE double
32 |     #include "wt.template.c"
33 |     #undef REAL_TYPE
34 |     #undef TYPE
35 | #endif
36 | 
37 | #endif /* REAL_TYPE */
38 | #endif /* TYPE */
39 | 


--------------------------------------------------------------------------------
/pywt/_extensions/c/wt.h:
--------------------------------------------------------------------------------
 1 | #pragma once
 2 | 
 3 | #include "common.h"
 4 | #include "convolution.h"
 5 | #include "wavelets.h"
 6 | 
 7 | #ifdef TYPE
 8 | #error TYPE should not be defined here.
 9 | #else
10 | 
11 | #ifdef REAL_TYPE
12 | #error REAL_TYPE should not be defined here.
13 | #else
14 | 
15 | #define TYPE float
16 | #define REAL_TYPE float
17 | #include "wt.template.h"
18 | #undef REAL_TYPE
19 | #undef TYPE
20 | 
21 | #define TYPE double
22 | #define REAL_TYPE double
23 | #include "wt.template.h"
24 | #undef REAL_TYPE
25 | #undef TYPE
26 | 
27 | #ifdef HAVE_C99_COMPLEX
28 |     #define TYPE float_complex
29 |     #define REAL_TYPE float
30 |     #include "wt.template.h"
31 |     #undef REAL_TYPE
32 |     #undef TYPE
33 | 
34 |     #define TYPE double_complex
35 |     #define REAL_TYPE double
36 |     #include "wt.template.h"
37 |     #undef REAL_TYPE
38 |     #undef TYPE
39 | #endif
40 | 
41 | #endif /* REAL_TYPE */
42 | #endif /* TYPE */
43 | 


--------------------------------------------------------------------------------
/pywt/_extensions/common.pxd:
--------------------------------------------------------------------------------
 1 | cdef extern from "c/common.h":
 2 |     ctypedef int pywt_index_t
 3 | 
 4 |     cdef void* wtmalloc(long size)
 5 |     cdef void* wtcalloc(long len, long size)
 6 |     cdef void wtfree(void* ptr)
 7 | 
 8 |     ctypedef struct ArrayInfo:
 9 |         size_t * shape
10 |         pywt_index_t * strides
11 |         size_t ndim
12 | 
13 |     ctypedef enum Coefficient:
14 |         COEF_APPROX = 0
15 |         COEF_DETAIL = 1
16 | 
17 |     ctypedef enum DiscreteTransformType:
18 |         DWT_TRANSFORM = 0
19 |         SWT_TRANSFORM = 1
20 | 
21 |     ctypedef enum MODE:
22 |         MODE_INVALID = -1
23 |         MODE_ZEROPAD = 0
24 |         MODE_SYMMETRIC
25 |         MODE_CONSTANT_EDGE
26 |         MODE_SMOOTH
27 |         MODE_PERIODIC
28 |         MODE_PERIODIZATION
29 |         MODE_REFLECT
30 |         MODE_ANTISYMMETRIC
31 |         MODE_ANTIREFLECT
32 |         MODE_MAX
33 | 
34 |     # buffers lengths
35 |     cdef size_t dwt_buffer_length(size_t input_len, size_t filter_len, MODE mode)
36 |     cdef size_t upsampling_buffer_length(size_t coeffs_len, size_t filter_len,
37 |                                          MODE mode)
38 |     cdef size_t reconstruction_buffer_length(size_t coeffs_len, size_t filter_len)
39 |     cdef size_t idwt_buffer_length(size_t coeffs_len, size_t filter_len, MODE mode)
40 |     cdef size_t swt_buffer_length(size_t coeffs_len)
41 | 
42 |     # max dec levels
43 |     cdef unsigned char dwt_max_level(size_t input_len, size_t filter_len)
44 |     cdef unsigned char swt_max_level(size_t input_len)
45 | 


--------------------------------------------------------------------------------
/pywt/_extensions/config.pxi.in:
--------------------------------------------------------------------------------
1 | # Autogenerated file containing Cython compile-time defines
2 | 
3 | DEF HAVE_C99_CPLX = @have_c99_complex_cy@
4 | 


--------------------------------------------------------------------------------
/pywt/_extensions/wavelet.pxd:
--------------------------------------------------------------------------------
 1 | from .common cimport pywt_index_t
 2 | 
 3 | cdef extern from "c/wavelets.h":
 4 |     ctypedef enum SYMMETRY:
 5 |         ASYMMETRIC
 6 |         NEAR_SYMMETRIC
 7 |         SYMMETRIC
 8 |         ANTI_SYMMETRIC
 9 | 
10 | 
11 |     ctypedef enum WAVELET_NAME:
12 |         HAAR
13 |         RBIO
14 |         DB
15 |         SYM
16 |         COIF
17 |         BIOR
18 |         DMEY
19 |         GAUS
20 |         MEXH
21 |         MORL
22 |         CGAU
23 |         SHAN
24 |         FBSP
25 |         CMOR
26 | 
27 |     ctypedef struct BaseWavelet:
28 |         pywt_index_t support_width
29 | 
30 |         unsigned int orthogonal
31 |         unsigned int biorthogonal
32 |         unsigned int compact_support
33 | 
34 |         SYMMETRY symmetry
35 | 
36 | 
37 |         int _builtin
38 |         char* family_name
39 |         char* short_name
40 | 
41 |     ctypedef struct DiscreteWavelet:
42 |         double* dec_hi_double      # highpass decomposition
43 |         double* dec_lo_double      # lowpass   decomposition
44 |         double* rec_hi_double      # highpass reconstruction
45 |         double* rec_lo_double      # lowpass   reconstruction
46 | 
47 |         float* dec_hi_float
48 |         float* dec_lo_float
49 |         float* rec_hi_float
50 |         float* rec_lo_float
51 |         size_t dec_len         # length of decomposition filter
52 |         size_t rec_len         # length of reconstruction filter
53 | 
54 |         int vanishing_moments_psi
55 |         int vanishing_moments_phi
56 |         BaseWavelet base
57 | 
58 | 
59 |     ctypedef struct ContinuousWavelet:
60 | 
61 |         BaseWavelet base
62 |         float lower_bound
63 |         float upper_bound
64 |         float center_frequency
65 |         float bandwidth_frequency
66 |         unsigned int fbsp_order
67 |         int complex_cwt
68 | 
69 | 
70 |     cdef int is_discrete_wavelet(WAVELET_NAME name)
71 |     cdef DiscreteWavelet* discrete_wavelet(WAVELET_NAME name, int type)
72 |     cdef DiscreteWavelet* blank_discrete_wavelet(size_t filter_length)
73 |     cdef void free_discrete_wavelet(DiscreteWavelet* wavelet)
74 | 
75 |     cdef ContinuousWavelet* continuous_wavelet(WAVELET_NAME name, int type)
76 |     cdef ContinuousWavelet* blank_continuous_wavelet()
77 |     cdef void free_continuous_wavelet(ContinuousWavelet* wavelet)
78 | 


--------------------------------------------------------------------------------
/pywt/_pytest.py:
--------------------------------------------------------------------------------
 1 | """common test-related code."""
 2 | import multiprocessing
 3 | import os
 4 | import platform
 5 | import sys
 6 | 
 7 | import numpy as np
 8 | import pytest
 9 | 
10 | __all__ = ['uses_matlab',   # skip if pymatbridge and Matlab unavailable
11 |            'uses_futures',  # skip if futures unavailable
12 |            'uses_pymatbridge',  # skip if no PYWT_XSLOW environment variable
13 |            'uses_precomputed',  # skip if PYWT_XSLOW environment variable found
14 |            'matlab_result_dict_cwt',   # dict with precomputed Matlab dwt data
15 |            'matlab_result_dict_dwt',   # dict with precomputed Matlab cwt data
16 |            'futures',      # the futures module or None
17 |            'max_workers',  # the number of workers available to futures
18 |            'size_set',     # the set of Matlab tests to run
19 |            ]
20 | 
21 | try:
22 |     from concurrent import futures
23 |     max_workers = multiprocessing.cpu_count()
24 |     futures_available = True
25 | except ImportError:
26 |     futures_available = False
27 |     futures = None
28 |     max_workers = 1
29 | 
30 | # Check if running on Emscripten/WASM, and skip tests that require concurrency.
31 | # Relevant issue: https://github.com/pyodide/pyodide/issues/237
32 | IS_WASM = (sys.platform == "emscripten") or (platform.machine() in ["wasm32", "wasm64"])
33 | 
34 | 
35 | # check if pymatbridge + MATLAB tests should be run
36 | matlab_result_dict_dwt = None
37 | matlab_result_dict_cwt = None
38 | matlab_missing = True
39 | use_precomputed = True
40 | size_set = 'reduced'
41 | if 'PYWT_XSLOW' in os.environ:
42 |     try:
43 |         from pymatbridge import Matlab
44 |         mlab = Matlab()
45 |         matlab_missing = False
46 |         use_precomputed = False
47 |         size_set = 'full'
48 |     except ImportError:
49 |         print("To run Matlab compatibility tests you need to have MathWorks "
50 |               "MATLAB, MathWorks Wavelet Toolbox and the pymatbridge Python "
51 |               "package installed.")
52 | if use_precomputed:
53 |     # load dictionaries of precomputed results
54 |     data_dir = os.path.join(os.path.dirname(__file__), 'tests', 'data')
55 |     matlab_data_file_cwt = os.path.join(
56 |         data_dir, 'cwt_matlabR2015b_result.npz')
57 |     matlab_result_dict_cwt = np.load(matlab_data_file_cwt)
58 | 
59 |     matlab_data_file_dwt = os.path.join(
60 |         data_dir, 'dwt_matlabR2012a_result.npz')
61 |     matlab_result_dict_dwt = np.load(matlab_data_file_dwt)
62 | 
63 | uses_futures = pytest.mark.skipif(
64 |     not futures_available or IS_WASM,
65 |     reason='futures is not available, or running via Pyodide/WASM.')
66 |     # not futures_available, reason='futures not available')
67 | uses_matlab = pytest.mark.skipif(
68 |     matlab_missing, reason='pymatbridge and/or Matlab not available')
69 | uses_pymatbridge = pytest.mark.skipif(
70 |     use_precomputed,
71 |     reason='PYWT_XSLOW set: skipping tests against precomputed Matlab results')
72 | uses_precomputed = pytest.mark.skipif(
73 |     not use_precomputed,
74 |     reason='PYWT_XSLOW not set: test against precomputed matlab tests')
75 | 


--------------------------------------------------------------------------------
/pywt/conftest.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | 
3 | 
4 | def pytest_configure(config):
5 |     config.addinivalue_line("markers",
6 |                             "slow: Tests that are slow.")
7 | 


--------------------------------------------------------------------------------
/pywt/data/__init__.py:
--------------------------------------------------------------------------------
1 | from ._readers import aero, ascent, camera, ecg, nino
2 | from ._wavelab_signals import demo_signal
3 | 


--------------------------------------------------------------------------------
/pywt/data/aero.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/data/aero.npz


--------------------------------------------------------------------------------
/pywt/data/ascent.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/data/ascent.npz


--------------------------------------------------------------------------------
/pywt/data/camera.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/data/camera.npz


--------------------------------------------------------------------------------
/pywt/data/ecg.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/data/ecg.npz


--------------------------------------------------------------------------------
/pywt/data/sst_nino3.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/data/sst_nino3.npz


--------------------------------------------------------------------------------
/pywt/meson.build:
--------------------------------------------------------------------------------
 1 | fs = import('fs')
 2 | 
 3 | py.install_sources(
 4 |   [
 5 |     '__init__.py',
 6 |     '_cwt.py',
 7 |     '_doc_utils.py',
 8 |     '_dwt.py',
 9 |     '_functions.py',
10 |     '_mra.py',
11 |     '_multidim.py',
12 |     '_multilevel.py',
13 |     '_pytest.py',
14 |     '_pytesttester.py',
15 |     '_swt.py',
16 |     '_thresholding.py',
17 |     '_utils.py',
18 |     '_wavelet_packets.py',
19 |     'conftest.py',
20 |   ],
21 |   subdir: 'pywt'
22 | )
23 | 
24 | generate_version = custom_target(
25 |   'generate-version',
26 |   install: true,
27 |   build_always_stale: true,
28 |   build_by_default: true,
29 |   output: 'version.py',
30 |   input: '../util/version_utils.py',
31 |   command: [py, '@INPUT@', '--source-root', '@SOURCE_ROOT@'],
32 |   install_dir: py.get_install_dir() / 'pywt',
33 |   install_tag: 'python-runtime',
34 | )
35 | 
36 | cc = meson.get_compiler('c')
37 | 
38 | # Check for C99 complex types support. MSVC shouldn't have it, other compilers
39 | # most likely will.
40 | cdata = configuration_data()
41 | have_c99_complex = cc.has_type('complex float', prefix: '#include ')
42 | if have_c99_complex
43 |   cdata.set('have_c99_complex', 'True')
44 |   cdata.set('have_c99_complex_cy', '1')
45 | else
46 |   cdata.set('have_c99_complex', 'False')
47 |   cdata.set('have_c99_complex_cy', '0')
48 | endif
49 | 
50 | _c99_config = configure_file(
51 |   input: '_c99_config.py.in',
52 |   output: '_c99_config.py',
53 |   configuration: cdata,
54 |   install: true,
55 |   install_dir: py.get_install_dir() / 'pywt',
56 |   install_tag: 'python-runtime',
57 | )
58 | 
59 | install_subdir('data', install_dir: py.get_install_dir() / 'pywt')
60 | install_subdir('tests', install_dir:  py.get_install_dir() / 'pywt')
61 | 
62 | # Copy needed for Cython code in _extensions
63 | __init__py = fs.copyfile('__init__.py')
64 | 
65 | subdir('_extensions')
66 | 


--------------------------------------------------------------------------------
/pywt/tests/data/cwt_matlabR2015b_result.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/tests/data/cwt_matlabR2015b_result.npz


--------------------------------------------------------------------------------
/pywt/tests/data/dwt_matlabR2012a_result.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/tests/data/dwt_matlabR2012a_result.npz


--------------------------------------------------------------------------------
/pywt/tests/data/generate_matlab_data_cwt.py:
--------------------------------------------------------------------------------
 1 | """ This script was used to generate dwt_matlabR2012a_result.npz by storing
 2 | the outputs from Matlab R2012a. """
 3 | 
 4 | 
 5 | import numpy as np
 6 | 
 7 | import pywt
 8 | 
 9 | try:
10 |     from pymatbridge import Matlab
11 |     mlab = Matlab()
12 |     _matlab_missing = False
13 | except ImportError:
14 |     print("To run Matlab compatibility tests you need to have MathWorks "
15 |           "MATLAB, MathWorks Wavelet Toolbox and the pymatbridge Python "
16 |           "package installed.")
17 |     _matlab_missing = True
18 | 
19 | if _matlab_missing:
20 |     raise OSError("Can't generate matlab data files without MATLAB")
21 | 
22 | size_set = 'reduced'
23 | 
24 | # list of mode names in pywt and matlab
25 | modes = [('zero', 'zpd'),
26 |          ('constant', 'sp0'),
27 |          ('symmetric', 'sym'),
28 |          ('periodic', 'ppd'),
29 |          ('smooth', 'sp1'),
30 |          ('periodization', 'per')]
31 | 
32 | families = ('gaus', 'mexh', 'morl', 'cgau', 'shan', 'fbsp', 'cmor')
33 | wavelets = sum([pywt.wavelist(name) for name in families], [])
34 | 
35 | rstate = np.random.RandomState(1234)
36 | mlab.start()
37 | try:
38 |     all_matlab_results = {}
39 |     for wavelet in wavelets:
40 |         w = pywt.ContinuousWavelet(wavelet)
41 |         if np.any((wavelet == np.array(['shan', 'cmor'])),axis=0):
42 |             mlab.set_variable('wavelet', wavelet+str(w.bandwidth_frequency)+'-'+str(w.center_frequency))
43 |         elif wavelet == 'fbsp':
44 |             mlab.set_variable('wavelet', wavelet+str(w.fbsp_order)+'-'+str(w.bandwidth_frequency)+'-'+str(w.center_frequency))
45 |         else:
46 |             mlab.set_variable('wavelet', wavelet)
47 |         if size_set == 'full':
48 |             data_sizes = list(range(100, 101)) + \
49 |                 [100, 200, 500, 1000, 50000]
50 |             Scales = (1,np.arange(1,3),np.arange(1,4),np.arange(1,5))
51 |         else:
52 |             data_sizes = (1000, 1000 + 1)
53 |             Scales = (1,np.arange(1,3))
54 |         mlab_code = ("psi = wavefun(wavelet,10)")
55 |         res = mlab.run_code(mlab_code)
56 |         if not res['success']:
57 |             raise RuntimeError(
58 |                 "Matlab failed to execute the provided code. "
59 |                 "Check that the wavelet toolbox is installed.")
60 |         psi = np.asarray(mlab.get_variable('psi'))
61 |         psi_key = '_'.join([wavelet, 'psi'])
62 |         all_matlab_results[psi_key] = psi
63 |         for N in data_sizes:
64 |             data = rstate.randn(N)
65 |             mlab.set_variable('data', data)
66 | 
67 |             # Matlab result
68 |             scale_count = 0
69 |             for scales in Scales:
70 |                 scale_count += 1
71 |                 mlab.set_variable('scales', scales)
72 |                 mlab_code = ("coefs = cwt(data, scales, wavelet)")
73 |                 res = mlab.run_code(mlab_code)
74 |                 if not res['success']:
75 |                     raise RuntimeError(
76 |                         "Matlab failed to execute the provided code. "
77 |                         "Check that the wavelet toolbox is installed.")
78 |                 # need np.asarray because sometimes the output is type float
79 |                 coefs = np.asarray(mlab.get_variable('coefs'))
80 |                 coefs_key = '_'.join([str(scale_count), wavelet, str(N), 'coefs'])
81 |                 all_matlab_results[coefs_key] = coefs
82 | 
83 | finally:
84 |     mlab.stop()
85 | 
86 | np.savez('cwt_matlabR2015b_result.npz', **all_matlab_results)
87 | 


--------------------------------------------------------------------------------
/pywt/tests/data/wavelab_test_signals.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyWavelets/pywt/4f2a870250fc2529feb8f978b01a30c7f8539400/pywt/tests/data/wavelab_test_signals.npz


--------------------------------------------------------------------------------
/pywt/tests/test_data.py:
--------------------------------------------------------------------------------
 1 | import os
 2 | 
 3 | import numpy as np
 4 | from numpy.testing import assert_, assert_allclose, assert_raises
 5 | 
 6 | import pywt.data
 7 | 
 8 | data_dir = os.path.join(os.path.dirname(__file__), 'data')
 9 | wavelab_data_file = os.path.join(data_dir, 'wavelab_test_signals.npz')
10 | wavelab_result_dict = np.load(wavelab_data_file)
11 | 
12 | 
13 | def test_data_aero():
14 |     aero = pywt.data.aero()
15 | 
16 |     ref = np.array([[178, 178, 179],
17 |                     [170, 173, 171],
18 |                     [185, 174, 171]])
19 | 
20 |     assert_allclose(aero[:3, :3], ref)
21 | 
22 | 
23 | def test_data_ascent():
24 |     ascent = pywt.data.ascent()
25 | 
26 |     ref = np.array([[83, 83, 83],
27 |                     [82, 82, 83],
28 |                     [80, 81, 83]])
29 | 
30 |     assert_allclose(ascent[:3, :3], ref)
31 | 
32 | 
33 | def test_data_camera():
34 |     camera = pywt.data.camera()
35 | 
36 |     ref = np.array([[200, 200, 200],
37 |                     [200, 199, 199],
38 |                     [199, 199, 199]])
39 | 
40 |     assert_allclose(camera[:3, :3], ref)
41 | 
42 | 
43 | def test_data_ecg():
44 |     ecg = pywt.data.ecg()
45 | 
46 |     ref = np.array([-86, -87, -87])
47 | 
48 |     assert_allclose(ecg[:3], ref)
49 | 
50 | 
51 | def test_wavelab_signals():
52 |     """Comparison with results generated using WaveLab"""
53 |     rtol = atol = 1e-12
54 | 
55 |     # get a list of the available signals
56 |     available_signals = pywt.data.demo_signal('list')
57 |     assert_('Doppler' in available_signals)
58 | 
59 |     for signal in available_signals:
60 |         # reference dictionary has lowercase names for the keys
61 |         key = signal.replace('-', '_').lower()
62 |         val = wavelab_result_dict[key]
63 |         if key in ['gabor', 'sineoneoverx']:
64 |             # these functions do not allow a size to be provided
65 |             assert_allclose(val, pywt.data.demo_signal(signal),
66 |                             rtol=rtol, atol=atol)
67 |             assert_raises(ValueError, pywt.data.demo_signal, key, val.size)
68 |         else:
69 |             assert_allclose(val, pywt.data.demo_signal(signal, val.size),
70 |                             rtol=rtol, atol=atol)
71 |             # these functions require a size to be provided
72 |             assert_raises(ValueError, pywt.data.demo_signal, key)
73 | 
74 |     # ValueError on unrecognized signal type
75 |     assert_raises(ValueError, pywt.data.demo_signal, 'unknown_signal', 512)
76 | 
77 |     # ValueError on invalid length
78 |     assert_raises(ValueError, pywt.data.demo_signal, 'Doppler', 0)
79 | 


--------------------------------------------------------------------------------
/pywt/tests/test_deprecations.py:
--------------------------------------------------------------------------------
 1 | import warnings
 2 | 
 3 | import numpy as np
 4 | from numpy.testing import assert_array_equal, assert_warns
 5 | 
 6 | import pywt
 7 | 
 8 | 
 9 | def test_intwave_deprecation():
10 |     wavelet = pywt.Wavelet('db3')
11 |     assert_warns(DeprecationWarning, pywt.intwave, wavelet)
12 | 
13 | 
14 | def test_centrfrq_deprecation():
15 |     wavelet = pywt.Wavelet('db3')
16 |     assert_warns(DeprecationWarning, pywt.centrfrq, wavelet)
17 | 
18 | 
19 | def test_scal2frq_deprecation():
20 |     wavelet = pywt.Wavelet('db3')
21 |     assert_warns(DeprecationWarning, pywt.scal2frq, wavelet, 1)
22 | 
23 | 
24 | def test_orthfilt_deprecation():
25 |     assert_warns(DeprecationWarning, pywt.orthfilt, range(6))
26 | 
27 | 
28 | def test_integrate_wave_tuple():
29 |     sig = [0, 1, 2, 3]
30 |     xgrid = [0, 1, 2, 3]
31 |     assert_warns(DeprecationWarning, pywt.integrate_wavelet, (sig, xgrid))
32 | 
33 | 
34 | old_modes = ['zpd',
35 |              'cpd',
36 |              'sym',
37 |              'ppd',
38 |              'sp1',
39 |              'per',
40 |              ]
41 | 
42 | 
43 | def test_MODES_from_object_deprecation():
44 |     for mode in old_modes:
45 |         assert_warns(DeprecationWarning, pywt.Modes.from_object, mode)
46 | 
47 | 
48 | def test_MODES_attributes_deprecation():
49 |     def get_mode(Modes, name):
50 |         return getattr(Modes, name)
51 | 
52 |     for mode in old_modes:
53 |         assert_warns(DeprecationWarning, get_mode, pywt.Modes, mode)
54 | 
55 | 
56 | def test_mode_equivalence():
57 |     old_new = [('zpd', 'zero'),
58 |                ('cpd', 'constant'),
59 |                ('sym', 'symmetric'),
60 |                ('ppd', 'periodic'),
61 |                ('sp1', 'smooth'),
62 |                ('per', 'periodization')]
63 |     x = np.arange(8.)
64 |     with warnings.catch_warnings():
65 |         warnings.simplefilter('ignore', DeprecationWarning)
66 |         for old, new in old_new:
67 |             assert_array_equal(pywt.dwt(x, 'db2', mode=old),
68 |                                pywt.dwt(x, 'db2', mode=new))
69 | 


--------------------------------------------------------------------------------
/pywt/tests/test_doc.py:
--------------------------------------------------------------------------------
 1 | 
 2 | import doctest
 3 | import glob
 4 | import os
 5 | import sys
 6 | import unittest
 7 | 
 8 | try:
 9 |     import numpy as np
10 |     np.set_printoptions(legacy='1.13')
11 | except TypeError:
12 |     pass
13 | 
14 | pdir = os.path.pardir
15 | docs_base = os.path.abspath(os.path.join(os.path.dirname(__file__),
16 |                             pdir, pdir, "doc", "source"))
17 | 
18 | files = glob.glob(os.path.join(docs_base, "*.rst")) + \
19 |     glob.glob(os.path.join(docs_base, "*", "*.rst"))
20 | 
21 | suite = doctest.DocFileSuite(*files, module_relative=False, encoding="utf-8")
22 | 
23 | 
24 | if __name__ == "__main__":
25 |     sys.exit(int(not unittest.TextTestRunner().run(suite).wasSuccessful()))
26 | 


--------------------------------------------------------------------------------
/pywt/tests/test_functions.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env python
 2 | 
 3 | from numpy.testing import assert_allclose, assert_almost_equal
 4 | 
 5 | import pywt
 6 | 
 7 | 
 8 | def test_centrfreq():
 9 |     # db1 is Haar function, frequency=1
10 |     w = pywt.Wavelet('db1')
11 |     expected = 1
12 |     result = pywt.central_frequency(w, precision=12)
13 |     assert_almost_equal(result, expected, decimal=3)
14 |     # db2, frequency=2/3
15 |     w = pywt.Wavelet('db2')
16 |     expected = 2/3.
17 |     result = pywt.central_frequency(w, precision=12)
18 |     assert_almost_equal(result, expected)
19 | 
20 | 
21 | def test_scal2frq_scale():
22 |     scale = 2
23 |     w = pywt.Wavelet('db1')
24 |     expected = 1. / scale
25 |     result = pywt.scale2frequency(w, scale, precision=12)
26 |     assert_almost_equal(result, expected, decimal=3)
27 | 
28 | def test_frq2scal_freq():
29 |     freq = 2
30 |     w = pywt.Wavelet('db1')
31 |     expected = 1. / freq
32 |     result = pywt.frequency2scale(w, freq, precision=12)
33 |     assert_almost_equal(result, expected, decimal=3)
34 | 
35 | 
36 | def test_intwave_orthogonal():
37 |     w = pywt.Wavelet('db1')
38 |     int_psi, x = pywt.integrate_wavelet(w, precision=12)
39 |     ix = x < 0.5
40 |     # For x < 0.5, the integral is equal to x
41 |     assert_allclose(int_psi[ix], x[ix])
42 |     # For x > 0.5, the integral is equal to (1 - x)
43 |     # Ignore last point here, there x > 1 and something goes wrong
44 |     assert_allclose(int_psi[~ix][:-1], 1 - x[~ix][:-1], atol=1e-10)
45 | 


--------------------------------------------------------------------------------
/pywt/tests/test_perfect_reconstruction.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env python
 2 | 
 3 | """
 4 | Verify DWT perfect reconstruction.
 5 | """
 6 | 
 7 | 
 8 | import numpy as np
 9 | import pytest
10 | from numpy.testing import assert_
11 | 
12 | import pywt
13 | 
14 | 
15 | @pytest.mark.slow
16 | def test_perfect_reconstruction():
17 |     families = ('db', 'sym', 'coif', 'bior', 'rbio')
18 |     wavelets = sum([pywt.wavelist(name) for name in families], [])
19 |     # list of mode names in pywt and matlab
20 |     modes = [('zero', 'zpd'),
21 |              ('constant', 'sp0'),
22 |              ('symmetric', 'sym'),
23 |              ('periodic', 'ppd'),
24 |              ('smooth', 'sp1'),
25 |              ('periodization', 'per')]
26 | 
27 |     dtypes = (np.float32, np.float64)
28 | 
29 |     for wavelet in wavelets:
30 |         for pmode, mmode in modes:
31 |             for dt in dtypes:
32 |                 check_reconstruction(pmode, mmode, wavelet, dt)
33 | 
34 | 
35 | def check_reconstruction(pmode, mmode, wavelet, dtype):
36 |     data_size = list(range(2, 40)) + [100, 200, 500, 1000, 2000, 10000,
37 |                                       50000, 100000]
38 |     np.random.seed(12345)
39 |     # TODO: smoke testing - more failures for different seeds
40 | 
41 |     if dtype == np.float32:
42 |         # was 3e-7 has to be lowered as db21, db29, db33, db35, coif14, coif16 were failing
43 |         epsilon = 6e-7
44 |     else:
45 |         epsilon = 5e-11
46 | 
47 |     for N in data_size:
48 |         data = np.asarray(np.random.random(N), dtype)
49 | 
50 |         # compute dwt coefficients
51 |         pa, pd = pywt.dwt(data, wavelet, pmode)
52 | 
53 |         # compute reconstruction
54 |         rec = pywt.idwt(pa, pd, wavelet, pmode)
55 | 
56 |         if len(data) % 2:
57 |             rec = rec[:len(data)]
58 | 
59 |         rms_rec = np.sqrt(np.mean((data-rec)**2))
60 |         msg = ('[RMS_REC > EPSILON] for Mode: %s, Wavelet: %s, '
61 |                'Length: %d, rms=%.3g' % (pmode, wavelet, len(data), rms_rec))
62 |         assert_(rms_rec < epsilon, msg=msg)
63 | 


--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
 1 | # Tox (http://tox.testrun.org/) is a tool for running tests
 2 | # in multiple virtualenvs. This configuration file will run the
 3 | # test suite on all supported python versions. To use it, "pip install tox"
 4 | # and then run "tox" from this directory.
 5 | 
 6 | # Running the command 'tox' while in the root of the pywt source
 7 | # directory will:
 8 | #   - Create a pywt source distribution
 9 | #   - Then for every supported version of Python:
10 | #     - Create a virtualenv in {homedir}/.tox/pywt/py$VERSION and
11 | #       install dependencies. (These virtualenvs are cached across
12 | #       runs unless you use --recreate.)
13 | #     - Use pip to install the pywt sdist into the virtualenv
14 | #     - Run the pywt tests
15 | # To run against a specific subset of Python versions, use:
16 | #   tox -e py39,py310
17 | 
18 | # Tox assumes that you have appropriate Python interpreters already
19 | # installed and that they can be run as 'python3.9', 'python3.10', etc.
20 | 
21 | [tox]
22 | toxworkdir = {homedir}/.tox/pywt/
23 | envlist = py310, py311, py312
24 | 
25 | [testenv]
26 | deps =
27 |     pytest
28 |     cython
29 |     numpy
30 |     matplotlib
31 | changedir = {envdir}
32 | commands =
33 |     pytest {toxinidir}/pywt/tests -v
34 | 


--------------------------------------------------------------------------------
/util/create_dat.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env python
 2 | 
 3 | """Helper script for creating image .dat files by numpy.save.
 4 | 
 5 | Usage:
 6 | 
 7 |     python create_dat.py  
 8 | 
 9 | Example (to create aero.dat):
10 | 
11 |     python create_dat.py aero.png aero.dat
12 | 
13 | Requires SciPy and PIL, which need to be installed separately.
14 | """
15 | 
16 | 
17 | import sys
18 | 
19 | import numpy as np
20 | 
21 | 
22 | def main():
23 |     from scipy.misc import imread
24 | 
25 |     if len(sys.argv) != 3:
26 |         print(__doc__)
27 |         exit()
28 | 
29 |     image_fname = sys.argv[1]
30 |     dat_fname = sys.argv[2]
31 | 
32 |     data = imread(image_fname)
33 | 
34 |     np.savez_compressed(dat_fname, data=data)
35 | 
36 | 
37 | if __name__ == "__main__":
38 |     main()
39 | 


--------------------------------------------------------------------------------
/util/readthedocs/requirements.txt:
--------------------------------------------------------------------------------
 1 | cython
 2 | docutils
 3 | # Pyodide kernel 0.5.1 comes with Pyodide 0.27.1 and PyWavelets 1.7.0
 4 | # see https://pyodide.org/en/stable/usage/packages-in-pyodide.html
 5 | # and https://jupyterlite-pyodide-kernel.readthedocs.io/en/stable/#with-pyodide
 6 | # for information on updating
 7 | jupyterlite-pyodide-kernel==0.5.1
 8 | jupyterlite-sphinx>=0.18.0
 9 | jupytext
10 | pydata-sphinx-theme
11 | pytest
12 | matplotlib
13 | meson-python
14 | myst-nb
15 | nbformat
16 | numpy
17 | numpydoc
18 | sphinx>=7
19 | sphinx-copybutton
20 | sphinx-design
21 | sphinx-togglebutton
22 | 


--------------------------------------------------------------------------------
/util/version_utils.py:
--------------------------------------------------------------------------------
 1 | import argparse
 2 | import os
 3 | import subprocess
 4 | 
 5 | MAJOR = 1
 6 | MINOR = 8
 7 | MICRO = 0
 8 | ISRELEASED = False
 9 | VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
10 | 
11 | 
12 | def get_version_info(source_root):
13 |     # Adding the git rev number needs to be done inside
14 |     # write_version_py(), otherwise the import of pywt.version messes
15 |     # up the build under Python 3.
16 |     FULLVERSION = VERSION
17 |     if os.path.exists(os.path.join(source_root, '.git')):
18 |         GIT_REVISION = git_version(source_root)
19 |     elif os.path.exists('pywt/version.py'):
20 |         # must be a source distribution, use existing version file
21 |         # load it as a separate module to not load pywt/__init__.py
22 |         import runpy
23 |         ns = runpy.run_path('pywt/version.py')
24 |         GIT_REVISION = ns['git_revision']
25 |     else:
26 |         GIT_REVISION = "Unknown"
27 | 
28 |     if not ISRELEASED:
29 |         FULLVERSION += '.dev0+' + GIT_REVISION
30 | 
31 |     return FULLVERSION, GIT_REVISION
32 | 
33 | 
34 | def write_version_py(source_root, filename='pywt/version.py'):
35 |     cnt = """\
36 | # THIS FILE IS GENERATED DURING THE PYWAVELETS BUILD
37 | # See util/version_utils.py for details
38 | 
39 | short_version = '%(version)s'
40 | version = '%(version)s'
41 | full_version = '%(full_version)s'
42 | git_revision = '%(git_revision)s'
43 | release = %(isrelease)s
44 | 
45 | if not release:
46 |     version = full_version
47 | """
48 |     FULLVERSION, GIT_REVISION = get_version_info(source_root)
49 | 
50 |     a = open(filename, 'w')
51 |     try:
52 |         a.write(cnt % {'version': VERSION,
53 |                        'full_version': FULLVERSION,
54 |                        'git_revision': GIT_REVISION,
55 |                        'isrelease': str(ISRELEASED)})
56 |     finally:
57 |         a.close()
58 | 
59 | 
60 | # Return the git revision as a string
61 | def git_version(cwd):
62 |     def _minimal_ext_cmd(cmd):
63 |         # construct minimal environment
64 |         env = {}
65 |         for k in ['SYSTEMROOT', 'PATH']:
66 |             v = os.environ.get(k)
67 |             if v is not None:
68 |                 env[k] = v
69 |         # LANGUAGE is used on win32
70 |         env['LANGUAGE'] = 'C'
71 |         env['LANG'] = 'C'
72 |         env['LC_ALL'] = 'C'
73 |         out = subprocess.Popen(cmd, stdout=subprocess.PIPE,
74 |                                env=env, cwd=cwd).communicate()[0]
75 |         return out
76 | 
77 |     try:
78 |         git_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
79 |         git_dir = os.path.join(git_dir, ".git")
80 |         out = _minimal_ext_cmd(['git',
81 |                                 '--git-dir',
82 |                                 git_dir,
83 |                                 'rev-parse',
84 |                                 'HEAD'])
85 |         GIT_REVISION = out.strip().decode('ascii')[:7]
86 |     except OSError:
87 |         GIT_REVISION = "Unknown"
88 | 
89 |     return GIT_REVISION
90 | 
91 | 
92 | if __name__ == "__main__":
93 |     parser = argparse.ArgumentParser()
94 |     parser.add_argument("--source-root", type=str, default='.',
95 |                         help="Relative path to the root of the source directory")
96 |     args = parser.parse_args()
97 | 
98 |     write_version_py(args.source_root)
99 | 


--------------------------------------------------------------------------------