
    `iL                         d dl mZ d dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZ d dlmZ ddZdd
ZddZddZddZddZddZddZddZdS )    )prodN)config)_convert_fft_type_default_fft_func_fft_get_cufft_plan_nd_get_fftn_out_size_output_dtype)get_plan_cacheC2Cc                 ,   ddl m} | j        j        rd}n| j        j        rd}nt          d          t          |t                    r|f}t          |t                    r|f}|1|/t          |          t          |          k    rt          d          |I|| j	        nt          |          }t          d t          | d          D                       }|d	k    rd}ntt          |          }|d	k    rJ|d         }|| j	        k    s|| j	         k     r*d
                    || j	                  }t          |          n|dk    rt          d          |}	t          | j                  }|	7t          |	|          D ]&\  }
}|
||d         k    r|dk    r|
dz  d	z   }
|
||<   't          |          }t!          | j        |          }t%          ||          }|d	k    r!|dk    r| j        j        rt          d          |d	k    rZt&          j        j        j        r|dk    rt/          d          t1          ||	|d         |          }t3          |||||d          }n4|dk    r	||         }nt1          ||	||          }t5          |          ||         z  }t6          j        sdnt6          j        }||||f}t7          j                    }|=|j        }|j         }||j!        |j"        |dn|j#        j$        |dn|j#        j$        fz  }tK                      }|&                    |          }||}na||'                    ||||          }nE|rtQ          d          |)                    d|dd         f          }|*                    |           |S )a   Generate a CUDA FFT plan for transforming up to three axes.

    Args:
        a (cupy.ndarray): Array to be transform, assumed to be either C- or
            F- contiguous.
        shape (None or tuple of ints): Shape of the transformed axes of the
            output. If ``shape`` is not given, the lengths of the input along
            the axes specified by ``axes`` are used.
        axes (None or int or tuple of int):  The axes of the array to
            transform. If `None`, it is assumed that all axes are transformed.

            Currently, for performing N-D transform these must be a set of up
            to three adjacent axes, and must include either the first or the
            last axis of the array.
        value_type (str): The FFT type to perform. Acceptable values are:

            * 'C2C': complex-to-complex transform (default)
            * 'R2C': real-to-complex transform
            * 'C2R': complex-to-real transform

    Returns:
        a cuFFT plan for either 1D transform (``cupy.cuda.cufft.Plan1d``) or
        N-D transform (``cupy.cuda.cufft.PlanNd``).

    .. note::
        The returned plan can not only be passed as one of the arguments of
        the functions in ``cupyx.scipy.fftpack``, but also be used as a
        context manager for both ``cupy.fft`` and ``cupyx.scipy.fftpack``
        functions:

        .. code-block:: python

            x = cupy.random.random(16).reshape(4, 4).astype(complex)
            plan = cupyx.scipy.fftpack.get_fft_plan(x)
            with plan:
                y = cupy.fft.fftn(x)
                # alternatively:
                y = cupyx.scipy.fftpack.fftn(x)  # no explicit plan is given!
            # alternatively:
            y = cupyx.scipy.fftpack.fftn(x, plan=plan)  # pass plan explicitly

        In the first case, no cuFFT plan will be generated automatically,
        even if ``cupy.fft.config.enable_nd_planning = True`` is set.

    .. note::
        If this function is called under the context of
        :func:`~cupy.fft.config.set_cufft_callbacks`, the generated plan will
        have callbacks enabled.

    .. warning::
        This API is a deviation from SciPy's, is currently experimental, and
        may be changed in the future version.
    r   cufftCFz Input array a must be contiguousNz&Shape and axes have different lengths.c              3      K   | ]}|V  d S )N ).0is     l/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/cupyx/scipy/fftpack/_fft.py	<genexpr>zget_fft_plan.<locals>.<genexpr>V   s"      --1Q------       zAThe chosen axis ({0}) exceeds the number of dimensions of a ({1})   z"Only up to three axes is supportedC2R   r   z2C2R/R2C PlanNd for F-order arrays is not supportedz,hipFFT's C2R PlanNd is buggy and unsupportedF)axesorderout_sizeto_cache)devicesz/multi-GPU cuFFT callbacks are not yet supportedPlan1d)+	cupy.cudar   flagsc_contiguousf_contiguous
ValueError
isinstanceintlenndimtuplerangeformatlistshapezipr
   dtyper   cupycudaruntimeis_hipRuntimeErrorr	   r   r   r   use_multi_gpus_devicesget_current_callback_managercb_load_aux_arrcb_store_aux_arrcb_loadcb_storedataptrr   getr#   NotImplementedErrorcreate_planset_callbacks)ar2   r   
value_typer   r   naxis1Derrtransformed_shapesaxis	out_dtypefft_typer    planbatchr"   keysmgrload_aux	store_auxcachecached_plans                           r   get_fft_planrY      s'   l   	w =	
	 =;<<<% $ w 0c%jjCII6M6MABBB |mAFFU--qb!-----66FII66!WF6QVG#3#3..4fVQV.D.D  oo% $4 UUABBB MME$,d33 	  	 GAt}48##
e(;(;Q
Ad%LLE agz22I J77H1uuu$$)=$MNNN 	1uu9# 	O
e(;(;MNNN%$d2h
< < "8$eh  
 V}HH)(&*> >HUuV},$3H$$(E73133? *H,IS[#,"*QQ0A#+QQ1CE ED   iioo"DD[<<(E7<KKDD  ;) +: ; ; ;??Hd3B3i#899Dd###Kr   r   Fc           	      H    ddl m} t          | |f|fd|j        ||          S )ac  Compute the one-dimensional FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        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.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.Plan1d` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axis``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, axis)

            Note that `plan` is defaulted to None, meaning CuPy will use an
            auto-generated plan behind the scene.

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

    .. note::
       The argument `plan` is currently experimental and the interface may be
       changed in the future version.

    .. seealso:: :func:`scipy.fftpack.fft`
    r   r   Noverwrite_xrQ   )r%   r   r   CUFFT_FORWARDxrI   rN   r\   rQ   r   s         r   fftr`      C    :  A4$$(;'d4 4 4 4r   c           	      H    ddl m} t          | |f|fd|j        ||          S )al  Compute the one-dimensional inverse FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        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.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.Plan1d` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axis``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, axis)

            Note that `plan` is defaulted to None, meaning CuPy will use an
            auto-generated plan behind the scene.

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

    .. note::
       The argument `plan` is currently experimental and the interface may be
       changed in the future version.

    .. seealso:: :func:`scipy.fftpack.ifft`
    r   r   Nr[   )r%   r   r   CUFFT_INVERSEr^   s         r   ifftrd      ra   r   r   c           	      `    ddl m} t          | |||          } || ||d|j        ||          S )a  Compute the two-dimensional FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        shape (None or tuple of ints): Shape of the transformed axes of the
            output. If ``shape`` 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.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, axes)

            Note that `plan` is defaulted to None, meaning CuPy will either
            use an auto-generated plan behind the scene if cupy.fft.config.
            enable_nd_planning = True, or use no cuFFT plan if it is set to
            False.

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

    .. seealso:: :func:`scipy.fftpack.fft2`

    .. note::
       The argument `plan` is currently experimental and the interface may be
       changed in the future version.
    r   r   Nr[   r%   r   r   r]   r_   r2   r   r\   rQ   r   funcs          r   fft2rk      T    >  QtT22D45$e&9'd4 4 4 4r   c           	      `    ddl m} t          | |||          } || ||d|j        ||          S )a  Compute the two-dimensional inverse FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        shape (None or tuple of ints): Shape of the transformed axes of the
            output. If ``shape`` 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.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, axes)

            Note that `plan` is defaulted to None, meaning CuPy will either
            use an auto-generated plan behind the scene if cupy.fft.config.
            enable_nd_planning = True, or use no cuFFT plan if it is set to
            False.

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

    .. seealso:: :func:`scipy.fftpack.ifft2`

    .. note::
       The argument `plan` is currently experimental and the interface may be
       changed in the future version.
    r   r   Nr[   r%   r   r   rc   ri   s          r   ifft2ro     rl   r   c           	      `    ddl m} t          | |||          } || ||d|j        ||          S )a  Compute the N-dimensional FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        shape (None or tuple of ints): Shape of the transformed axes of the
            output. If ``shape`` 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.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, axes)

            Note that `plan` is defaulted to None, meaning CuPy will either
            use an auto-generated plan behind the scene if cupy.fft.config.
            enable_nd_planning = True, or use no cuFFT plan if it is set to
            False.

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

    .. seealso:: :func:`scipy.fftpack.fftn`

    .. note::
       The argument `plan` is currently experimental and the interface may be
       changed in the future version.
    r   r   Nr[   rh   ri   s          r   fftnrq   :  rl   r   c           	      `    ddl m} t          | |||          } || ||d|j        ||          S )a  Compute the N-dimensional inverse FFT.

    Args:
        x (cupy.ndarray): Array to be transformed.
        shape (None or tuple of ints): Shape of the transformed axes of the
            output. If ``shape`` 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.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.PlanNd` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axes``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(x, axes)

            Note that `plan` is defaulted to None, meaning CuPy will either
            use an auto-generated plan behind the scene if cupy.fft.config.
            enable_nd_planning = True, or use no cuFFT plan if it is set to
            False.

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

    .. seealso:: :func:`scipy.fftpack.ifftn`

    .. note::
       The argument `plan` is currently experimental and the interface may be
       changed in the future version.
    r   r   Nr[   rn   ri   s          r   ifftnrs   `  rl   r   c           
      >   ddl m} || j        |         }t          | j                  }|||<   t	          | |f|fd|j        d||          }t          j        ||j        j	                  }t          d          g| j        z  }	t          d          g| j        z  }
