7171]
7272
7373import 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
7779from . import _float_utils
7880from . 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+
8197def _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
106117def 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
10331021def 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
11271114def 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
12791256def 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 )
0 commit comments