
    `iZ                        d dl Z d dlZd dlZd dlZd dlmZ d dlmZ e j	        Z
ej        j        j        Zej                                        d             Zd Zd.dZd Z	 d/d	Zd0d
Z	 	 d1dZd2dZd Z	 d3dZd Z	 d/dZ	 	 d4dZd5dZd6dZd6dZ d7dZ!d7dZ"d/dZ#d/dZ$d6dZ%d6d Z&d7d!Z'd7d"Z(d/d#Z)d$ Z*d/d%Z+d& Z,d6d'Z-d6d(Z.d8d*Z/d8d+Z0d0d,Z1d0d-Z2dS )9    N)config)get_plan_cachec                    |dk    rM| t           j        t           j        fv rt           j        S | t           j        t           j        fvrt           j        S n| t           j        t           j        fv r+t          j        | j                                                  S | t           j        k    rt           j        S | t           j        t           j        fvrt           j        S | S )NR2C)	npfloat16float32	complex64
complex128dtypecharlowerfloat64)r   
value_types     a/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/cupy/fft/_fft.py_output_dtyper      s    URZ,,,<2<777=  8 R\2=1118EJ,,..///bj  :2:rz222:L    c                 p    t          | j        |          }|| j        k    r|                     |          } | S N)r   r   astype)ar   	out_dtypes      r   _convert_dtyper       s6    agz22IAGHHYHr   Cc                 j   ||| j         k    r| S |dk    r(|d          t          |          }|d         dz  dz   |d<   t          ||          D ]\  }}||| j         |         k    rt          | j                   }||         |k    rAt          d           g| j        z  }t          d|          ||<   | t          |                   } yt          d           g| j        z  }t          d||                   ||<   |||<   t          j        || j        j	        |          }	| |	t          |          <   |	} | S )NC2R      r   order)
shapelistzipslicendimtuplecupyzerosr   r   )
r   saxesr   r!   szaxisr"   indexzs
             r   _cook_shaper0   '   s4   yALLe!B%"3GG"
Q"4LL  DNqwt}!4!4MMET{Rt.#ArlldeEllOt.#AuT{33d dJuagl%@@@"#%,,Hr   c                 x   ddl m} |dk    r| t          j        k    r|j        S |dk    r| t          j        k    r|j        S |dk    r| t          j        k    r|j        S |dk    r| t          j        k    r|j	        S |dk    r| t          j
        k    r|j        S |dk    r| t          j        k    r|j        S t          )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4	u		"*!4!4	u		",!6!6	u		"-!7!7	u		"*!4!4	u		"-!7!7r   c	                 B   ddl m}	 t          | j        |          }
|| j        z  | j        dz
  k    r|                     |d          } | j        | j        j        s| 	                                } nct          j        j        j        s|dk    r|s| 	                                } n0t          j        j        j        r|dk    r| 	                                } | j        d         }|dk     rt          d|z            t          j        j        j        r>|dk    r8d| d         _        |d| d	         _        n|d
z  dk    rd| d|d
z  f         _        ||}| j        |z  }|	                                }|||}nt'          d          |t(          j        sd nt(          j        }||
||f}t)          j                    }|=|j        }|j        }||j        |j        |dn|j        j        |dn|j        j        fz  }t=                      }|                    |          }||}n||	                     ||
||          }|||<   n|rtC          d          |"                    d|d d         f          }|#                    |           |||<   ntI          ||	j                   st          d          |
|j%        k    rt          d          ||j&        k    rt          d||j&                  ||j'        k    rt          d          t(          j        |j(        d uk    rt          d          |r	|dk    r| }n.||)                    | |           n|*                    |           }|dk    r|+                    | ||           |j        d         }|
|	j,        k    s|
|	j-        k    r|}|dk    r||	j.        k    r||z  }n4|dk    r|t_          j0        |          z  }n|dk    r||	j1        k    r||z  }|| j        z  | j        dz
  k    r|                    |d          }|S )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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   use_multi_gpus_devicesget_current_callback_managercb_load_aux_arrcb_store_aux_arrcb_loadcb_storedataptrr   getrB   NotImplementedErrorcreate_planset_callbacks
isinstancefft_typenxbatchgpuscheck_output_arrayget_output_arrayfftr7   r:   CUFFT_INVERSEmathsqrtCUFFT_FORWARD)r   	directionr   normr-   overwrite_xout_sizeoutplanr3   rb   nrd   	curr_planrA   keysmgrload_aux	store_auxcachecached_planr,   s                         r   	_exec_fftr{   Q   s    *55Haf}
""JJtR  v!5FFHHI$
eK FFHH			! jE&9&9 FFHH	A1uu?!CE E 	E y +J%$7$7&	AgJOO\Q)*Ac8q= !&FaKE &&((I<DD  5 6 6 6 |$3H$$(E73133? *H,IS[#,"*QQ0A#+QQ1CE ED   iioo"DD[<<(E7<KKDE$KK  ;) +: ; ; ;??Hd3B3i#899Dd###E$KK $-- 	HFGGGt}$$9:::twI%tw0 0 0DJBCCC TYd%:;;NOOO 'zU**	3''''##A&&zzC###	2B5?""h%/&A&Azi5+>>>r		ty}}			yE,???r	af}
""ll4$$Jr   c           
      <    |D ]}t          | |d||||          } | S )Nr4   rr   )r{   )r   rm   rn   r+   ro   rr   r-   s          r   _fft_c2cr~      s6     O OaE4{NNNHr   r4   Fc           	      J   t          | t          j                  st          d          |1|/t	          |          t	          |          k    rt          d          |5|| j        }nt	          |          }d t          | d          D             }nt          |          }|s|dk    r| S t          d          |d}|dvrt          d	|z            t          | |          } t          | |||          } |dk    rt          | |||||
          } n|dk    r6t          | ||||d         |          } t          | |||d d         |          } nSt          | |||d d         |          } t          | j        ||d         |          }	t          | ||||d         ||	          } | S )N(The input array a must be a cupy.ndarray&Shape and axes have different lengths.c                     g | ]}|S  r   ).0is     r   
<listcomp>z_fft.<locals>.<listcomp>   s    ***a***r   r   r4   list index out of rangerE   rE   rF   rG   CInvalid norm value %s, should be "backward", "ortho", or "forward".r}   r   r   )ra   r(   ndarray	TypeErrorlenr<   r&   ranger'   
IndexErrorr   r0   r~   r{   _get_fftn_out_sizer"   )
r   r*   r+   rn   rm   r   ro   rr   dimrp   s
             r   _fftr      s   a&& DBCCC	D,#a&&CII2E2EABBB|9&CCa&&C**5#q>>***T{{ 8H6777| 333 2489 : : 	:q*%%AAq$
++AUQ	4{FFF	u		aJd2hLLQ	4crcK@@Q	4crcK@@%agq$r(JGGaJd2h    Hr   c                     |1|/t          |          t          |          k    rt          d          |A| }nt          |          }t           fdt          | d          D                       }|}nt          |          }|sdS t	          t
          |            k     st	          t          |           dz
  k    rt          d          |dk    r)t          t           fd	|D                                 }nPt           fd
|dd         D                       }|                    |d          z             t          |          }||fS )zwConfigure axes argument for an n-dimensional FFT.

    The axes to be transformed are returned in ascending order.
    Nr   c                     g | ]}|z   S r   r   )r   r   r&   s     r   r   z#_prep_fftn_axes.<locals>.<listcomp>  s    7771a$h777r   r   )r   r   r   z/The specified axes exceed the array dimensions.r4   c                     g | ]}|z  S r   r   r   axr&   s     r   r   z#_prep_fftn_axes.<locals>.<listcomp>  s    'A'A'AbT	'A'A'Ar   c                     g | ]}|z  S r   r   r   s     r   r   z#_prep_fftn_axes.<locals>.<listcomp>   s    !@!@!@"t)!@!@!@r   r   )	r   r<   r'   r   _reduceminmaxsortedappend)r&   r*   r+   r   r   axes_sorteds   `     r   _prep_fftn_axesr     sr    	