t          d          |	|<   t          d          |
|<   |t          |
                   j        |t          |	          <   t          ddd          |	|<   t          dd          |
|<   |t          |
                   j        |t          |	          <   t          ddd          |	|<   t          d||j        |         z
  dz             |
|<   |t          |
                   j        |t          |	          <   |S )aq  Compute the one-dimensional FFT for real input.

    The returned real array contains

    .. code-block:: python

        [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2))]  # if n is even
        [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2)),Im(y(n/2))]  # if n is odd

    Args:
        x (cupy.ndarray): Array to be transformed.
        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.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.
        plan (:class:`cupy.cuda.cufft.Plan1d` or ``None``): a cuFFT plan for
            transforming ``x`` over ``axis``, which can be obtained using::

                plan = cupyx.scipy.fftpack.get_fft_plan(
                    x, axes, value_type='R2C')

            Note that `plan` is defaulted to None, meaning CuPy will either
            use an auto-generated plan behind the scene if cupy.fft.config.
            enable_nd_planning = True, or use no cuFFT plan if it is set to
            False.

    Returns:
        cupy.ndarray:
            The transformed array.

    .. seealso:: :func:`scipy.fftpack.rfft`

    .. note::
       The argument `plan` is currently experimental and the interface may be
       changed in the future version.
    r   r   NR2Cr[   r   r   )r%   r   r2   r1   r   r]   r5   emptyrealr4   slicer-   r.   imag)r_   rI   rN   r\   rQ   r   r2   fzslice_zslice_fs              r   rfftr~     s   L  yGDMMMEE$KQtgtU%8%$4	1 	1 	1A
