
    
9j2                    &   S SK Jr  S SKrS SKrS SKrS SKrS SKJr  S SK	J
r
  \R                  r\R                  R                  R                  r\R"                  R%                  5       S 5       rS rS(S jrS r S)S	 jrS*S
 jr  S+S jrS,S jrS r S-S jrS r S)S jr  S.S jrS/S jr S r!S0S jr"S0S jr#S1S jr$S1S jr%S)S jr&S)S jr'S0S jr(S0S jr)S1S jr*S1S jr+S)S jr,S r-S)S  jr.S! r/S0S" jr0S0S# jr1S2S$ jr2S2S% jr3S*S& jr4S*S' jr5g)3    )annotationsN)config)get_plan_cachec                <   US:w  ak  U [         R                  [         R                  4;   a  [         R                  $ U [         R                  [         R                  4;  a  [         R                  $  U $ U [         R                  [         R                  4;   a.  [         R
                  " U R                  R                  5       5      $ U [         R                  :X  a  [         R                  $ U [         R                  [         R                  4;  a  [         R                  $ U $ )NR2C)	npfloat16float32	complex64
complex128dtypecharlowerfloat64)r   
value_types     G/home/wildlama/miniconda3/lib/python3.13/site-packages/cupy/fft/_fft.py_output_dtyper      s    URZZ,,<<2<<77==  8 L R\\2==1188EJJ,,.//bjj ::2::rzz22::L    c                r    [        U R                  U5      nX R                  :w  a  U R                  U5      n U $ N)r   r   astype)ar   	out_dtypes      r   _convert_dtyper   "   s/    aggz2IGGHHYHr   c                D   Ub  XR                   :X  a  U $ US:X  a  US   b  [        U5      nUS   S-  S-   US'   [        X5       H  u  pVUc  M
  XPR                   U   :w  d  M  [        U R                   5      nXv   U:  a7  [        S 5      /U R                  -  n[        SU5      X'   U [        U5         n Mr  [        S 5      /U R                  -  n[        SXv   5      X'   XWU'   [        R                  " XpR                  R                  US9n	X	[        U5      '   U	n M     U $ )NC2R      r   order)
shapelistzipslicendimtuplecupyzerosr   r   )
r   saxesr   r!   szaxisr"   indexzs
             r   _cook_shaper0   )   s   yALe!B%"3G"
