Ë
     \;j3  ã                   óx   — d Z ddlZddlmZ ddlmZ dd„Zdd„Zdd„Z	dd„Z
d	„ Zd
„ Zd„ Zdd„Zd„ Zdd„Zdd„Zy)aÔ  Function of unitary fourier transform (uft) and utilities

This module implements the unitary fourier transform, also known as
the ortho-normal transform. It is especially useful for convolution
[1], as it respects the Parseval equality. The value of the null
frequency is equal to

.. math::  \frac{1}{\sqrt{n}} \sum_i x_i

so the Fourier transform has the same energy as the original image
(see ``image_quad_norm`` function). The transform is applied from the
last axis for performance (assuming a C-order array input).

References
----------
.. [1] B. R. Hunt "A matrix theory proof of the discrete convolution
       theorem", IEEE Trans. on Audio and Electroacoustics,
       vol. au-19, no. 4, pp. 285-288, dec. 1971

é    Né   )Ú_supported_float_typec                 óh   — |€| j                   }t        j                  | t        | d«      d¬«      }|S )aI  N-dimensional unitary Fourier transform.

    Parameters
    ----------
    inarray : ndarray
        The array to transform.
    dim : int, optional
        The last axis along which to compute the transform. All
        axes by default.

    Returns
    -------
    outarray : ndarray (same shape than inarray)
        The unitary N-D Fourier transform of ``inarray``.

    Examples
    --------
    >>> input = np.ones((3, 3, 3))
    >>> output = ufftn(input)
    >>> np.allclose(np.sum(input) / np.sqrt(input.size), output[0, 0, 0])
    True
    >>> output.shape
    (3, 3, 3)
    r   Úortho©ÚaxesÚnorm)ÚndimÚfftÚfftnÚrange©ÚinarrayÚdimÚoutarrays      ú`G:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\skimage/restoration/uft.pyÚufftnr      s1   € ð2 €{Ø�l‰lˆÜ�x‰x˜¤e¨S¨D°!£n¸7ÔC€HØ€Oó    c                 óh   — |€| j                   }t        j                  | t        | d«      d¬«      }|S )aj  N-dimensional unitary inverse Fourier transform.

    Parameters
    ----------
    inarray : ndarray
        The array to transform.
    dim : int, optional
        The last axis along which to compute the transform. All
        axes by default.

    Returns
    -------
    outarray : ndarray
        The unitary inverse nD Fourier transform of ``inarray``. Has the same shape as
        ``inarray``.

    Examples
    --------
    >>> input = np.ones((3, 3, 3))
    >>> output = uifftn(input)
    >>> np.allclose(np.sum(input) / np.sqrt(input.size), output[0, 0, 0])
    True
    >>> output.shape
    (3, 3, 3)
    r   r   r   )r
   r   Úifftnr   r   s      r   Úuifftnr   ;   s1   € ð4 €{Ø�l‰lˆÜ�y‰y˜¤u¨c¨T°1£~¸GÔD€HØ€Or   c                 óh   — |€| j                   }t        j                  | t        | d«      d¬«      }|S )a�  N-dimensional real unitary Fourier transform.

    This transform considers the Hermitian property of the transform on
    real-valued input.

    Parameters
    ----------
    inarray : ndarray, shape (M[, ...], P)
        The array to transform.
    dim : int, optional
        The last axis along which to compute the transform. All
        axes by default.

    Returns
    -------
    outarray : ndarray, shape (M[, ...], P / 2 + 1)
        The unitary N-D real Fourier transform of ``inarray``.

    Notes
    -----
    The ``urfft`` functions assume an input array of real
    values. Consequently, the output has a Hermitian property and
    redundant values are not computed or returned.

    Examples
    --------
    >>> input = np.ones((5, 5, 5))
    >>> output = urfftn(input)
    >>> np.allclose(np.sum(input) / np.sqrt(input.size), output[0, 0, 0])
    True
    >>> output.shape
    (5, 5, 3)
    r   r   r   )r
   r   Úrfftnr   r   s      r   Úurfftnr   [   s2   € ðD €{Ø�l‰lˆÜ�y‰y˜¤u¨c¨T°1£~¸GÔD€HØ€Or   c                 ój   — |€| j                   }t        j                  | |t        | d«      d¬«      }|S )aQ  N-dimensional inverse real unitary Fourier transform.

    This transform considers the Hermitian property of the transform
    from complex to real input.

    Parameters
    ----------
    inarray : ndarray
        The array to transform.
    dim : int, optional
        The last axis along which to compute the transform. All
        axes by default.
    shape : tuple of int, optional
        The shape of the output. The shape of ``rfft`` is ambiguous in
        case of odd-valued input shape. In this case, this parameter
        should be provided. See ``np.fft.irfftn``.

    Returns
    -------
    outarray : ndarray
        The unitary N-D inverse real Fourier transform of ``inarray``.

    Notes
    -----
    The ``uirfft`` function assumes that the output array is
    real-valued. Consequently, the input is assumed to have a Hermitian
    property and redundant values are implicit.

    Examples
    --------
    >>> input = np.ones((5, 5, 5))
    >>> output = uirfftn(urfftn(input), shape=input.shape)
    >>> np.allclose(input, output)
    True
    >>> output.shape
    (5, 5, 5)
    r   r   r   )r
   r   Úirfftnr   )r   r   Úshaper   s       r   Úuirfftnr   ƒ   s4   € ðL €{Ø�l‰lˆÜ�z‰z˜' 5¬u°c°T¸1«~ÀGÔL€HØ€Or   c                 ó   — t        | d«      S )ap  2-dimensional unitary Fourier transform.

    Compute the Fourier transform on the last 2 axes.

    Parameters
    ----------
    inarray : ndarray
        The array to transform.

    Returns
    -------
    outarray : ndarray (same shape as inarray)
        The unitary 2-D Fourier transform of ``inarray``.

    See Also
    --------
    uifft2, ufftn, urfftn

    Examples
    --------
    >>> input = np.ones((10, 128, 128))
    >>> output = ufft2(input)
    >>> np.allclose(np.sum(input[1, ...]) / np.sqrt(input[1, ...].size),
    ...             output[1, 0, 0])
    True
    >>> output.shape
    (10, 128, 128)
    r   )r   ©r   s    r   Úufft2r!   ¯   s   € ô: �˜!ÓÐr   c                 ó   — t        | d«      S )a‹  2-dimensional inverse unitary Fourier transform.

    Compute the inverse Fourier transform on the last 2 axes.

    Parameters
    ----------
    inarray : ndarray
        The array to transform.

    Returns
    -------
    outarray : ndarray (same shape as inarray)
        The unitary 2-D inverse Fourier transform of ``inarray``.

    See Also
    --------
    uifft2, uifftn, uirfftn

    Examples
    --------
    >>> input = np.ones((10, 128, 128))
    >>> output = uifft2(input)
    >>> np.allclose(np.sum(input[1, ...]) / np.sqrt(input[1, ...].size),
    ...             output[0, 0, 0])
    True
    >>> output.shape
    (10, 128, 128)
    r   )r   r    s    r   Úuifft2r#   Ï   s   € ô: �'˜1ÓÐr   c                 ó   — t        | d«      S )a  2-dimensional real unitary Fourier transform

    Compute the real Fourier transform on the last 2 axes. This
    transform considers the Hermitian property of the transform from
    complex to real-valued input.

    Parameters
    ----------
    inarray : ndarray, shape (M[, ...], P)
        The array to transform.

    Returns
    -------
    outarray : ndarray, shape (M[, ...], 2 * (P - 1))
        The unitary 2-D real Fourier transform of ``inarray``.

    See Also
    --------
    ufft2, ufftn, urfftn

    Examples
    --------
    >>> input = np.ones((10, 128, 128))
    >>> output = urfft2(input)
    >>> np.allclose(np.sum(input[1,...]) / np.sqrt(input[1,...].size),
    ...             output[1, 0, 0])
    True
    >>> output.shape
    (10, 128, 65)
    r   )r   r    s    r   Úurfft2r%   ï   s   € ô> �'˜1ÓÐr   c                 ó   — t        | d|¬«      S )aÕ  2-dimensional inverse real unitary Fourier transform.

    Compute the real inverse Fourier transform on the last 2 axes.
    This transform considers the Hermitian property of the transform
    from complex to real-valued input.

    Parameters
    ----------
    inarray : ndarray, shape (M[, ...], P)
        The array to transform.
    shape : tuple of int, optional
        The shape of the output. The shape of ``rfft`` is ambiguous in
        case of odd-valued input shape. In this case, this parameter
        should be provided. See ``np.fft.irfftn``.

    Returns
    -------
    outarray : ndarray, shape (M[, ...], 2 * (P - 1))
        The unitary 2-D inverse real Fourier transform of ``inarray``.

    See Also
    --------
    urfft2, uifftn, uirfftn

    Examples
    --------
    >>> input = np.ones((10, 128, 128))
    >>> output = uirfftn(urfftn(input), shape=input.shape)
    >>> np.allclose(input, output)
    True
    >>> output.shape
    (10, 128, 128)
    r   )r   )r   )r   r   s     r   Úuirfft2r'     s   € ôD �7˜A UÔ+Ð+r   c                 ó°  — | j                   d   | j                   d   k7  rvdt        j                  t        j                  t        j                  | «      dz  d¬«      d¬«      z  t        j                  t        j                  | d   «      dz  d¬«      z
  S t        j                  t        j                  t        j                  | «      dz  d¬«      d¬«      S )aE  Return the quadratic norm of images in Fourier space.

    This function detects whether the input image satisfies the
    Hermitian property.

    Parameters
    ----------
    inarray : ndarray
        Input image. The image data should reside in the final two
        axes.

    Returns
    -------
    norm : float
        The quadratic norm of ``inarray``.

    Examples
    --------
    >>> input = np.ones((5, 5))
    >>> image_quad_norm(ufft2(input)) == np.sum(np.abs(input)**2)
    True
    >>> image_quad_norm(ufft2(input)) == image_quad_norm(urfft2(input))
    True
    éÿÿÿÿéþÿÿÿr   )Úaxis).r   )r   ÚnpÚsumÚabsr    s    r   Úimage_quad_normr/   6  s¡   € ð4 ‡}�}�RÑ˜GŸM™M¨"Ñ-Ò-Ø”2—6‘6œ"Ÿ&™&¤§¡¨£°AÑ!5¸BÔ?ÀbÔIÑIÌBÏFÉFÜ�F‰F�7˜6‘?Ó# qÑ(¨rôM
ñ 
ð 	
ô �v‰v”b—f‘fœRŸV™V G›_°Ñ1¸Ô;À"ÔEÐEr   c                 óŒ  — |s| j                   }t        | j                  «      }t        j                  ||¬«      }| |t        | j                  D �cg c]  }t        d|«      ‘Œ c}«      <   t        | j                  «      D ]P  \  }}|| j                   |z
  k\  sŒt        j                  |t        t        j                  |dz  «      «       |¬«      }ŒR |rt        j                  nt        j                  }	 |	|t        | d«      ¬«      }
t        j                   |t        j"                  «      }|
j%                  |d¬«      S c c}w )a˜  Compute the transfer function of an impulse response (IR).

    This function makes the necessary correct zero-padding, zero
    convention, correct fft2, etc... to compute the transfer function
    of IR. To use with unitary Fourier transform for the signal (ufftn
    or equivalent).

    Parameters
    ----------
    imp_resp : ndarray
        The impulse responses.
    shape : tuple of int
        A tuple of integer corresponding to the target shape of the
        transfer function.
    dim : int, optional
        The last axis along which to compute the transform. All
        axes by default.
    is_real : bool, optional
       If True (default), imp_resp is supposed real and the Hermitian property
       is used with rfftn Fourier transform.

    Returns
    -------
    y : complex ndarray
       The transfer function of shape ``shape``.

    See Also
    --------
    ufftn, uifftn, urfftn, uirfftn

    Examples
    --------
    >>> np.all(np.array([[4, 0], [0, 0]]) == ir2tf(np.ones((2, 2)), (2, 2)))
    True
    >>> ir2tf(np.ones((2, 2)), (512, 512)).shape == (512, 257)
    True
    >>> ir2tf(np.ones((2, 2)), (512, 512), is_real=False).shape == (512, 512)
    True

    Notes
    -----
    The input array can be composed of multiple-dimensional IR with
    an arbitrary number of IR. The individual IR must be accessed
    through the first axes. The last ``dim`` axes contain the space
    definition.
    )Údtyper   r   )Úshiftr+   )r   F)Úcopy)r
   r   r1   r,   ÚzerosÚtupler   ÚsliceÚ	enumerateÚrollÚintÚfloorr   r   r   r   Úpromote_typesÚ	complex64Úastype)Úimp_respr   r   Úis_realÚirpadded_dtypeÚirpaddedÚsr+   Ú	axis_sizeÚfuncÚoutÚ
cplx_dtypes               r   Úir2tfrG   X  s   € ñ^ Ø�m‰mˆä*¨8¯>©>Ó:€NÜ�x‰x˜ ^Ô4€HØ=E€HŒU¨¯ªÓ8© A”E˜!˜Q•K¨Ñ8Ó9Ñ:ô % X§^¡^Ö4‰ˆˆiØ�8—=‘= 3Ñ&Ó&Ü—w‘w˜x´´B·H±H¸YÈ¹]Ó4KÓ0LÐ/LÐSWÔX‰Hð 5ñ  Œ3�9Š9¤S§X¡X€DÙ
ˆxœu c T¨1›~Ô
/€Cô ×!Ñ! .´"·,±,Ó?€JØ�:‰:�j uˆ:Ó-Ð-ùò 9s   ÁEc                 ó²  — t        j                  dg| z  «      }t        | «      D ]†  }t        t	        dd«      g|z  t	        d«      gz   t	        dd«      g| |z
  dz
  z  z   «      }t        j
                  g d¢«      j                  t        | «      D �cg c]  }||k(  rdnd‘Œ c}«      ||<   Œˆ d| z  |t	        dd«      f| z  <   t        |||¬«      |fS c c}w )	a5  Return the transfer function of the Laplacian.

    Laplacian is the second order difference, on row and column.

    Parameters
    ----------
    ndim : int
        The dimension of the Laplacian.
    shape : tuple
        The support on which to compute the transfer function.
    is_real : bool, optional
       If True (default), imp_resp is assumed to be real-valued and
       the Hermitian property is used with rfftn Fourier transform
       to return the transfer function.

    Returns
    -------
    tf : array_like, complex
        The transfer function.
    impr : array_like, real
        The Laplacian.

    Examples
    --------
    >>> tf, ir = laplacian(2, (32, 32))
    >>> np.all(ir == np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]]))
    True
    >>> np.all(tf == ir2tf(ir, (32, 32)))
    True
    é   é   r   N)ç      ð¿g        rK   r)   g       @)r?   )r,   r4   r   r5   r6   ÚarrayÚreshaperG   )r
   r   r?   Úimprr   ÚidxÚis          r   Ú	laplacianrQ   ›  sÝ   € ô> �8‰8�Q�C˜$‘JÓ€DÜ�TŽ{ˆÜÜ�1�a‹[ˆM˜CÑ¤5¨£; -Ñ/´5¸¸A³;°-À4È#Á:ÐPQÁ>Ñ2RÑRó
ˆô —H‘HÒ.Ó/×7Ñ7Ü,1°$¬KÓ8©K q�1˜’8‰R Ñ"¨KÑ8ó
ˆˆSŠ	ð	 ð #&¨¡*€DŒ%��1‹+ˆ˜$Ñ	ÑÜ��u gÔ.°Ð4Ð4ùò 9s   ÂC
)N)NN)NT)T)Ú__doc__Únumpyr,   Ú	scipy.fftr   Ú_shared.utilsr   r   r   r   r   r!   r#   r%   r'   r/   rG   rQ   © r   r   Ú<module>rW      sW   ðñó* Ý å 1óó>ó@%óP)òXò@ò@óD",òJFóD@.ôF(5r   