Skip to content

Commit 57c4c52

Browse files
authored
raise warning similar to numpy >= 2.0 (#139)
* raise warning similar to numpy * changes to raise warning only when numpy > 2.0 is used * remove duplication * address comments
1 parent bee4cf6 commit 57c4c52

File tree

7 files changed

+102
-130
lines changed

7 files changed

+102
-130
lines changed

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,5 @@ The package also provides `mkl_fft._numpy_fft` and `mkl_fft._scipy_fft` interfac
8282

8383
To build ``mkl_fft`` from sources on Linux:
8484
- install a recent version of MKL, if necessary;
85-
- execute ``source /path_to_oneapi/mkl/latest/env/vars.sh`` ;
85+
- execute ``source /path_to_oneapi/mkl/latest/env/vars.sh``;
8686
- execute ``python -m pip install .``

Diff for: mkl_fft/_float_utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def __downcast_float128_array(x):
8181

8282
def __supported_array_or_not_implemented(x):
8383
"""
84-
Used in _scipy_fft_backend to convert array to float32,
84+
Used in _scipy_fft to convert array to float32,
8585
float64, complex64, or complex128 type or return NotImplemented
8686
"""
8787
__x = np.asarray(x)

Diff for: mkl_fft/_numpy_fft.py

+89-122
Original file line numberDiff line numberDiff line change
@@ -71,36 +71,47 @@
7171
]
7272

7373
import re
74+
import warnings
7475

75-
from numpy import array, asanyarray, conjugate, prod, sqrt, take
76+
import numpy as np
77+
from numpy import array, conjugate, prod, sqrt, take
7678

7779
from . import _float_utils
7880
from . import _pydfti as mkl_fft # pylint: disable=no-name-in-module
7981

8082

83+
def _compute_fwd_scale(norm, n, shape):
84+
_check_norm(norm)
85+
if norm in (None, "backward"):
86+
return 1.0
87+
88+
ss = n if n is not None else shape
89+
nn = prod(ss)
90+
fsc = 1 / nn if nn != 0 else 1
91+
if norm == "forward":
92+
return fsc
93+
else: # norm == "ortho"
94+
return sqrt(fsc)
95+
96+
8197
def _check_norm(norm):
8298
if norm not in (None, "ortho", "forward", "backward"):
8399
raise ValueError(
84-
(
85-
"Invalid norm value {} should be None, "
86-
'"ortho", "forward", or "backward".'
87-
).format(norm)
100+
f"Invalid norm value {norm} should be None, 'ortho', 'forward', "
101+
"or 'backward'."
88102
)
89103

90104

91-
def frwd_sc_1d(n, s):
92-
nn = n if n is not None else s
93-
return 1 / nn if nn != 0 else 1
94-
95-
96-
def frwd_sc_nd(s, x_shape):
97-
ss = s if s is not None else x_shape
98-
nn = prod(ss)
99-
return 1 / nn if nn != 0 else 1
100-
105+
def _swap_direction(norm):
106+
_check_norm(norm)
107+
_swap_direction_map = {
108+
"backward": "forward",
109+
None: "forward",
110+
"ortho": "ortho",
111+
"forward": "backward",
112+
}
101113

102-
def ortho_sc_1d(n, s):
103-
return sqrt(frwd_sc_1d(n, s))
114+
return _swap_direction_map[norm]
104115

105116

106117
def trycall(func, args, kwrds):
@@ -206,15 +217,9 @@ def fft(a, n=None, axis=-1, norm=None):
206217
the `numpy.fft` documentation.
207218
208219
"""
209-
_check_norm(norm)
210-
x = _float_utils.__downcast_float128_array(a)
211220

212-
if norm in (None, "backward"):
213-
fsc = 1.0
214-
elif norm == "forward":
215-
fsc = frwd_sc_1d(n, x.shape[axis])
216-
else:
217-
fsc = ortho_sc_1d(n, x.shape[axis])
221+
x = _float_utils.__downcast_float128_array(a)
222+
fsc = _compute_fwd_scale(norm, n, x.shape[axis])
218223

219224
return trycall(mkl_fft.fft, (x,), {"n": n, "axis": axis, "fwd_scale": fsc})
220225

@@ -305,15 +310,9 @@ def ifft(a, n=None, axis=-1, norm=None):
305310
>>> plt.show()
306311
307312
"""
308-
_check_norm(norm)
309-
x = _float_utils.__downcast_float128_array(a)
310313