Q"LNwwt}!4ME{Rt.#ArleElOt.#Au{3 dJJuggll%@"#%, ! Hr   c                   SSK Jn  US:X  a   U [        R                  :X  a  UR                  $ US:X  a   U [        R
                  :X  a  UR                  $ US:X  a   U [        R                  :X  a  UR                  $ US:X  a   U [        R                  :X  a  UR                  $ US:X  a   U [        R                  :X  a  UR                  $ US:X  a   U [        R                  :X  a  UR                  $ [        e)Nr   cufftC2Cr   r   )	cupy.cudar3   r   r   	CUFFT_C2Cr
   	CUFFT_R2C	CUFFT_C2Rr   	CUFFT_Z2Zr   	CUFFT_D2Z	CUFFT_Z2D
ValueError)r   r   r3   s      r   _convert_fft_typer=   @   s    Uu4	u	"**!4	u	",,!6	u	"--!7	u	"**!4	u	"--!7r   c	                X	   SSK Jn	  [        U R                  U5      n
X@R                  -  U R                  S-
  :w  a  U R                  US5      n U R                  c  U R                  R                  (       d  U R                  5       n O[        R                  R                  R                  (       d  US:X  a  U(       d  U R                  5       n O?[        R                  R                  R                  (       a  US:w  a  U R                  5       n U R                  S   nUS:  a  [        SU-  5      e[        R                  R                  R                  (       a6  US:X  a0  SU S   l        Uc  SU S	   l        OUS
-  S:X  a  SU SUS
-  4   l        Uc  UnU R"                  U-  nU	R%                  5       nUb  Uc  UnO['        S5      eUGc3  [(        R*                  nXjX4n[(        R,                  " 5       nUbS  UR.                  nUR0                  nUUR2                  UR4                  Uc  SOUR6                  Uc  SOUR6                  4-  n[9        5       nUR;                  U5      nUb  UnGO;Uc  U	R=                  XjXS9nUUU'   GO!U(       a  [?        S5      eUR@                  S:X  a(  URC                  SUS S 45      nURE                  U5        O(URE                  U
5      nURC                  USUS S 45      nUUU'   O[G        XR<                  5      (       d  [        S5      eXRH                  :w  a  [        S5      eXhRJ                  :w  a  [        SXhRJ                  5      eXRL                  :w  a  [        S5      e[(        RN                  URP                  S L:w  a  [        S5      eU(       a	  US:X  a  U nO&Ub  URS                  X5        OURU                  U 5      nUS:w  a  URW                  XU5        UR                  S   nXRX                  :X  d  XRZ                  :X  a  UnUS:X  a  XR\                  :X  a  UU-  nO:US:X  a  U[^        R`                  " U5      -  nOUS:X  a  XRb                  :X  a  UU-  nX@R                  -  U R                  S-
  :w  a  UR                  US5      nU$ )Nr   r2   r   r   r   r4   1Invalid number of FFT data points (%d) specified.).r   ).r   r   .AUse the cuFFT plan either as a context manager or as an argument.)devicesz/multi-GPU cuFFT callbacks are not yet supportedlegacyPlan1dz'expected plan to have type cufft.Plan1dcuFFT plan dtype mismatch.z*Target array size does not match the plan.z#Batch size does not match the plan.z/Unclear if multiple GPUs are to be used or not.backwardorthoforward)2r5   r3   r=   r   r&   swapaxesbaseflagsc_contiguouscopyr(   cudaruntimeis_hipr"   r<   imagsizeget_current_planRuntimeErrorr   rA   get_current_callback_managercb_load_datacb_store_datacb_loadcb_storeptrr   getrC   NotImplementedErroridentitycreate_planset_callbacks
isinstancefft_typenxbatchuse_multi_gpusgpuscheck_output_arrayget_output_arrayfftr7   r:   CUFFT_INVERSEmathsqrtCUFFT_FORWARD)r   	directionr   normr-   overwrite_xout_sizeoutplanr3   ra   nrc   	curr_planrA   keysmgr	load_data
store_datacachecached_planr,   s                         r   	_exec_fftr{   S   s/    *5Hff}
"JJtR vv!5!5FFHII$$eK FFH				!	!jE&9 FFH	A1u?!CE 	E yyJ%$7&	AgJO\Q)*Ac8q= !&FFaKE &&(I<D  5 6 6 |..E3113? ((I**JS[[#,,#+Q$,Q*..B BD  iio"D[<<E<KDE$K ) +: ; ;||x'$s)'<=!!$'((2thSb	-BCE$K $--FGG}}$9::wwI%ww0 0JJBCC  TYYd%:;NOOzU*	'##A&z#	2B??"h//&Azi+>+>>r		tyy}		y,?,??r	ff}
"ll4$Jr   c                0    U H  n[        XSX&XES9n M     U $ )Nr4   rr   )r{   )r   rm   rn   r+   ro   rr   r-   s          r   _fft_c2cr~      s!    aE4{N Hr   c           	        [        U [        R                  5      (       d  [        S5      eUb&  Ub#  [	        U5      [	        U5      :w  a  [        S5      eUc8  Uc  U R                  nO[	        U5      n[        U* S5       V	s/ s H  oPM     nn	O[        U5      nU(       d  US:X  a  U $ [        S5      eUc  SnUS;  a  [        SU-  5      e[        X5      n [        XX%5      n US:X  a  [        XX2XgS	9n U $ US
:X  a#  [        XXSUS   U5      n [        XX2S S U5      n U $ [        XX2S S U5      n [        U R                  XS   U5      n
[        XXSUS   UU
5      n U $ s  sn	f )N(The input array a must be a cupy.ndarray&Shape and axes have different lengths.r   r4   list index out of rangerF   rF   rG   rH   CInvalid norm value %s, should be "backward", "ortho", or "forward".r}   r   r   )r`   r(   ndarray	TypeErrorlenr<   r&   ranger'   
IndexErrorr   r0   r~   r{   _get_fftn_out_sizer"   )r   r*   r+   rn   rm   r   ro   rr   dimirp   s              r   _fftr      s   a&&BCC	D,#a&CI2EABB|9&&Ca&C #q>*>a>*T{H677| 33 2489 : 	:q%AA$+AUQ4{F H 
u	aJd2hLQ4crK@ H Q4crK@%aggqr(JGaJd2h  H? +s   Ec           	     v   Ub&  Ub#  [        U5      [        U5      :w  a  [        S5      eUc?  Uc  U nO[        U5      n[        [        U* S5       Vs/ s H  oUU -   PM	     sn5      nUnX&4$ [        U5      nU(       d  g[	        [
        U5      U * :  d  [	        [        U5      U S-
  :  a  [        S5      eUS:X  a*  [        [        U Vs/ s H  owU -  PM	     sn5      5      nX&4$ [        USS  Vs/ s H  owU -  PM	     sn5      nUR                  US   U -  5        [        U5      nX&4$ s  snf s  snf s  snf )	zoConfigure axes argument for an n-dimensional FFT.

The axes to be transformed are returned in ascending order.
Nr   r   ) r   r   z/The specified axes exceed the array dimensions.r4   r   )	r   r<   r'   r   _reduceminmaxsortedappend)r&   r*   r+   r   r   r   axes_sortedaxs           r   _prep_fftn_axesr   
  sF    	
D,#a&CI2EABB|9Ca&CsdA71$h78"  T{3%d);dQh)FNOOD'ADbT	D'A BCK  !d3Bi!@it)i!@AKtBx$/,K % 8 (B "As   D,
D12D6c                   ^  S[        T 5      s=:  =(       a    S:*  Os  =(       aE    ST ;   =(       d    US-
  T ;   =(       a*    [        U 4S j[        [        T 5      S-
  5       5       5      $ )Nr      r   c              3  F   >#    U  H  nTUS -      TU   -
  S :H  v   M     g7f)r   Nr   ).0rs   r   s     r   	<genexpr>'_nd_plan_is_possible.<locals>.<genexpr>3  s/      :8 !Q'+a.8Q>8s   !)r   allr   )r   r&   s   ` r   _nd_plan_is_possibler   .  sc     K %%A% :k!>dQh;%>: :"3{#3a#78: :;r   c                   SSK Jn  [        U 5      nXR                  UR                  4;   a  SnO XR
                  UR                  4;   a  SnOSnUc  [        [        U5      5      n	O[        USUUS9u  p[        X5      (       d  [        S5      eUS	;  a  [        S
5      e U	 Vs/ s H  oU   PM	     nnUS:X  a  USSS2   n[        U5      nXR                  UR                  4;   a  UnUnO=[        U5      nUb  XMS'   [        U5      nXR                  UR                  4;   a  UnOUnUnUnU	[        [        U5      5      :X  a  SnS=nnS=nnOSU	;  aN  [        [         U	5      n[#        U SU 5      nUS:X  a  [#        U5      n[#        U5      nSnSnOpUS:X  a  SnSnUnUnOaUS-
  U	;  aM  U[        U	5      -
  n[#        U U* S 5      nUS:X  a	  SnSnUnUnO,US:X  a  [#        U5      n[#        U5      nSnSnO[        S5      eU H  nUS:  d  M  [        S5      e   XWWUWWUUX9S   U4n[$        R&                  " 5       nUbS  UR(                  nUR*                  nUUR,                  UR.                  Uc  SOUR0                  Uc  SOUR0                  4-  n[3        5       nUR5                  U5      nUb  UnU$ Uc  UR6                  " U6 nU(       a  UUU'   U$ UR8                  S:X  a(  UR;                  SUSS 45      nUR=                  U5        O(UR=                  U5      nUR;                  USUSS 45      nU(       a  UUU'   U$ s  snf )a  Generate a CUDA FFT plan for transforming up to three axes.

Args:
    shape (tuple of int): The shape of the array to transform
    fft_type (int): The FFT type to perform. Supported values are:
        `cufft.CUFFT_C2C`, `cufft.CUFFT_C2R`, `cufft.CUFFT_R2C`,
        `cufft.CUFFT_Z2Z`, `cufft.CUFFT_Z2D`, and `cufft.CUFFT_D2Z`.
    axes (None or int or tuple of int):  The axes of the array to
        transform. Currently, these must be a set of up to three adjacent
        axes and must include either the first or the last axis of the
        array.  If `None`, it is assumed that all axes are transformed.
    order ({'C', 'F'}): Specify whether the data to be transformed has C or
        Fortran ordered data layout.
    out_size (int): The output length along the last axis for R2C/C2R FFTs.
        For C2C FFT, this is ignored (and set to `None`).
    to_cache (bool): Whether to cache the generated plan. Default is
        ``True``.

Returns:
    plan (cufft.PlanNd): A cuFFT Plan for the chosen `fft_type`.
r   r2   r4   r   r   N)r*   r+   r   zAn n-dimensional cuFFT plan could not be created. The axes must be contiguous and non-repeating. Between one and three axes can be transformed and either the first or last axis must be included in axes.CFzorder must be 'C' or 'F'r   r   r   r   zzGeneral subsets of FFT axes not currently supported for GPU case (Can only batch FFT over the first or last spatial axes).z,Invalid number of FFT data points specified.rB   PlanNd)r5   r3   r   r6   r9   r8   r;   r'   r   r   r   r<   r#   r7   r:   r   r   _prodr   rU   rV   rW   rX   rY   rZ   r   r[   r   r]   r^   r_   ) r"   ra   r+   r!   rp   to_cacher3   r&   r   fft_axes_din_dimensionsout_dimensionsplan_dimensionsinembedonembednbatchidistodististrideostridemin_axis_fftnum_axes_batchrs   ru   rv   rw   rx   ry   rz   rr   s                                    r   _get_cufft_plan_ndr   7  s   .  u:DOOU__55
	oou7	7

|t%%dd1;=  // ! 	! J788& (00x!1XxM0|%dd+-(MOOU__55&'m,!)2~.99+O,OGG5t%%' H"31L5,/0F|m,n-#  Qhx'!CM1N5.!123F|  #m,n-!" "
 q5>@ @ 
 g7GUfeb\8=D 
-
-
/C
 $$	&&
cll'Y]] (jnn> 	> E))D/K K 
||T"E$K K <<8#??Hd3Bi#89Dd#$$X.D??4(D"I)>?DE$KKI 1s   'Mc                t    US:X  a  Ub  US   c  SX   S-
  -  nU$ US   n U$ US:X  a  X   S-  S-   nU$ S nU$ )Nr   r   r   r   r   r   )in_shaper*   	last_axisr   rp   s        r   r   r     sq    UI1R5=H/!34H O uH
 O	 
u	&!+a/ O Or   c	                   SSK Jn	  [        U R                  U5      n
U R                  R
                  (       a  SnO)U R                  R                  (       a  SnO[        S5      eUS:X  a  U(       d  U R                  5       n O?[        R                  R                  R                  (       a  US:w  a  U R                  5       n U	R                  5       nUb  UnUc  [        U R                  XUUS9nGOb[!        XiR"                  5      (       d  [        S	5      eXR$                  :w  a%  [        S
R'                  UR$                  U5      5      eU R                  R
                  (       a)  U Vs/ s H  oR                  U   PM     nnUS:X  a  XS'   O$US S S2    Vs/ s H  oR                  U   PM     nn[)        U5      nXR                  :w  a/  [        SR'                  UR                  XR                  5      5      eXR*                  :w  a  [        S5      eUS:w  a8  US   UR,                  :w  a  [        S5      eXR.                  :w  a  [        S5      eU(       a	  US:X  a  U nO$Uc  UR1                  XS9nOUR3                  X5        UR4                  S:w  a  UR7                  XU5        XR8                  U	R:                  4;   a  U OUn[=        U Vs/ s H  oR                  U   PM     sn5      nUS:X  a  XR>                  :X  a  UU-  nU$ US:X  a  U[@        RB                  " U5      -  nU$ US:X  a  XRD                  :X  a  UU-  nU$ s  snf s  snf s  snf )Nr   r2   r   r   za must be contiguousr   r4   )r+   r!   rp   z'expected plan to have type cufft.PlanNdz+array orders mismatch (plan: {}, input: {})r   zYThe cuFFT plan and a.shape do not match: plan.shape = {}, expected_shape={}, a.shape = {}rE   z"The last axis for R2C/C2R mismatchz-The size along the last R2C/C2R axis mismatchr    rF   rG   rH   )#r5   r3   r=   r   rK   rL   f_contiguousr<   rM   r(   rN   rO   rP   rS   r   r"   r`   r   r!   formatr'   ra   r   	last_sizerg   rf   rR   rh   r7   r:   r   ri   rj   rk   rl   )r   rm   r   rn   r+   ro   rr   rq   rp   r3   ra   r!   rt   r   expected_shapearrr,   s                    r   
_exec_fftnr     s    *5Hww	
		/00U; FFH				!	!jE&9 FFH &&(I|!!''8e+35 $--FGGJJJ$fTZZ79 977489DbggbkDN9U"%-r" 592J?JbggbkJN?~.ZZ'CCI6JJD9: : }}$9::Bx4>>) !EFF>>)  ", - - zU*	##A#3'
xx1}# OOU__==!3C	-"		"-	.Bzi+>+>>r	 J 
tyy} J 
	y,?,??r	JW :
 @< .s   )M	MMc
                   [        U [        R                  5      (       d  [        S5      eUc  SnUS;  a  [	        SU-  5      e[        U R                  XU5      u  p*U
(       d  US:X  a  U $ [        S5      e[        X5      n US:X  aU  U R                  R                  (       a  SnOWU R                  R                  (       a  S	nO9[        R                  " U 5      n S	nO US
;  a  [	        SR                  U5      5      e[        XX%US9n U R                   H  nUS:  d  M  [	        SU-  5      e   US	:X  a2  U R                  R                  (       d  [        R                  " U 5      n O7US:X  a1  U R                  R                  (       d  [        R                   " U 5      n [#        U R                  XS   U5      n[%        XXSU
XU	US9	n U $ )Nr   rF   r   r   r4   r   Ar   r   r   zUnsupported order: {}r    r   r?   r   )rn   r+   ro   rr   rq   rp   )r`   r(   r   r   r<   r   r&   r   r   rK   r   rL   ascontiguousarrayr   r0   r"   asfortranarrayr   r   )r   r*   r+   rn   rm   r   r!   rr   ro   rq   r   rs   rp   s                r   _fftnr   I  s   a&&BCC|33 2489 : 	: (DDH677q%A|77EWW!!E&&q)AE	j	 077>?? 	A$%8AWWq5CaGI I 
 |AGG00""1%	#agg22" "!''1"ozJH1[*3$	&A Hr   c                   SSK Jn  UR                  5       nUb  Uc  UnO[        S5      e[	        X5R
                  5      (       a  [        $ [	        X5R                  5      (       d3  U R                  S:X  d#  [        R                  R                  5       (       d  [        $ U R                  R                  (       a  US:w  a  [        $ [        U R                  XU5      u  px[!        U5      S:  a  [#        XR                  5      (       a~  [$        R&                  R(                  R*                  (       aO  SUS   :X  a:  [!        U5      U R                  :w  a!  U R                  R,                  (       a  [        $ US:X  a  [        $ [        $ [        $ )Nr   r2   r@   r   r4   r   )r5   r3   rS   rT   r`   r   r   rC   r&   r   _enable_nd_planningr[   r   rK   r   r   r   r   r(   rN   rO   rP   rL   )	r   r*   r+   rr   r   r3   rt   r   r   s	            r   _default_fft_funcr   |  s'   &&(I<D  5 6 6 $%%
T<<
(
(
&&A+V77;;== 	ww
e 3$QVVQjANA
;! 4[&& I I 99##[^#K(8AFF(B,, U" Kr   c                   ^ [         R                  " U R                  R                  S5      mUb  [	        U5      S:X  a  U4S j$ S $ )N      ?r   c                $   > U R                  TSS9$ )NF)rM   )r   )x
real_dtypes    r   <lambda> _compat_caster.<locals>.<lambda>  s    *59r   c                    U $ r   r   )r   s    r   r   r     s    Qr   )r   result_typerealr   r   )r   r+   r   s     @r   _compat_casterr     s7    c2JCIN99r   c                @    SSK Jn  [        X4U4X4R                  5      $ )a  Compute the one-dimensional FFT.

Args:
    a (cupy.ndarray): Array to be transform.
    n (None or int): Length of the transformed axis of the output. If ``n``
        is not given, the length of the input along the axis specified by
        ``axis`` is used.
    axis (int): Axis over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``n`` and type
        will convert to complex if the input is other.

.. seealso:: :func:`numpy.fft.fft`
r   r2   r5   r3   r   rl   r   rs   r-   rn   r3   s        r   rh   rh          (  4$$(;(;<<r   c                @    SSK Jn  [        X4U4X4R                  5      $ )a  Compute the one-dimensional inverse FFT.

Args:
    a (cupy.ndarray): Array to be transform.
    n (None or int): Length of the transformed axis of the output. If ``n``
        is not given, the length of the input along the axis specified by
        ``axis`` is used.
    axis (int): Axis over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``n`` and type
        will convert to complex if the input is other.

.. seealso:: :func:`numpy.fft.ifft`
r   r2   )r5   r3   r   ri   r   s        r   ifftr     r   r   c                N    SSK Jn  [        XU5      nU" XX#UR                  5      $ )a  Compute the two-dimensional FFT.

Args:
    a (cupy.ndarray): Array to be transform.
    s (None or tuple of ints): Shape of the transformed axes of the
        output. If ``s`` is not given, the lengths of the input along the
        axes specified by ``axes`` are used.
    axes (tuple of ints): Axes over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``s`` and type
        will convert to complex if the input is other.

.. seealso:: :func:`numpy.fft.fft2`
r   r2   r5   r3   r   rl   r   r*   r+   rn   r3   funcs         r   fft2r     (    (  Q4(Dd%"5"566r   c                N    SSK Jn  [        XU5      nU" XX#UR                  5      $ )a  Compute the two-dimensional inverse FFT.

Args:
    a (cupy.ndarray): Array to be transform.
    s (None or tuple of ints): Shape of the transformed axes of the
        output. If ``s`` is not given, the lengths of the input along the
        axes specified by ``axes`` are used.
    axes (tuple of ints): Axes over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``s`` and type
        will convert to complex if the input is other.

.. seealso:: :func:`numpy.fft.ifft2`
r   r2   r5   r3   r   ri   r   s         r   ifft2r     r   r   c                N    SSK Jn  [        XU5      nU" XX#UR                  5      $ )a  Compute the N-dimensional FFT.

Args:
    a (cupy.ndarray): Array to be transform.
    s (None or tuple of ints): Shape of the transformed axes of the
        output. If ``s`` is not given, the lengths of the input along the
        axes specified by ``axes`` are used.
    axes (tuple of ints): Axes over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``s`` and type
        will convert to complex if the input is other.

.. seealso:: :func:`numpy.fft.fftn`
r   r2   r   r   s         r   fftnr     r   r   c                N    SSK Jn  [        XU5      nU" XX#UR                  5      $ )a  Compute the N-dimensional inverse FFT.

Args:
    a (cupy.ndarray): Array to be transform.
    s (None or tuple of ints): Shape of the transformed axes of the
        output. If ``s`` is not given, the lengths of the input along the
        axes specified by ``axes`` are used.
    axes (tuple of ints): Axes over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``s`` and type
        will convert to complex if the input is other.

.. seealso:: :func:`numpy.fft.ifftn`
r   r2   r   r   s         r   ifftnr   (  r   r   c                B    SSK Jn  [        X4U4X4R                  S5      $ )a  Compute the one-dimensional FFT for real input.

Args:
    a (cupy.ndarray): Array to be transform.
    n (None or int): Number of points along transformation axis in the
        input to use. If ``n`` is not given, the length of the input along
        the axis specified by ``axis`` is used.
    axis (int): Axis over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``n`` and type
        will convert to complex if the input is other. The length of the
        transformed axis is ``n//2+1``.

.. seealso:: :func:`numpy.fft.rfft`
r   r2   r   r   r   s        r   rfftr   B  s"    *  4$$(;(;UCCr   c           
     f    SSK Jn  [        X45      nU" [        X4U4X4R                  S5      5      $ )a  Compute the one-dimensional inverse FFT for real input.

Args:
    a (cupy.ndarray): Array to be transform.
    n (None or int): Length of the transformed axis of the output. For
        ``n`` output points, ``n//2+1`` input points are necessary. If
        ``n`` is not given, it is determined from the length of the input
        along the axis specified by ``axis``.
    axis (int): Axis over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``n`` and type
        will convert to complex if the input is other. If ``n`` is not
        given, the length of the transformed axis is`2*(m-1)` where `m`
        is the length of the transformed axis of the input.

.. seealso:: :func:`numpy.fft.irfft`
r   r2   r   )r5   r3   r   r   ri   )r   rs   r-   rn   r3   casters         r   irfftr   \  s3    .  Aw'F$q$/B/BEJKKr   c                N    SSK Jn  [        XUSS9nU" XX#UR                  S5      $ )a  Compute the two-dimensional FFT for real input.

Args:
    a (cupy.ndarray): Array to be transform.
    s (None or tuple of ints): Shape to use from the input. If ``s`` is not
        given, the lengths of the input along the axes specified by
        ``axes`` are used.
    axes (tuple of ints): Axes over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``s`` and type
        will convert to complex if the input is other. The length of the
        last axis transformed will be ``s[-1]//2+1``.

.. seealso:: :func:`numpy.fft.rfft2`
r   r2   r   r   r   r   s         r   rfft2r   y  ,    *  Q4E:Dd%"5"5u==r   c           
     p    SSK Jn  [        X5      n[        XUSS9nU" U" XX#UR                  S5      5      $ )a  Compute the two-dimensional inverse FFT for real input.

Args:
    a (cupy.ndarray): Array to be transform.
    s (None or tuple of ints): Shape of the output. If ``s`` is not given,
        they are determined from the lengths of the input along the axes
        specified by ``axes``.
    axes (tuple of ints): Axes over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``s`` and type
        will convert to complex if the input is other. If ``s`` is not
        given, the length of final transformed axis of output will be
        `2*(m-1)` where `m` is the length of the final transformed axis of
        the input.

.. seealso:: :func:`numpy.fft.irfft2`
r   r2   r   r   r5   r3   r   r   ri   r   r*   r+   rn   r3   r   r   s          r   irfft2r     ;    .  A$FQ4E:D$qT)<)<eDEEr   c                N    SSK Jn  [        XUSS9nU" XX#UR                  S5      $ )a  Compute the N-dimensional FFT for real input.

Args:
    a (cupy.ndarray): Array to be transform.
    s (None or tuple of ints): Shape to use from the input. If ``s`` is not
        given, the lengths of the input along the axes specified by
        ``axes`` are used.
    axes (tuple of ints): Axes over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``s`` and type
        will convert to complex if the input is other. The length of the
        last axis transformed will be ``s[-1]//2+1``.

.. seealso:: :func:`numpy.fft.rfftn`
r   r2   r   r   r   r   s         r   rfftnr     r   r   c                H    Ub  US   b  US   $  U S   $ Ub  XS      $ U S   $ )Nr   r   )r"   r*   r+   s      r   _size_last_transform_axisr     sI    }R5R5L  9 
	"X9r   c           
     p    SSK Jn  [        X5      n[        XUSS9nU" U" XX#UR                  S5      5      $ )a  Compute the N-dimensional inverse FFT for real input.

Args:
    a (cupy.ndarray): Array to be transform.
    s (None or tuple of ints): Shape of the output. If ``s`` is not given,
        they are determined from the lengths of the input along the axes
        specified by ``axes``.
    axes (tuple of ints): Axes over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``s`` and type
        will convert to complex if the input is other. If ``s`` is not
        given, the length of final transformed axis of output will be
        ``2*(m-1)`` where `m` is the length of the final transformed axis
        of the input.

.. seealso:: :func:`numpy.fft.irfftn`
r   r2   r   r   r   r   s          r   irfftnr     r   r   c                V    U S;   a  Sn U $ U S:X  a  Sn U $ U S:w  a  [        SU -  5      eU $ )N)NrF   rH   rF   rG   zCInvalid norm value %s; should be "backward", "ortho", or "forward".)r<   )rn   s    r   _swap_directionr     sU    !! K 
	 K 
 2489 : 	:Kr   c                J    [        U R                  5       X[        U5      5      $ )a  Compute the FFT of a signal that has Hermitian symmetry.

Args:
    a (cupy.ndarray): Array to be transform.
    n (None or int): Length of the transformed axis of the output. For
        ``n`` output points, ``n//2+1`` input points are necessary. If
        ``n`` is not given, it is determined from the length of the input
        along the axis specified by ``axis``.
    axis (int): Axis over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``n`` and type
        will convert to complex if the input is other. If ``n`` is not
        given, the length of the transformed axis is ``2*(m-1)`` where `m`
        is the length of the transformed axis of the input.

.. seealso:: :func:`numpy.fft.hfft`
)r   conjr   r   rs   r-   rn   s       r   hfftr    s    . 1OD$9::r   c                J    [        XU[        U5      5      R                  5       $ )a  Compute the FFT of a signal that has Hermitian symmetry.

Args:
    a (cupy.ndarray): Array to be transform.
    n (None or int): Number of points along transformation axis in the
        input to use. If ``n`` is not given, the length of the input along
        the axis specified by ``axis`` is used.
    axis (int): Axis over which to compute the FFT.
    norm (``"backward"``, ``"ortho"``, or ``"forward"``): Optional keyword
        to specify the normalization mode. Default is ``None``, which is
        an alias of ``"backward"``.

Returns:
    cupy.ndarray:
        The transformed array which shape is specified by ``n`` and type
        will convert to complex if the input is other. The length of the
        transformed axis is ``n//2+1``.

.. seealso:: :func:`numpy.fft.ihfft`
)r   r   r   r   s       r   ihfftr    s!    * dOD127799r   c           	         [         R                  " [         R                  " SU S-
  S-  S-   [        R                  S9[         R                  " U S-  * S[        R                  S945      X-  -  $ )zReturn the FFT sample frequencies.

Args:
    n (int): Window length.
    d (scalar): Sample spacing.

Returns:
    cupy.ndarray: Array of length ``n`` containing the sample frequencies.

.. seealso:: :func:`numpy.fft.fftfreq`
r   r   r   r   )r(   hstackaranger   r   rs   r   s     r   fftfreqr	  1  sb     ;;AA!|a'7rzzJa1fIq

CE FIJP Pr   c                `    [         R                  " SU S-  S-   [        R                  S9X-  -  $ )a   Return the FFT sample frequencies for real input.

Args:
    n (int): Window length.
    d (scalar): Sample spacing.

Returns:
    cupy.ndarray:
        Array of length ``n//2+1`` containing the sample frequencies.

.. seealso:: :func:`numpy.fft.rfftfreq`
r   r   r   r  )r(   r  r   r   r  s     r   rfftfreqr  A  s*     ;;q!q&1*BJJ715AAr   c                   [         R                  " U 5      n Uc  [        [        U R                  5      5      nO[        U[        5      (       a  U4n[         R                  " X Vs/ s H  o R                  U   S-  PM     snU5      $ s  snf )a3  Shift the zero-frequency component to the center of the spectrum.

Args:
    x (cupy.ndarray): Input array.
    axes (int or tuple of ints): Axes over which to shift. Default is
        ``None``, which shifts all axes.

Returns:
    cupy.ndarray: The shifted array.

.. seealso:: :func:`numpy.fft.fftshift`
r   	r(   asarrayr#   r   r&   r`   introllr"   r   r+   r-   s      r   fftshiftr  Q  sl     	QA|E!&&M"	D#		w99Q=!+=tDD=s   %B
c                   [         R                  " U 5      n Uc  [        [        U R                  5      5      nO[        U[        5      (       a  U4n[         R                  " X Vs/ s H  o R                  U   S-  * PM     snU5      $ s  snf )a  The inverse of :meth:`fftshift`.

Args:
    x (cupy.ndarray): Input array.
    axes (int or tuple of ints): Axes over which to shift. Default is
        ``None``, which shifts all axes.

Returns:
    cupy.ndarray: The shifted array.

.. seealso:: :func:`numpy.fft.ifftshift`
r   r  r  s      r   	ifftshiftr  f  so     	QA|E!&&M"	D#		w99Q4@44774=A-.4@$GG@s   %B	
)r   )NNNr   )r4   FN)NNr4   )Nr   NT)r4   r   NFN)NNNr4   )Nr   N)N)r   N)r   )6
__future__r   	functoolsrj   numpyr   r(   cupy.fftr   cupy.fft._cacher   reducer   _coreinternalprodr   _utilmemoizer   r   r0   r=   r{   r~   r   r   r   r   r   r   r   r   r   rh   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r  r  r  r   r   r   <module>r!     s>   "      * 



     .( -1AH EJ*Z!H; HLjZ
 .2Up JN!%0f$N=0=074747474D4L:>6F<>6F<;4:0P B E*Hr   