ó
 ‰\c           @  s°   d  Z  d d l m Z m Z d d l Z d Z d d „ Z d d „ Z	 d d „ Z
 d d d „ Z d	 „  Z d
 „  Z d „  Z d d „ Z d „  Z d e d „ Z e d „ Z d S(   sÍ  Function of unitary fourier transform 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::  rac{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

iÿÿÿÿ(   t   divisiont   print_functionNs,   fft, Fourier Transform, orthonormal, unitaryc         C  s\   | d k r |  j } n  t j j |  d t | d ƒ ƒ} | t j t j |  j | ƒ ƒ S(   sI  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)
    t   axesi    N(	   t   Nonet   ndimt   npt   fftt   fftnt   ranget   sqrtt   prodt   shape(   t   inarrayt   dimt   outarray(    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   ufftn    s    "c         C  s\   | d k r |  j } n  t j j |  d t | d ƒ ƒ} | t j t j |  j | ƒ ƒ S(   sZ  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 (same shape than inarray)
        The unitary inverse N-D Fourier transform of ``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   i    N(	   R   R   R   R   t   ifftnR   R	   R
   R   (   R   R   R   (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   uifftn?   s    "c         C  s\   | d k r |  j } n  t j j |  d t | d ƒ ƒ} | t j t j |  j | ƒ ƒ S(   s’  N-dimensional real unitary Fourier transform.

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

    Parameters
    ----------
    inarray : ndarray, shape (M, N, ..., 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, N, ..., 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   i    N(	   R   R   R   R   t   rfftnR   R	   R
   R   (   R   R   R   (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   urfftn^   s    ""c         C  s_   | d k r |  j } n  t j j |  | d t | d ƒ ƒ} | t j t j | j | ƒ ƒ S(   sQ  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   i    N(	   R   R   R   R   t   irfftnR   R	   R
   R   (   R   R   R   R   (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   uirfftn†   s    &%c         C  s   t  |  d ƒ S(   sp  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)
    i   (   R   (   R   (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   ufft2²   s    c         C  s   t  |  d ƒ S(   s‹  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)
    i   (   R   (   R   (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   uifft2Ò   s    c         C  s   t  |  d ƒ S(   s  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, N, ..., P)
        The array to transform.

    Returns
    -------
    outarray : ndarray, shape (M, N, ..., 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)
    i   (   R   (   R   (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   urfft2ò   s    c         C  s   t  |  d d | ƒS(   sõ  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, N, ..., P)
        The array to transform.

    Returns
    -------
    outarray : ndarray, shape (M, N, ..., 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)
    i   R   (   R   (   R   R   (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   uirfft2  s    c         C  s¤   |  j  d |  j  d k rq d t j t j t j |  ƒ d d d ƒd d ƒt j t j |  d ƒ d d d ƒSt j t j t j |  ƒ d d d ƒd d ƒSd S(	   sE  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
    iÿÿÿÿiþÿÿÿi   t   axis.i    N(   .i    (   R   R   t   sumt   abs(   R   (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   image_quad_norm5  s    2%c         C  sÿ   | s |  j  } n  t j | ƒ } |  | t g  |  j D] } t d | ƒ ^ q4 ƒ <xb t |  j ƒ D]Q \ } } | |  j  | k r` t j | d t t j	 | d ƒ ƒ d | ƒ} q` q` W| rÛ t j
 j | d t | d ƒ ƒSt j
 j | d t | d ƒ ƒSd S(   s   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 : boolean (optional, default True)
       If True, 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.
    i    t   shifti   R   R   N(   R   R   t   zerost   tupleR   t   slicet	   enumeratet   rollt   intt   floorR   R   R   R   (   t   imp_respR   R   t   is_realt   irpaddedt   sR   t	   axis_size(    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   ir2tfV  s    // c         C  sù   t  j d g |  ƒ } x© t |  ƒ D]› } t t d d ƒ g | t d	 ƒ g t d d ƒ g |  | d ƒ } t  j d d d g ƒ j g  t |  ƒ D] } | | k r« d n d ^ q“ ƒ | | <q# Wd |  | t d d ƒ f |  <t | | d | ƒ| f S(
   sC  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, shape
        The support on which to compute the transfer function
    is_real : boolean (optional, default True)
       If True, 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
    i   i   i   g      ð¿g        iÿÿÿÿg       @R'   N(	   R   R   R   R    R!   R   t   arrayt   reshapeR+   (   R   R   R'   t   imprR   t   idxt   i(    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt	   laplacian—  s     "	9(   t   __doc__t
   __future__R    R   t   numpyR   t   __keywords__R   R   R   R   R   R   R   R   R   R   t   TrueR+   R1   (    (    (    s6   lib/python2.7/site-packages/skimage/restoration/uft.pyt   <module>   s   (,	 	 	"!	!A