311-
if norm in (None, "backward"):
312-
fsc = 1.0
313-
elif norm == "forward":
314-
fsc = frwd_sc_1d(n, x.shape[axis])
315-
else:
316-
fsc = ortho_sc_1d(n, x.shape[axis])
314+
x = _float_utils.__downcast_float128_array(a)
315+
fsc = _compute_fwd_scale(norm, n, x.shape[axis])
317316

318317
return trycall(mkl_fft.ifft, (x,), {"n": n, "axis": axis, "fwd_scale": fsc})
319318

@@ -402,15 +401,9 @@ def rfft(a, n=None, axis=-1, norm=None):
402401
exploited to compute only the non-negative frequency terms.
403402
404403
"""
405-
_check_norm(norm)
406-
x = _float_utils.__downcast_float128_array(a)
407404

408-
if norm in (None, "backward"):
409-
fsc = 1.0
410-
elif norm == "forward":
411-
fsc = frwd_sc_1d(n, x.shape[axis])
412-
else:
413-
fsc = ortho_sc_1d(n, x.shape[axis])
405+
x = _float_utils.__downcast_float128_array(a)
406+
fsc = _compute_fwd_scale(norm, n, x.shape[axis])
414407

415408
return trycall(mkl_fft.rfft, (x,), {"n": n, "axis": axis, "fwd_scale": fsc})
416409

@@ -501,16 +494,9 @@ def irfft(a, n=None, axis=-1, norm=None):
501494
specified, and the output array is purely real.
502495
503496
"""
504-
_check_norm(norm)
505-
x = _float_utils.__downcast_float128_array(a)
506497

507-
nn = n if n else 2 * (x.shape[axis] - 1)
508-
if norm in (None, "backward"):
509-
fsc = 1.0
510-
elif norm == "forward":
511-
fsc = frwd_sc_1d(nn, nn)
512-
else:
513-
fsc = ortho_sc_1d(nn, nn)
498+
x = _float_utils.__downcast_float128_array(a)
499+
fsc = _compute_fwd_scale(norm, n, 2 * (x.shape[axis] - 1))
514500

515501
return trycall(
516502
mkl_fft.irfft, (x,), {"n": n, "axis": axis, "fwd_scale": fsc}
@@ -593,18 +579,12 @@ def hfft(a, n=None, axis=-1, norm=None):
593579
[ 2., -2.]])
594580
595581
"""
596-
_check_norm(norm)
582+
583+
norm = _swap_direction(norm)
597584
x = _float_utils.__downcast_float128_array(a)
598585
x = array(x, copy=True, dtype=complex)
599586
conjugate(x, out=x)
600-
601-
nn = n if n else 2 * (x.shape[axis] - 1)
602-
if norm in (None, "backward"):
603-
fsc = frwd_sc_1d(nn, nn)
604-
elif norm == "forward":
605-
fsc = 1.0
606-
else:
607-
fsc = ortho_sc_1d(nn, nn)
587+
fsc = _compute_fwd_scale(norm, n, 2 * (x.shape[axis] - 1))
608588

609589
return trycall(
610590
mkl_fft.irfft, (x,), {"n": n, "axis": axis, "fwd_scale": fsc}
@@ -668,17 +648,12 @@ def ihfft(a, n=None, axis=-1, norm=None):
668648
array([ 1.-0.j, 2.-0.j, 3.-0.j, 4.-0.j])
669649
670650
"""
651+
671652
# The copy may be required for multithreading.
672-
_check_norm(norm)
653+
norm = _swap_direction(norm)
673654
x = _float_utils.__downcast_float128_array(a)
674655
x = array(x, copy=True, dtype=float)
675-
676-
if norm in (None, "backward"):
677-
fsc = frwd_sc_1d(n, x.shape[axis])
678-
elif norm == "forward":
679-
fsc = 1.0
680-
else:
681-
fsc = ortho_sc_1d(n, x.shape[axis])
656+
fsc = _compute_fwd_scale(norm, n, x.shape[axis])
682657