D,#a&&CII2E2EABBB|9CCa&&C7777sdA77788T{{ 	63%%d););dQh)F)FNOOO'A'A'A'AD'A'A'A B BCCKK !!@!@!@!@d3B3i!@!@!@AAKtBx$///,,K r   c                      dt                     cxk     odk    nc oBd v p|dz
   v o7t           fdt          t                     dz
            D                       S )Nr      r   c              3   H   K   | ]}|d z            |         z
  d k    V  dS )r   Nr   )r   rs   r   s     r   	<genexpr>z'_nd_plan_is_possible.<locals>.<genexpr>-  sN       : : !Q'+a.8Q> : : : : : :r   )r   allr   )r   r&   s   ` r   _nd_plan_is_possibler   (  s     K  %%%%A%%%% :k!>dQh;%>: : : : :"3{#3#3a#788: : : : :;r   Tc                 X    ddl m} t                     }||j        |j        fv rd}n||j        |j        fv rd}nd}|t          t          |                    }	nt          |d||          \  }
}	t          |	|          st          d          |d	vrt          d
          	  fd|	D             }|dk    r|ddd         }t          |          }||j        |j        fv r|}|}n:t          |          }|||d<   t          |          }||j        |j        fv r|}n|}|}|}|	t          t          |                    k    rd}dx}}dx}}nd|	vrdt          t           |	          }t#           d|                   }|dk    r#t#          |          }t#          |          }d}d}n|dk    rd}d}|}|}nx|dz
  |	vrb|t          |	          z
  }t#           | d                   }|dk    r	d}d}|}|}n8|dk    r"t#          |          }t#          |          }d}d}nt          d          |D ]}|dk     rt          d          |||||||||||	d         |f}t%          j                    }|=|j        }|j        }||j        |j        |dn|j        j        |dn|j        j        fz  }t5                      }|                    |          }||}nO| |j        | }|r|||<   n;|                    d|dd         f          }|                    |           |r|||<   |S )aF  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.r   Fzorder must be 'C' or 'F'c                      g | ]
}|         S r   r   )r   dr"   s     r   r   z&_get_cufft_plan_nd.<locals>.<listcomp>w  s    000!U1X000r   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.PlanNd)r5   r3   r   r6   r9   r8   r;   r'   r   r   r   r<   r#   r7   r:   r   r   _prodr   rV   rW   rX   rY   rZ   r[   r\   r   r]   r   r_   r`   )r"   rb   r+   r!   rp   to_cacher3   r&   r   fft_axes_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   1  sB   .  u::DEOU_555

	eou7	7	7


