71
71
]
72
72
73
73
import re
74
+ import warnings
74
75
75
- from numpy import array , asanyarray , conjugate , prod , sqrt , take
76
+ import numpy as np
77
+ from numpy import array , conjugate , prod , sqrt , take
76
78
77
79
from . import _float_utils
78
80
from . import _pydfti as mkl_fft # pylint: disable=no-name-in-module
79
81
80
82
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
+
81
97
def _check_norm (norm ):
82
98
if norm not in (None , "ortho" , "forward" , "backward" ):
83
99
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'."
88
102
)
89
103
90
104
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
+ }
101
113
102
- def ortho_sc_1d (n , s ):
103
- return sqrt (frwd_sc_1d (n , s ))
114
+ return _swap_direction_map [norm ]
104
115
105
116
106
117
def trycall (func , args , kwrds ):
@@ -206,15 +217,9 @@ def fft(a, n=None, axis=-1, norm=None):
206
217
the `numpy.fft` documentation.
207
218
208
219
"""
209
- _check_norm (norm )
210
- x = _float_utils .__downcast_float128_array (a )
211
220
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 ])
218
223
219
224
return trycall (mkl_fft .fft , (x ,), {"n" : n , "axis" : axis , "fwd_scale" : fsc })
220
225
@@ -305,15 +310,9 @@ def ifft(a, n=None, axis=-1, norm=None):
305
310
>>> plt.show()
306
311
307
312
"""
308
- _check_norm (norm )
309
- x = _float_utils .__downcast_float128_array (a )
310
313
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 ])
317
316
318
317
return trycall (mkl_fft .ifft , (x ,), {"n" : n , "axis" : axis , "fwd_scale" : fsc })
319
318
@@ -402,15 +401,9 @@ def rfft(a, n=None, axis=-1, norm=None):
402
401
exploited to compute only the non-negative frequency terms.
403
402
404
403
"""
405
- _check_norm (norm )
406
- x = _float_utils .__downcast_float128_array (a )
407
404
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 ])
414
407
415
408
return trycall (mkl_fft .rfft , (x ,), {"n" : n , "axis" : axis , "fwd_scale" : fsc })
416
409
@@ -501,16 +494,9 @@ def irfft(a, n=None, axis=-1, norm=None):
501
494
specified, and the output array is purely real.
502
495
503
496
"""
504
- _check_norm (norm )
505
- x = _float_utils .__downcast_float128_array (a )
506
497
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 ))
514
500
515
501
return trycall (
516
502
mkl_fft .irfft , (x ,), {"n" : n , "axis" : axis , "fwd_scale" : fsc }
@@ -593,18 +579,12 @@ def hfft(a, n=None, axis=-1, norm=None):
593
579
[ 2., -2.]])
594
580
595
581
"""
596
- _check_norm (norm )
582
+
583
+ norm = _swap_direction (norm )
597
584
x = _float_utils .__downcast_float128_array (a )
598
585
x = array (x , copy = True , dtype = complex )
599
586
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 ))
608
588
609
589
return trycall (
610
590
mkl_fft .irfft , (x ,), {"n" : n , "axis" : axis , "fwd_scale" : fsc }
@@ -668,17 +648,12 @@ def ihfft(a, n=None, axis=-1, norm=None):
668
648
array([ 1.-0.j, 2.-0.j, 3.-0.j, 4.-0.j])
669
649
670
650
"""
651
+
671
652
# The copy may be required for multithreading.
672
- _check_norm (norm )
653
+ norm = _swap_direction (norm )
673
654
x = _float_utils .__downcast_float128_array (a )
674
655
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 ])
682
657
683
658
output = trycall (
684
659
mkl_fft .rfft , (x ,), {"n" : n , "axis" : axis , "fwd_scale" : fsc }
@@ -688,22 +663,46 @@ def ihfft(a, n=None, axis=-1, norm=None):
688
663
return output
689
664
690
665
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 ):
692
668
if s is None :
693
- shapeless = 1
669
+ shapeless = True
694
670
if axes is None :
695
671
s = list (a .shape )
696
672
else :
697
673
s = take (a .shape , axes )
698
674
else :
699
- shapeless = 0
675
+ shapeless = False
700
676
s = list (s )
701
677
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 )
702
688
axes = list (range (- len (s ), 0 ))
703
689
if len (s ) != len (axes ):
704
690
raise ValueError ("Shape and axes have different lengths." )
705
691
if invreal and shapeless :
706
692
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
+
707
706
return s , axes
708
707
709
708
@@ -806,15 +805,10 @@ def fftn(a, s=None, axes=None, norm=None):
806
805
>>> plt.show()
807
806
808
807
"""
809
- _check_norm (norm )
810
- x = _float_utils .__downcast_float128_array (a )
811
808
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 )
818
812
819
813
return trycall (mkl_fft .fftn , (x ,), {"s" : s , "axes" : axes , "fwd_scale" : fsc })
820
814
@@ -918,15 +912,10 @@ def ifftn(a, s=None, axes=None, norm=None):
918
912
>>> plt.show()
919
913
920
914
"""
921
- _check_norm (norm )
922
- x = _float_utils .__downcast_float128_array (a )
923
915
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 )
930
919
931
920
return trycall (
932
921
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):
1025
1014
0.0 +0.j , 0.0 +0.j ]])
1026
1015
1027
1016
"""
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 )
1031
1019
1032
1020
1033
1021
def ifft2 (a , s = None , axes = (- 2 , - 1 ), norm = None ):
@@ -1119,9 +1107,8 @@ def ifft2(a, s=None, axes=(-2, -1), norm=None):
1119
1107
[ 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]])
1120
1108
1121
1109
"""
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 )
1125
1112
1126
1113
1127
1114
def rfftn (a , s = None , axes = None , norm = None ):
@@ -1213,19 +1200,10 @@ def rfftn(a, s=None, axes=None, norm=None):
1213
1200
[ 0.+0.j, 0.+0.j]]])
1214
1201
1215
1202
"""
1216
- _check_norm (norm )
1217
- x = _float_utils .__downcast_float128_array (a )
1218
1203
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 )
1229
1207
1230
1208
return trycall (
1231
1209
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):
1271
1249
For more details see `rfftn`.
1272
1250
1273
1251
"""
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 )
1277
1254
1278
1255
1279
1256
def irfftn (a , s = None , axes = None , norm = None ):
@@ -1367,19 +1344,10 @@ def irfftn(a, s=None, axes=None, norm=None):
1367
1344
[ 1., 1.]]])
1368
1345
1369
1346
"""
1370
- _check_norm (norm )
1371
- x = _float_utils .__downcast_float128_array (a )
1372
1347
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 )
1383
1351
1384
1352
return trycall (
1385
1353
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):
1425
1393
For more details see `irfftn`.
1426
1394
1427
1395
"""
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