683658
output = trycall(
684659
mkl_fft.rfft, (x,), {"n": n, "axis": axis, "fwd_scale": fsc}
@@ -688,22 +663,46 @@ def ihfft(a, n=None, axis=-1, norm=None):
688663
return output
689664

690665

691-
def _cook_nd_args(a, s=None, axes=None, invreal=0):
666+
# copied from: https://github.com/numpy/numpy/blob/main/numpy/fft/_pocketfft.py
667+
def _cook_nd_args(a, s=None, axes=None, invreal=False):
692668
if s is None:
693-
shapeless = 1
669+
shapeless = True
694670
if axes is None:
695671
s = list(a.shape)
696672
else:
697673
s = take(a.shape, axes)
698674
else:
699-
shapeless = 0
675+
shapeless = False
700676
s = list(s)
701677
if axes is None:
678+
if not shapeless and np.__version__ >= "2.0":
679+
msg = (
680+
"`axes` should not be `None` if `s` is not `None` "
681+
"(Deprecated in NumPy 2.0). In a future version of NumPy, "
682+
"this will raise an error and `s[i]` will correspond to "
683+
"the size along the transformed axis specified by "
684+
"`axes[i]`. To retain current behaviour, pass a sequence "
685+
"[0, ..., k-1] to `axes` for an array of dimension k."
686+
)
687+
warnings.warn(msg, DeprecationWarning, stacklevel=3)
702688
axes = list(range(-len(s), 0))
703689
if len(s) != len(axes):
704690
raise ValueError("Shape and axes have different lengths.")
705691
if invreal and shapeless:
706692
s[-1] = (a.shape[axes[-1]] - 1) * 2
693+
if None in s and np.__version__ >= "2.0":
694+
msg = (
695+
"Passing an array containing `None` values to `s` is "
696+
"deprecated in NumPy 2.0 and will raise an error in "
697+
"a future version of NumPy. To use the default behaviour "
698+
"of the corresponding 1-D transform, pass the value matching "
699+
"the default for its `n` parameter. To use the default "
700+
"behaviour for every axis, the `s` argument can be omitted."
701+
)
702+
warnings.warn(msg, DeprecationWarning, stacklevel=3)
703+
# use the whole input array along axis `i` if `s[i] == -1 or None`
704+
s = [a.shape[_a] if _s in [-1, None] else _s for _s, _a in zip(s, axes)]
705+
707706
return s, axes
708707

709708

@@ -806,15 +805,10 @@ def fftn(a, s=None, axes=None, norm=None):
806805
>>> plt.show()
807806
808807
"""
809-
_check_norm(norm)
810-
x = _float_utils.__downcast_float128_array(a)
811808

812-
if norm in (None, "backward"):
813-
fsc = 1.0
814-
elif norm == "forward":
815-
fsc = frwd_sc_nd(s, x.shape)
816-
else:
817-
fsc = sqrt(frwd_sc_nd(s, x.shape))
809+
x = _float_utils.__downcast_float128_array(a)
810+
s, axes = _cook_nd_args(x, s, axes)
811+
fsc = _compute_fwd_scale(norm, s, x.shape)
818812

819813
return trycall(mkl_fft.fftn, (x,), {"s": s, "axes": axes, "fwd_scale": fsc})
820814

@@ -918,15 +912,10 @@ def ifftn(a, s=None, axes=None, norm=None):
918912
>>> plt.show()
919913
920914
"""
921-
_check_norm(norm)
922-
x = _float_utils.__downcast_float128_array(a)
923915

924-
if norm in (None, "backward"):
925-
fsc = 1.0
926-
elif norm == "forward":
927-
fsc = frwd_sc_nd(s, x.shape)
928-
else:
929-
fsc = sqrt(frwd_sc_nd(s, x.shape))
916+
x = _float_utils.__downcast_float128_array(a)
917+
s, axes = _cook_nd_args(x, s, axes)
918+
fsc = _compute_fwd_scale(norm, s, x.shape)
930919

931920
return trycall(
932921
mkl_fft.ifftn, (x,), {"s": s, "axes": axes, "fwd_scale": fsc}
@@ -1025,9 +1014,8 @@ def fft2(a, s=None, axes=(-2, -1), norm=None):
10251014
0.0 +0.j , 0.0 +0.j ]])
10261015
10271016
"""
1028-
_check_norm(norm)
1029-
x = _float_utils.__downcast_float128_array(a)
1030-
return fftn(x, s=s, axes=axes, norm=norm)
1017+
1018+
return fftn(a, s=s, axes=axes, norm=norm)
10311019

10321020

10331021
def ifft2(a, s=None, axes=(-2, -1), norm=None):
@@ -1119,9 +1107,8 @@ def ifft2(a, s=None, axes=(-2, -1), norm=None):
11191107
[ 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]])
11201108
11211109
"""
1122-
_check_norm(norm)
1123-
x = _float_utils.__downcast_float128_array(a)
1124-
return ifftn(x, s=s, axes=axes, norm=norm)
1110+
1111+
return ifftn(a, s=s, axes=axes, norm=norm)
11251112