|t%%%dd1;= = =8  $// ! ! ! 	! J7888& 1000x000M||%ddd+-((MEOU_555&'m,,!)N2~..999+OO,OGG5t%%%%'' H"311L5,/00F||m,,n--#  Qhx''!CMM1N5.!1!1233F||  #m,,n--!" " "
  @ @q55>@ @ @  Wg7GUfeXb\8=D 
-
/
/C
 &(	cl&HM,='Y^-?A 	A E))D//K	u|T" 	E$K$ss)455$ 	E$KKr   c                     |dk    r"||d         d| |         dz
  z  }n |d         }n|dk    r| |         dz  dz   }nd }|S )Nr   r   r   r   r   r   )in_shaper*   	last_axisr   rp   s        r   r   r     sf    UI1R5=HY/!34HHuHH	u		I&!+a/Or   c	                     ddl m}	 t           j        |          }
 j        j        rd}n j        j        rd}nt          d          |dk    r|s                                  n0t          j
        j        j        r|dk    r                                  |	                                }||}|t           j        |
|||          }n6t!          ||	j                  st          d	          ||j        k    r(t          d
                    |j        |                     j        j        r fd|D             }|dk    r||d<   n fd|d d d         D             }t)          |          }||j        k    r.t          d                    |j        | j                            |