5!&,''AT{{maf$GT{{maf$G!HHGDM!HHGDM%..).AeGnn!T1%%GDM!TNNGDM%..).AeGnn!T1%%GDM!Q.233GDM%..).AeGnnHr   c           	         ddl m} || j        |         }t          || j        |                   }t	          | j                  }|dz  dz   ||<   | j        t          j        t          j        fv r!t          j	        |t          j
                  }n t          j	        |t          j                  }t          d          g| j        z  }t          d          g| j        z  }	t          d          ||<   t          d          |	|<   | t          |                   |t          |	                   _        t          d|d          ||<   t          d|dz  dz             |	|<   | t          |                   |t          |	                   _        t          d|d          ||<   t          d|dz   dz            |	|<   | t          |                   |t          |	                   _        t#          ||f|fd|j        d|          S )	a  Compute the one-dimensional inverse FFT for real input.

    Args:
        x (cupy.ndarray): Array to be transformed.
        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.
        overwrite_x (bool): If True, the contents of ``x`` can be destroyed.

    Returns:
        cupy.ndarray:
            The transformed array.

    .. seealso:: :func:`scipy.fftpack.irfft`

    .. note::
       This function does not support a precomputed `plan`. If you need this
       capability, please consider using :func:`cupy.fft.irfft` or :func:`
       cupyx.scipy.fft.irfft`.
    r   r   Nr   r   )r4   r   )r\   )r%   r   r2   minr1   r4   r5   float16float32zeros	complex64
complex128rx   r-   r.   rw   ry   r   rc   )
r_   rI   rN   r\   r   mr2   r{   slice_xr|   s
             r   irfftr     s   ,  yGDMAqwt}AMMEq&1*E$Kw4<...JuDN333JuDO444T{{maf$GT{{maf$G!HHGDM!HHGDMuW~~.AeGnn!QNNGDM!Q!VaZ((GDMuW~~.AeGnn!QNNGDM!a!e\**GDMuW~~.AeGnnA4$$(;U') ) ) )r   )NNr   )Nr   FN)Nre   FN)NNFN)Nr   F)numpyr   r5   cupy.fftr   cupy.fft._fftr   r   r   r   r	   r
   cupy.fft._cacher   rY   r`   rd   rk   ro   rq   rs   r~   r   r   r   r   <module>r      sd               * * * * * * * * * * * * * * * * + * * * * *\ \ \ \~4 4 4 4D4 4 4 4D#4 #4 #4 #4L#4 #4 #4 #4L#4 #4 #4 #4L#4 #4 #4 #4L@ @ @ @F3) 3) 3) 3) 3) 3)r   