From e7b80afd22fecff2253ef72e24b01cf0a6ef20e7 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:08:05 +0530 Subject: [PATCH 1/9] DEP: Drop installation of nightly SciPy --- .github/workflows/tests.yml | 4 ++-- .github/workflows/wheel_tests_and_release.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 448beac7..92f97b7f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -147,7 +147,7 @@ jobs: popd test_pywavelets_linux_free_threaded: - name: linux-cp313t-with-scipy + name: linux-cp313t-free-threaded runs-on: ubuntu-latest strategy: # Ensure that a wheel builder finishes even if another fails @@ -169,7 +169,7 @@ jobs: python --version pip install --upgrade pip build # We need nightly wheels for free-threaded support and latest fixes - pip install --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython numpy scipy + pip install --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython numpy pip install pytest meson-python ninja pip install . -v --no-build-isolation diff --git a/.github/workflows/wheel_tests_and_release.yml b/.github/workflows/wheel_tests_and_release.yml index 1c239a1f..1f924f48 100644 --- a/.github/workflows/wheel_tests_and_release.yml +++ b/.github/workflows/wheel_tests_and_release.yml @@ -49,7 +49,7 @@ jobs: if: ${{ matrix.cibw_python }} == "cp313t" run: | PYPI_URL="https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" - CIBW_DEPS="pip install --pre -i $PYPI_URL cython scipy &&\ + CIBW_DEPS="pip install --pre -i $PYPI_URL cython &&\ pip install numpy pytest meson-python ninja" NO_BUILD_ISOLATION="pip; args: --no-build-isolation" echo "CIBW_BEFORE_BUILD=$CIBW_DEPS" >> "$GITHUB_ENV" @@ -136,7 +136,7 @@ jobs: if: ${{ matrix.cibw_python }} == "cp313t" run: | PYPI_URL="https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" - CIBW_DEPS="pip install --pre -i $PYPI_URL cython scipy &&\ + CIBW_DEPS="pip install --pre -i $PYPI_URL cython &&\ pip install numpy pytest meson-python ninja" NO_BUILD_ISOLATION="pip; args: --no-build-isolation" echo "CIBW_BEFORE_BUILD=$CIBW_DEPS" >> "$GITHUB_ENV" From 6181b57177dd8c9b62e4fafc9f6a58e49c6f891e Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:09:05 +0530 Subject: [PATCH 2/9] MAINT: Move `create_dat.py` to `util/` directory --- .coveragerc | 1 - {pywt/data => util}/create_dat.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) rename {pywt/data => util}/create_dat.py (80%) diff --git a/.coveragerc b/.coveragerc index e67fd3aa..6b5969de 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,7 +7,6 @@ omit = */pywt/_doc_utils.py* */pywt/_pytesttester.py* */pywt/_pytest.py* - */pywt/data/create_dat.py *.pxd stringsource plugins = Cython.Coverage diff --git a/pywt/data/create_dat.py b/util/create_dat.py similarity index 80% rename from pywt/data/create_dat.py rename to util/create_dat.py index 4c993855..1616fb01 100755 --- a/pywt/data/create_dat.py +++ b/util/create_dat.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -"""Helper script for creating image .dat files by numpy.save +"""Helper script for creating image .dat files by numpy.save. Usage: @@ -10,7 +10,7 @@ python create_dat.py aero.png aero.dat -Requires Scipy and PIL. +Requires SciPy and PIL, which need to be installed separately. """ From c31a47b2e4aff781bd204fbc96ee4bef1d222385 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:09:58 +0530 Subject: [PATCH 3/9] MAINT: Remove SciPy ref from manual + installation guide --- README.rst | 4 +--- doc/source/install.rst | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 10287ef4..451eb26d 100644 --- a/README.rst +++ b/README.rst @@ -67,9 +67,7 @@ Installation PyWavelets supports `Python`_ >=3.10, and is only dependent on `NumPy`_ (supported versions are currently ``>= 1.23.0``). To pass all of the tests, -`Matplotlib`_ is also required. `SciPy`_ is also an optional dependency. When -present, FFT-based continuous wavelet transforms will use FFTs from SciPy -rather than NumPy. +`Matplotlib`_ is also required. There are binary wheels for Intel Linux, Windows and macOS / OSX on PyPi. If you are on one of these platforms, you should get a binary (precompiled) diff --git a/doc/source/install.rst b/doc/source/install.rst index bd91a8c3..840b8f7b 100644 --- a/doc/source/install.rst +++ b/doc/source/install.rst @@ -40,8 +40,7 @@ For the requirements needed to build from source are (Python, NumPy and Cython minimum versions in particular), see ``pyproject.toml``. To run all the tests for PyWavelets, you will also need to install the -Matplotlib_ package. If SciPy_ is available, FFT-based continuous wavelet -transforms will use the FFT implementation from SciPy instead of NumPy. +Matplotlib_ package. .. seealso:: The :ref:`Development guide ` section contains more information on building and installing from source code. From d7f52cc881c4d180551fc44e6715c849d83e1807 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:10:28 +0530 Subject: [PATCH 4/9] STY: Fix usage of SciPy noun --- doc/source/dev/conduct/code_of_conduct.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/dev/conduct/code_of_conduct.rst b/doc/source/dev/conduct/code_of_conduct.rst index 49d23d17..6fb3b2e6 100644 --- a/doc/source/dev/conduct/code_of_conduct.rst +++ b/doc/source/dev/conduct/code_of_conduct.rst @@ -165,7 +165,7 @@ Endnotes We are thankful to the SciPy developers for creating the code of conduct we have adapted here. -- `Scipy Code of Conduct `_ +- `SciPy Code of Conduct `_ The SciPy code of conduct was in turn inspired by the following documents: From e847b6ef7ddbc77124c74e05d2b999f9c26c7593 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:10:45 +0530 Subject: [PATCH 5/9] DEP, MAINT: Remove optional-dependencies table --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dedcbead..60a80810 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,9 +50,6 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules" ] -[project.optional-dependencies] -optional = ["scipy>=1.9"] - [project.urls] homepage = "https://github.com/PyWavelets/pywt" source = "https://github.com/PyWavelets/pywt" From 5bcef685d7d1657116132eaa7a39a15abc823292 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:11:29 +0530 Subject: [PATCH 6/9] CI, MAINT: Remove SciPy-related CI options --- .github/workflows/tests.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 92f97b7f..83707051 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,7 +23,6 @@ env: CYTHONSPEC: cython NUMPY_MIN: numpy==1.23.0 CYTHON_MIN: cython==3.0.4 - SCIPY_MIN: scipy==1.9.0 jobs: test_pywavelets_linux: @@ -36,7 +35,6 @@ jobs: runs-on: [ubuntu-latest] # Arm runner tested separately, see below python-version: ["3.10", "3.13"] MINIMUM_REQUIREMENTS: [0] - USE_SCIPY: [0] USE_SDIST: [0] REFGUIDE_CHECK: [1] PIP_FLAGS: [""] @@ -52,8 +50,6 @@ jobs: OPTIONS_NAME: "minimum-req" - runs-on: ubuntu-latest python-version: "3.10" - USE_SCIPY: 1 - OPTIONS_NAME: "with-scipy" - runs-on: ubuntu-latest python-version: "3.10" USE_SDIST: 1 @@ -81,7 +77,6 @@ jobs: MINIMUM_REQUIREMENTS: ${{ matrix.MINIMUM_REQUIREMENTS }} PIP_FLAGS: ${{ matrix.PIP_FLAGS }} USE_SDIST: ${{ matrix.USE_SDIST }} - USE_SCIPY: ${{ matrix.USE_SCIPY }} REFGUIDE_CHECK: ${{ matrix.REFGUIDE_CHECK }} OPTIONS_NAME: ${{ matrix.OPTIONS_NAME }} run: | @@ -97,11 +92,9 @@ jobs: if [ "${MINIMUM_REQUIREMENTS}" == "1" ]; then pip install ${CYTHON_MIN} pip install ${NUMPY_MIN} - if [ "${USE_SCIPY}" == "1" ]; then pip install ${SCIPY_MIN}; fi else pip install ${PIP_FLAGS} cython pip install ${PIP_FLAGS} numpy - if [ "${USE_SCIPY}" == "1" ]; then pip install ${PIP_FLAGS} scipy; fi fi pip install ${PIP_FLAGS} matplotlib pytest @@ -190,7 +183,6 @@ jobs: matrix: python-version: ["3.10", "3.13"] MINIMUM_REQUIREMENTS: [0] - USE_SCIPY: [0] USE_SDIST: [0] REFGUIDE_CHECK: [0] PIP_FLAGS: [""] @@ -219,7 +211,6 @@ jobs: MINIMUM_REQUIREMENTS: ${{ matrix.MINIMUM_REQUIREMENTS }} PIP_FLAGS: ${{ matrix.PIP_FLAGS }} USE_SDIST: ${{ matrix.USE_SDIST }} - USE_SCIPY: ${{ matrix.USE_SCIPY }} REFGUIDE_CHECK: ${{ matrix.REFGUIDE_CHECK }} CC: /usr/bin/clang CXX: /usr/bin/clang++ @@ -233,10 +224,8 @@ jobs: # Set numpy version first, other packages link against it if [ "${MINIMUM_REQUIREMENTS}" == "1" ]; then pip install ${CYTHON_MIN} ${NUMPY_MIN} - if [ "${USE_SCIPY}" == "1" ]; then pip install ${SCIPY_MIN}; fi else pip install ${PIP_FLAGS} cython numpy - if [ "${USE_SCIPY}" == "1" ]; then pip install ${PIP_FLAGS} scipy; fi fi pip install ${PIP_FLAGS} matplotlib pytest From ed82b68661ae1c3a2923850aad84548a8c15a9e1 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:14:10 +0530 Subject: [PATCH 7/9] MAINT: don't opt for SciPy's FFT, use `numpy.fft` --- pywt/_cwt.py | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/pywt/_cwt.py b/pywt/_cwt.py index 5239e0e0..5a497f70 100644 --- a/pywt/_cwt.py +++ b/pywt/_cwt.py @@ -14,24 +14,16 @@ import numpy as np -try: - import scipy - fftmodule = scipy.fft - next_fast_len = fftmodule.next_fast_len -except ImportError: - fftmodule = np.fft - - # provide a fallback so scipy is an optional requirement - # note: numpy.fft in numpy 2.0 is as fast as scipy.fft, so could be used - # unconditionally once the minimum supported numpy version is >=2.0 - def next_fast_len(n): - """Round up size to the nearest power of two. - - Given a number of samples `n`, returns the next power of two - following this number to take advantage of FFT speedup. - This fallback is less efficient than `scipy.fftpack.next_fast_len` - """ - return 2**ceil(np.log2(n)) +fftmodule = np.fft + + +def next_fast_len(n): + """Round up size to the nearest power of two. + + Given a number of samples `n`, returns the next power of two + following this number to take advantage of FFT speedup. + """ + return 2**ceil(np.log2(n)) def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1): From b8283af0851b2da17c26073ccdd8237b06beedd1 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:58:42 +0530 Subject: [PATCH 8/9] STY: rename noGIL job to `linux-cp313t-default` --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 83707051..42ca9713 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -140,7 +140,7 @@ jobs: popd test_pywavelets_linux_free_threaded: - name: linux-cp313t-free-threaded + name: linux-cp313t-default runs-on: ubuntu-latest strategy: # Ensure that a wheel builder finishes even if another fails From 7a692e78bfe10397c08cd011000373aa670d96d6 Mon Sep 17 00:00:00 2001 From: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com> Date: Sun, 2 Feb 2025 04:00:41 +0530 Subject: [PATCH 9/9] STY: Remove `fftmodule` variable, use `np.fft` --- pywt/_cwt.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pywt/_cwt.py b/pywt/_cwt.py index 5a497f70..0d69095b 100644 --- a/pywt/_cwt.py +++ b/pywt/_cwt.py @@ -14,8 +14,6 @@ import numpy as np -fftmodule = np.fft - def next_fast_len(n): """Round up size to the nearest power of two. @@ -169,10 +167,10 @@ def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1): ) if size_scale != size_scale0: # Must recompute fft_data when the padding size changes. - fft_data = fftmodule.fft(data, size_scale, axis=-1) + fft_data = np.fft.fft(data, size_scale, axis=-1) size_scale0 = size_scale - fft_wav = fftmodule.fft(int_psi_scale, size_scale, axis=-1) - conv = fftmodule.ifft(fft_wav * fft_data, axis=-1) + fft_wav = np.fft.fft(int_psi_scale, size_scale, axis=-1) + conv = np.fft.ifft(fft_wav * fft_data, axis=-1) conv = conv[..., :data.shape[-1] + int_psi_scale.size - 1] coef = - np.sqrt(scale) * np.diff(conv, axis=-1)