U
    /e0                     @   s  d dl Z d dlmZ d dlZzd dlZd dlZW n ek
rH   dZY nX d dlm	Z	 d dlm
Z d dlmZ d dlmZmZ dZdZd	d
 Zdd Zdd Zdd Zdd ZeeeeeedZd%ddZeejjZeejjZeejjZeejjZeejjZeejj Z eejj!Z!eejj"Z"eejj#Z#eejj$Z$eejj%Z%eejj&Z&eejj'Z'eejj(Z(dd Z)eejd&ddZ*eejd'ddZ+d(dd Z,eejd)d!d"Z-eejd*d#d$Z.dS )+    N)Sequence)asarray)concatenate)arange)derived_fromskip_doctestzDask array only supports taking an FFT along an axis that 
has a single chunk. An FFT operation was tried on axis %s 
which has chunks %s. To change the array's chunks use dask.Array.rechunk.z
    Wrapping of %s

    The axis along which the FFT is applied must have only one chunk. To change
    the array's chunking use dask.Array.rechunk.

    The %s docstring follows below:

    c                 C   s<   |dkr| j S t| j }t|D ]\}}|| f||< q |S )z*For computing the output chunks of [i]fft*N)chunkslist	enumerateasaxesr   iaxis r   2/tmp/pip-unpacked-wheel-dbjnr7gq/dask/array/fft.py_fft_out_chunks#   s    
r   c                    sd   |dkr fdd|D }t |}|d d d |d< t  j}t|D ]\}}|| f||< qH|S )z(For computing the output chunks of rfft*Nc                    s   g | ]} j | d  qS r   r   .0r   r   r   r   
<listcomp>0   s     z$_rfft_out_chunks.<locals>.<listcomp>      r	   r   r
   r   r   r   r   _rfft_out_chunks-   s    
r   c                    s\   |dkr. fdd|D }d|d d  |d< t  j}t|D ]\}}|| f||< q@|S )z)For computing the output chunks of irfft*Nc                    s   g | ]} j | d  qS r   r   r   r   r   r   r   <   s     z%_irfft_out_chunks.<locals>.<listcomp>r   r   r   r   r   r   r   r   _irfft_out_chunks9   s    
r   c                 C   sX   t |dkst|d }|d kr8d| j| d d  g}|d }t| j}|f||< |S Nr   r   r   lenAssertionErrorr   r	   )r   r   r   r   nr   r   r   r   _hfft_out_chunksD   s    

r%   c                 C   s   t |dkst|d }|d kr2| j| d g}nt |dksBt|d }t| j}|d dkrn|d d }n|d d }|f||< |S r    r!   )r   r   r   r   r$   r   mr   r   r   _ihfft_out_chunksS   s    

r'   )fftifftrfftirffthfftihfftc                    s  t dk	r2t jjkrtdnt jjkr2tddkr@jztd W n  tk
rr   td Y nX dfdd	}	dr| d fd	d	}t
}j}|jd
 | }jdk	 rtd|f  |_| jj7  _t|j|_||_|S )a|  Wrap 1D, 2D, and ND real and complex FFT functions

    Takes a function that behaves like ``numpy.fft`` functions and
    a specified kind to match it to that are named after the functions
    in the ``numpy.fft`` API.

    Supported kinds include:

        * fft
        * fft2
        * fftn
        * ifft
        * ifft2
        * ifftn
        * rfft
        * rfft2
        * rfftn
        * irfft
        * irfft2
        * irfftn
        * hfft
        * ihfft

    Examples
    --------
    >>> import dask.array.fft as dff
    >>> parallel_fft = dff.fft_wrap(np.fft.fft)
    >>> parallel_ifft = dff.fft_wrap(np.fft.ifft)
    Nz+SciPy's `rfft` doesn't match the NumPy API.z,SciPy's `irfft` doesn't match the NumPy API.Z2nzGiven unknown `kind` %s.c           
         sh  t | } |d krZdr d}qvdrT|d krBtt| j}qXttt|}qvd}ntt|t|k rvtd }|d krtj	| jd | j
d}z||dj
}W n tk
r   |j
}Y nX |D ],}t| j| d	krtt|| j| f qΈ| ||}||f}d
rP|d kr*d n|d }|d kr@d n|d }	|	|f}| jf|||dS )N2)r   r$   )r   zDuplicate axes not allowed.)   )dtype)r   r   r(   r   r1   r   )r   endswithtuplerangendimr"   set
ValueErrornpZonesr1   	TypeErrorr   chunk_error
map_blocks)
r   r   r   Z_dtypesampleZ	each_axisr   argsr   r$   )r1   fft_funckindout_chunk_fnr   r   func   s8    

zfft_wrap.<locals>.funcr(   c                    s0   d }|d k	r|f}d }|d k	r$|f} | ||S )Nr   )r   r$   r   r   r   )_funcr   r   rB      s    .r   )NN)NN)scipyZfftpackr*   r8   r+   __name___out_chunk_fnsrstripKeyErrorr3   inspect	getmodule__doc__fft_preambler   )r?   r@   r1   rB   Zfunc_mod	func_nameZfunc_fullnamer   )rC   r1   r?   r@   rA   r   fft_wrapr   s0    
&

rO   c                 C   s4   |   }|| |d d k  |8  < |||  }|S )Nr   r   )copy)r   r$   drr   r   r   _fftfreq_block   s    rS         ?autoc                 C   s0   t | } t|}t| t|d}|jtt| |dS )Nr2   )r1   r$   rQ   )intfloat_aranger<   rS   r$   rQ   r   rR   r   r   r   fftfreq   s    rZ   c                 C   s6   t | } t|}t| d d t|d}|| |  }|S )Nr   r   r2   )rV   rW   rX   rY   r   r   r   rfftfreq   s
    r[   Fc           	      C   s   |d krt t| j}nt|ts(|f}| }|D ]}|j| }|t|dk d }|jtd g }td |||< t|}|jtd g }t|d ||< t|}t	|| || g|d}t
| j| dkr0||| j| i}q0|S )NFr   )r   r   )r	   r5   r6   
isinstancer   shaperV   slicer4   _concatenater"   r   Zrechunk)	xr   inverseyr   r$   Zn_2lrR   r   r   r   _fftshift_helper  s$    

rd   c                 C   s   t | |ddS )NFr   ra   rd   r`   r   r   r   r   fftshift#  s    rh   c                 C   s   t | |ddS )NTre   rf   rg   r   r   r   	ifftshift(  s    ri   )NN)rT   rU   )rT   rU   )NF)N)N)/rJ   collections.abcr   Znumpyr9   rE   Zscipy.fftpackImportErrorZdask.array.corer   r   r_   Zdask.array.creationr   rX   Z
dask.utilsr   r   r;   rM   r   r   r   r%   r'   rG   rO   r(   Zfft2Zfftnr)   Zifft2Zifftnr*   Zrfft2Zrfftnr+   Zirfft2Zirfftnr,   r-   rS   rZ   r[   rd   rh   ri   r   r   r   r   <module>   sf   



j	