|j        k    rt          d          |dk    r:|d         |j        k    rt          d          ||j        k    rt          d          |r	|dk    r }n0||                     |          }n|                     |           |j        dk    r|                     ||           |
|	j        |	j        fv r n|t=          fd|D                       }|dk    r||	j        k    r||z  }n4|dk    r|tA          j!        |          z  }n|dk    r||	j"        k    r||z  }|S )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: {})c                 *    g | ]}j         |         S r   r"   r   r   r   s     r   r   z_exec_fftn.<locals>.<listcomp>  s    999bagbk999r   r   c                 *    g | ]}j         |         S r   r   r   s     r   r   z_exec_fftn.<locals>.<listcomp>  s    ???bagbk???r   zYThe cuFFT plan and a.shape do not match: plan.shape = {}, expected_shape={}, a.shape = {}rD   z"The last axis for R2C/C2R mismatchz-The size along the last R2C/C2R axis mismatchr    c                 *    g | ]}j         |         S r   r   )r   r   arrs     r   r   z_exec_fftn.<locals>.<listcomp>4  s    ---"	"---r   rE   rF   rG   )#r5   r3   r=   r   rJ   rK   f_contiguousr<   rL   r(   rM   rN   rO   rR   r   r"   ra   r   r!   formatr'   rb   r   	last_sizerg   rf   rQ   rh   r7   r:   r   ri   rj   rk   rl   )r   rm   r   rn   r+   ro   rr   rq   rp   r3   rb   r!   rt   expected_shaper,   r   s   `              @r   
_exec_fftnr     s|    *55Hw 1	
	 1/000U; FFHH			! jE&9&9 FFHH &&((I|!!'8$e+35 5 5 $-- 	HFGGGDJJ$fTZ779 9 97 	@9999D999NU""%-r" @???D2J???N~..TZ''CCI6JD9 D9: : : t}$$9:::Bx4>)) !EFFF4>))  ", - - -  (zU**	##AU#333'''
x1}}C### EOU_===!!3C	-------	.	.Bzi5+>>>r		ty}}			yE,???r	Jr   Ac
                 D   t          | t          j                  st          d          |d}|dvrt	          d|z            t          | j        |||          \  }}
|
s|dk    r| S t          d          t          | |          } |dk    r5| j	        j
        rd}nL| j	        j        rd	}n=t          j        |           } d	}n&|d
vr"t	          d                    |                    t          | ||||          } | j        D ]}|dk     rt	          d|z            |d	k    r!| j	        j        st          j        |           } n&|dk    r | j	        j
        st          j        |           } t#          | j        ||
d         |          }t%          | ||||
|||	|	  	        } | S )Nr   rE   r   r   r4   r   r   r   r   r   zUnsupported order: {}r    r   r?   r   )rn   r+   ro   rr   rq   rp   )ra   r(   r   r   r<   r   r&   r   r   rJ   r   rK   ascontiguousarrayr   r0   r"   asfortranarrayr   r   )r   r*   r+   rn   rm   r   r!   rr   ro   rq   r   rs   rp   s                r   _fftnr   ?  s   a&& DBCCC|333 2489 : : 	: (4DDD+ 8H6777q*%%A||7 	EEW! 	EE&q))AEE	j	 	 077>>??? 	Aq$
%888AW I Iq55CaGI I I  ||AG0|"1%%	#ag2"" "!'1k"ozJJH1i$[*3$	& 	& 	&A Hr   c                    ddl m} |                                }|||}nt          d          t	          ||j                  rt          S t	          ||j                  s| j        dk    st          j
        st          S | j        j        r|dk    rt          S t          | j        |||          \  }}t          |          dk    rvt!          || j                  rat"          j        j        j        rDd|d         k    r+t          |          | j        k    r| j        j        rt          S |dk    rt          S t          S t          S )Nr   r2   r@   r   r4   r   )r5   r3   rR   rS   ra   r   r   rB   r&   r   enable_nd_planningr   rJ   r   r   r   r   r(   rM   rN   rO   rK   )	r   r*   r+   rr   r   r3   rt   r   r   s	            r   _default_fft_funcr   r  sV   &&((I<DD  5 6 6 6 $%% 