11261113

11271114
def rfftn(a, s=None, axes=None, norm=None):
@@ -1213,19 +1200,10 @@ def rfftn(a, s=None, axes=None, norm=None):
12131200
[ 0.+0.j, 0.+0.j]]])
12141201
12151202
"""
1216-
_check_norm(norm)
1217-
x = _float_utils.__downcast_float128_array(a)
12181203

1219-
if norm in (None, "backward"):
1220-
fsc = 1.0
1221-
elif norm == "forward":
1222-
x = asanyarray(x)
1223-
s, axes = _cook_nd_args(x, s, axes)
1224-
fsc = frwd_sc_nd(s, x.shape)
1225-
else:
1226-
x = asanyarray(x)
1227-
s, axes = _cook_nd_args(x, s, axes)
1228-
fsc = sqrt(frwd_sc_nd(s, x.shape))
1204+
x = _float_utils.__downcast_float128_array(a)
1205+
s, axes = _cook_nd_args(x, s, axes)
1206+
fsc = _compute_fwd_scale(norm, s, x.shape)
12291207

12301208
return trycall(
12311209
mkl_fft.rfftn, (x,), {"s": s, "axes": axes, "fwd_scale": fsc}
@@ -1271,9 +1249,8 @@ def rfft2(a, s=None, axes=(-2, -1), norm=None):
12711249
For more details see `rfftn`.
12721250
12731251
"""
1274-
_check_norm(norm)
1275-
x = _float_utils.__downcast_float128_array(a)
1276-
return rfftn(x, s, axes, norm)
1252+
1253+
return rfftn(a, s, axes, norm)
12771254

12781255

12791256
def irfftn(a, s=None, axes=None, norm=None):
@@ -1367,19 +1344,10 @@ def irfftn(a, s=None, axes=None, norm=None):
13671344
[ 1., 1.]]])
13681345
13691346
"""
1370-
_check_norm(norm)
1371-
x = _float_utils.__downcast_float128_array(a)
13721347

1373-
if norm in (None, "backward"):
1374-
fsc = 1.0
1375-
elif norm == "forward":
1376-
x = asanyarray(x)
1377-
s, axes = _cook_nd_args(x, s, axes, invreal=1)
1378-
fsc = frwd_sc_nd(s, x.shape)
1379-
else:
1380-
x = asanyarray(x)
1381-
s, axes = _cook_nd_args(x, s, axes, invreal=1)
1382-
fsc = sqrt(frwd_sc_nd(s, x.shape))
1348+
x = _float_utils.__downcast_float128_array(a)
1349+
s, axes = _cook_nd_args(x, s, axes, invreal=True)
1350+
fsc = _compute_fwd_scale(norm, s, x.shape)
13831351

13841352
return trycall(
13851353
mkl_fft.irfftn, (x,), {"s": s, "axes": axes, "fwd_scale": fsc}
@@ -1425,6 +1393,5 @@ def irfft2(a, s=None, axes=(-2, -1), norm=None):
14251393
For more details see `irfftn`.
14261394
14271395
"""
1428-
_check_norm(norm)
1429-
x = _float_utils.__downcast_float128_array(a)
1430-
return irfftn(x, s, axes, norm)
1396+
1397+
return irfftn(a, s, axes, norm)

Diff for: mkl_fft/_pydfti.pyx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ def _fftnd_impl(x, s=None, axes=None, overwrite_x=False, direction=+1, double fs
11001100
_direct_fftnd,
11011101
{'overwrite_x': overwrite_x, 'direction': direction, 'fsc': fsc},
11021102
res
1103-
)
1103+
)
11041104
else:
11051105
sc = <object> fsc
11061106
return _iter_fftnd(x, s=s, axes=axes,
@@ -1200,7 +1200,7 @@ def rfftn(x, s=None, axes=None, fwd_scale=1.0):
12001200
a = _fix_dimensions(a, tuple(ss), axes)
12011201
if len(set(axes)) == len(axes) and len(axes) == a.ndim and len(axes) > 2:
12021202
ss, aa = _remove_axis(s, axes, -1)
1203-
ind = [slice(None,None,1),] * len(s)
1203+
ind = [slice(None, None, 1),] * len(s)
12041204
for ii in range(a.shape[la]):
12051205
ind[la] = ii
12061206
tind = tuple(ind)

0 commit comments

Comments
 (0)