Skip to content

Commit becef54

Browse files
MAINT: remove optional dependence on SciPy for FFT operations (#791)
1 parent 281caa4 commit becef54

File tree

9 files changed

+20
-48
lines changed

9 files changed

+20
-48
lines changed

.coveragerc

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ omit =
77
*/pywt/_doc_utils.py*
88
*/pywt/_pytesttester.py*
99
*/pywt/_pytest.py*
10-
*/pywt/data/create_dat.py
1110
*.pxd
1211
stringsource
1312
plugins = Cython.Coverage

.github/workflows/tests.yml

+2-13
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ env:
2323
CYTHONSPEC: cython
2424
NUMPY_MIN: numpy==1.23.0
2525
CYTHON_MIN: cython==3.0.4
26-
SCIPY_MIN: scipy==1.9.0
2726

2827
jobs:
2928
test_pywavelets_linux:
@@ -36,7 +35,6 @@ jobs:
3635
runs-on: [ubuntu-latest] # Arm runner tested separately, see below
3736
python-version: ["3.10", "3.13"]
3837
MINIMUM_REQUIREMENTS: [0]
39-
USE_SCIPY: [0]
4038
USE_SDIST: [0]
4139
REFGUIDE_CHECK: [1]
4240
PIP_FLAGS: [""]
@@ -52,8 +50,6 @@ jobs:
5250
OPTIONS_NAME: "minimum-req"
5351
- runs-on: ubuntu-latest
5452
python-version: "3.10"
55-
USE_SCIPY: 1
56-
OPTIONS_NAME: "with-scipy"
5753
- runs-on: ubuntu-latest
5854
python-version: "3.10"
5955
USE_SDIST: 1
@@ -81,7 +77,6 @@ jobs:
8177
MINIMUM_REQUIREMENTS: ${{ matrix.MINIMUM_REQUIREMENTS }}
8278
PIP_FLAGS: ${{ matrix.PIP_FLAGS }}
8379
USE_SDIST: ${{ matrix.USE_SDIST }}
84-
USE_SCIPY: ${{ matrix.USE_SCIPY }}
8580
REFGUIDE_CHECK: ${{ matrix.REFGUIDE_CHECK }}
8681
OPTIONS_NAME: ${{ matrix.OPTIONS_NAME }}
8782
run: |
@@ -97,11 +92,9 @@ jobs:
9792
if [ "${MINIMUM_REQUIREMENTS}" == "1" ]; then
9893
pip install ${CYTHON_MIN}
9994
pip install ${NUMPY_MIN}
100-
if [ "${USE_SCIPY}" == "1" ]; then pip install ${SCIPY_MIN}; fi
10195
else
10296
pip install ${PIP_FLAGS} cython
10397
pip install ${PIP_FLAGS} numpy
104-
if [ "${USE_SCIPY}" == "1" ]; then pip install ${PIP_FLAGS} scipy; fi
10598
fi
10699
pip install ${PIP_FLAGS} matplotlib pytest
107100
@@ -147,7 +140,7 @@ jobs:
147140
popd
148141
149142
test_pywavelets_linux_free_threaded:
150-
name: linux-cp313t-with-scipy
143+
name: linux-cp313t-default
151144
runs-on: ubuntu-latest
152145
strategy:
153146
# Ensure that a wheel builder finishes even if another fails
@@ -169,7 +162,7 @@ jobs:
169162
python --version
170163
pip install --upgrade pip build
171164
# We need nightly wheels for free-threaded support and latest fixes
172-
pip install --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython numpy scipy
165+
pip install --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython numpy
173166
pip install pytest meson-python ninja
174167
pip install . -v --no-build-isolation
175168
@@ -190,7 +183,6 @@ jobs:
190183
matrix:
191184
python-version: ["3.10", "3.13"]
192185
MINIMUM_REQUIREMENTS: [0]
193-
USE_SCIPY: [0]
194186
USE_SDIST: [0]
195187
REFGUIDE_CHECK: [0]
196188
PIP_FLAGS: [""]
@@ -219,7 +211,6 @@ jobs:
219211
MINIMUM_REQUIREMENTS: ${{ matrix.MINIMUM_REQUIREMENTS }}
220212
PIP_FLAGS: ${{ matrix.PIP_FLAGS }}
221213
USE_SDIST: ${{ matrix.USE_SDIST }}
222-
USE_SCIPY: ${{ matrix.USE_SCIPY }}
223214
REFGUIDE_CHECK: ${{ matrix.REFGUIDE_CHECK }}
224215
CC: /usr/bin/clang
225216
CXX: /usr/bin/clang++
@@ -233,10 +224,8 @@ jobs:
233224
# Set numpy version first, other packages link against it
234225
if [ "${MINIMUM_REQUIREMENTS}" == "1" ]; then
235226
pip install ${CYTHON_MIN} ${NUMPY_MIN}
236-
if [ "${USE_SCIPY}" == "1" ]; then pip install ${SCIPY_MIN}; fi
237227
else
238228
pip install ${PIP_FLAGS} cython numpy
239-
if [ "${USE_SCIPY}" == "1" ]; then pip install ${PIP_FLAGS} scipy; fi
240229
fi
241230
pip install ${PIP_FLAGS} matplotlib pytest
242231

.github/workflows/wheel_tests_and_release.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
if: ${{ matrix.cibw_python }} == "cp313t"
5050
run: |
5151
PYPI_URL="https://pypi.anaconda.org/scientific-python-nightly-wheels/simple"
52-
CIBW_DEPS="pip install --pre -i $PYPI_URL cython scipy &&\
52+
CIBW_DEPS="pip install --pre -i $PYPI_URL cython &&\
5353
pip install numpy pytest meson-python ninja"
5454
NO_BUILD_ISOLATION="pip; args: --no-build-isolation"
5555
echo "CIBW_BEFORE_BUILD=$CIBW_DEPS" >> "$GITHUB_ENV"
@@ -136,7 +136,7 @@ jobs:
136136
if: ${{ matrix.cibw_python }} == "cp313t"
137137
run: |
138138
PYPI_URL="https://pypi.anaconda.org/scientific-python-nightly-wheels/simple"
139-
CIBW_DEPS="pip install --pre -i $PYPI_URL cython scipy &&\
139+
CIBW_DEPS="pip install --pre -i $PYPI_URL cython &&\
140140
pip install numpy pytest meson-python ninja"
141141
NO_BUILD_ISOLATION="pip; args: --no-build-isolation"
142142
echo "CIBW_BEFORE_BUILD=$CIBW_DEPS" >> "$GITHUB_ENV"

README.rst

+1-3
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ Installation
6767

6868
PyWavelets supports `Python`_ >=3.10, and is only dependent on `NumPy`_
6969
(supported versions are currently ``>= 1.23.0``). To pass all of the tests,
70-
`Matplotlib`_ is also required. `SciPy`_ is also an optional dependency. When
71-
present, FFT-based continuous wavelet transforms will use FFTs from SciPy
72-
rather than NumPy.
70+
`Matplotlib`_ is also required.
7371

7472
There are binary wheels for Intel Linux, Windows and macOS / OSX on PyPi. If
7573
you are on one of these platforms, you should get a binary (precompiled)

doc/source/dev/conduct/code_of_conduct.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ Endnotes
165165
We are thankful to the SciPy developers for creating the code of conduct we
166166
have adapted here.
167167

168-
- `Scipy Code of Conduct <http://scipy.github.io/devdocs/dev/conduct/code_of_conduct.html>`_
168+
- `SciPy Code of Conduct <http://scipy.github.io/devdocs/dev/conduct/code_of_conduct.html>`_
169169

170170
The SciPy code of conduct was in turn inspired by the following documents:
171171

doc/source/install.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ For the requirements needed to build from source are (Python, NumPy and Cython
4040
minimum versions in particular), see ``pyproject.toml``.
4141

4242
To run all the tests for PyWavelets, you will also need to install the
43-
Matplotlib_ package. If SciPy_ is available, FFT-based continuous wavelet
44-
transforms will use the FFT implementation from SciPy instead of NumPy.
43+
Matplotlib_ package.
4544

4645
.. seealso:: The :ref:`Development guide <dev-index>` section contains more
4746
information on building and installing from source code.

pyproject.toml

-3
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ classifiers = [
5050
"Topic :: Software Development :: Libraries :: Python Modules"
5151
]
5252

53-
[project.optional-dependencies]
54-
optional = ["scipy>=1.9"]
55-
5653
[project.urls]
5754
homepage = "https://github.com/PyWavelets/pywt"
5855
source = "https://github.com/PyWavelets/pywt"

pywt/_cwt.py

+11-21
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,14 @@
1414

1515
import numpy as np
1616

17-
try:
18-
import scipy
19-
fftmodule = scipy.fft
20-
next_fast_len = fftmodule.next_fast_len
21-
except ImportError:
22-
fftmodule = np.fft
23-
24-
# provide a fallback so scipy is an optional requirement
25-
# note: numpy.fft in numpy 2.0 is as fast as scipy.fft, so could be used
26-
# unconditionally once the minimum supported numpy version is >=2.0
27-
def next_fast_len(n):
28-
"""Round up size to the nearest power of two.
29-
30-
Given a number of samples `n`, returns the next power of two
31-
following this number to take advantage of FFT speedup.
32-
This fallback is less efficient than `scipy.fftpack.next_fast_len`
33-
"""
34-
return 2**ceil(np.log2(n))
17+
18+
def next_fast_len(n):
19+
"""Round up size to the nearest power of two.
20+
21+
Given a number of samples `n`, returns the next power of two
22+
following this number to take advantage of FFT speedup.
23+
"""
24+
return 2**ceil(np.log2(n))
3525

3626

3727
def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1):
@@ -177,10 +167,10 @@ def cwt(data, scales, wavelet, sampling_period=1., method='conv', axis=-1):
177167
)
178168
if size_scale != size_scale0:
179169
# Must recompute fft_data when the padding size changes.
180-
fft_data = fftmodule.fft(data, size_scale, axis=-1)
170+
fft_data = np.fft.fft(data, size_scale, axis=-1)
181171
size_scale0 = size_scale
182-
fft_wav = fftmodule.fft(int_psi_scale, size_scale, axis=-1)
183-
conv = fftmodule.ifft(fft_wav * fft_data, axis=-1)
172+
fft_wav = np.fft.fft(int_psi_scale, size_scale, axis=-1)
173+
conv = np.fft.ifft(fft_wav * fft_data, axis=-1)
184174
conv = conv[..., :data.shape[-1] + int_psi_scale.size - 1]
185175

186176
coef = - np.sqrt(scale) * np.diff(conv, axis=-1)

pywt/data/create_dat.py util/create_dat.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
22

3-
"""Helper script for creating image .dat files by numpy.save
3+
"""Helper script for creating image .dat files by numpy.save.
44
55
Usage:
66
@@ -10,7 +10,7 @@
1010
1111
python create_dat.py aero.png aero.dat
1212
13-
Requires Scipy and PIL.
13+
Requires SciPy and PIL, which need to be installed separately.
1414
"""
1515

1616

0 commit comments

Comments
 (0)