T5<
(
( 
&A++V6+ 	w 
e 3 3$QVQjAANA{
;! 4[!& I I 9# 	[^##K(8(8AF(B(B, )C U"" Kr   r   c                 B    ddl m} t          | |f|f||j                  S )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     3    (  A4$$(;<<<r   c                 B    ddl m} t          | |f|f||j                  S )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   r   c                 X    ddl m} t          | ||          } || ||||j                  S )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     B    (  Q4((D41dD%"5666r   c                 X    ddl m} t          | ||          } || ||||j                  S )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                 X    ddl m} t          | ||          } || ||||j                  S )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                 X    ddl m} t          | ||          } || ||||j                  S )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                 D    ddl m} t          | |f|f||j        d          S )aM  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   1  s5    *  A4$$(;UCCCr   c                 D    ddl m} t          | |f|f||j        d          S )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   r   r   s        r   irfftr   K  s5    .  A4$$(;UCCCr   c                 ^    ddl m} t          | ||d          } || ||||j        d          S )aO  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   g  I    *  Q4E:::D41dD%"5u===r   c                 ^    ddl m} t          | ||d          } || ||||j        d          S )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   r   r   s         r   irfft2r     I    .  Q4E:::D41dD%"5u===r   c                 ^    ddl m} t          | ||d          } || ||||j        d          S )aM  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                 X    ||d         |d         S n|| |d                  S | d         S )Nr   r   )r"   r*   r+   s      r   _size_last_transform_axisr     s=    }R5R5L 		T"X9r   c                 ^    ddl m} t          | ||d          } || ||||j        d          S )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    | dv rd} n!| dk    rd} n| dk    rt          d| z            | S )N)NrE   rG   rE   rF   zCInvalid norm value %s; should be "backward", "ortho", or "forward".)r<   )rn   s    r   _swap_directionr     sT    !!!				 2489 : : 	:Kr   c                 d    t          |                                 ||t          |                    S )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(    . 1dOD$9$9:::r   c                 d    t          | ||t          |                                                    S )aW  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,    * 1dOD112277999r         ?c                     t          j        t          j        d| dz
  dz  dz   t          j                  t          j        | dz   dt          j                  f          | |z  z  S )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	    sl     ;AA!|a'7rzJJJa1fIq
CCCE F FIJQP Pr   c                 \    t          j        d| dz  dz   t          j                  | |z  z  S )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  -  s.     ;q!q&1*BJ7771q5AAr   c                      t          j                    |"t          t           j                            }nt          |t                    r|f}t          j          fd|D             |          S )aS  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`
    Nc                 0    g | ]}j         |         d z  S r   r   r   r-   xs     r   r   zfftshift.<locals>.<listcomp>O  s$    ===!+===r   r(   asarrayr#   r   r&   ra   introllr  r+   s   ` r   fftshiftr  =  sp     	QA|E!&MM""	D#		 w9Q=======tDDDr   c                      t          j                    |"t          t           j                            }nt          |t                    r|f}t          j          fd|D             |          S )a3  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`
    Nc                 2    g | ]}j         |         d z   S r  r   r  s     r   r   zifftshift.<locals>.<listcomp>d  s'    @@@4174=A-.@@@r   r  r  s   ` r   	ifftshiftr  R  sp     	QA|E!&MM""	D#		 w9Q@@@@4@@@$GGGr   )r   )NNNr   )r4   FN)NNr4   )Nr   NT)r4   r   NFN)NNNr4   )Nr   N)Nr   N)r  )3	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   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$     sf                   * * * * * * 

          .  ( -1} } } }@    EJ* * * *Z! ! ! !H; ; ; HLf f f fR
 
 
 .2U U U Up JN!%0 0 0 0f$ $ $ $N= = = =0= = = =07 7 7 747 7 7 747 7 7 747 7 7 74D D D D4D D D D8> > > >6> > > >:> > > >6  > > > >:  ; ; ; ;4: : : :0P P P P B B B B E E E E*H H H H H Hr   