B
    )²ô`ÁG  ã               @   sâ  d Z ddlmZ ddlmZ ddlmZ ddlZddlmZ	 ddlm
Z ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ dd„ Zdd„ ZdRdd„Zdd„ Zdd„ ZejZejZej Z ej!Z!ej"Z"ej#Z#eej$ddƒZ$edddgde %e$¡ƒ eej&ddƒZ&ed d d!gde %e&¡ƒ eej'd"d#ƒZ'ed$d$d%gde %e'¡ƒ eej(d"d&ƒZ(ed'd'd(gde %e(¡ƒ eej)d)d*ƒZ)ed+d+d,gde %e)¡ƒ eej*d)d-ƒZ*ed.d.d/gde %e*¡ƒ d0d1„ Z+e ,d2¡d3d4„ ƒZ-e ,d5¡d6d7„ ƒZ.e ,d8¡d9d:„ ƒZ/e ,d;¡d<d=„ ƒZ0e ,d>¡d?d@„ ƒZ1e ,dA¡dBdC„ ƒZ2dDdE„ Z3dFdG„ Z4edHƒej%dSdIdJ„ƒƒZ5edKƒej%dTdLdM„ƒƒZ6e ,dN¡e3de&ƒƒ e ,dO¡e4de$ƒƒ e ,dP¡e3d"e(ƒƒ e ,dQ¡e4d"e'ƒƒ dS )UzFast-Fourier Transform ops.é    )Úabsolute_import)Údivision)Úprint_functionN)Údtypes)Úops)Útensor_util)Ú	array_ops)Úgen_spectral_ops)Ú	manip_ops)Úmath_ops)Údispatch)Ú	tf_exportc             C   s@   |   ¡ | d… }| ¡ s.t | ¡| d… S t | ¡ tj¡S )zGInfers the `fft_length` argument for a `rank` RFFT from `input_tensor`.N)	Ú	get_shapeÚis_fully_definedÚ
_array_opsÚshapeÚ_opsÚconvert_to_tensorÚas_listÚ_dtypesÚint32)Úinput_tensorÚfft_rankÚ	fft_shape© r   úS/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow/python/ops/signal/fft_ops.pyÚ_infer_fft_length_for_rfft!   s    r   c             C   sŽ   |   ¡ | d… }| ¡ sZt t | ¡| d… ¡}t dd|d d  ¡|d< t |¡S | ¡ }|r€t	dd|d d  ƒ|d< t
 |tj¡S )zHInfers the `fft_length` argument for a `rank` IRFFT from `input_tensor`.Nr   é   éÿÿÿÿé   )r   r   r   Zunstackr   Ú	_math_opsÚmaximumÚstackr   Úmaxr   r   r   r   )r   r   r   Ú
fft_lengthr   r   r   Ú_infer_fft_length_for_irfft.   s    
r%   Fc             C   s  t  |¡}| jjdk	r0tdd„ | jjD ƒƒr0| S | ¡ rà| jjdk	rà| j|j d… }| ¡ rà|r„|dd…  |jd jd d ¡}dd„ t	|j|jƒD ƒ}td	d„ |D ƒƒrÜd
d
ggt
| jj|j d
ƒ }t | || ¡S | S t | ¡}t | ¡| d… }t d
|| ¡}	t |	g|j¡}|rLt |dd… |dd… d d gd
¡}t d
|| ¡}
t ||
gd
¡}tjt |¡|gdd}t | |¡S )zFPads `input_tensor` to `fft_length` on its inner-most `fft_rank` dims.Nc             s   s   | ]}|j d kV  qdS )r   N)Úvalue)Ú.0Zdimr   r   r   ú	<genexpr>F   s    z&_maybe_pad_for_rfft.<locals>.<genexpr>r   r   r   c             S   s&   g | ]\}}d t |j|j d ƒg‘qS )r   )r#   r&   )r'   Zfft_dimZ	input_dimr   r   r   ú
<listcomp>V   s   z'_maybe_pad_for_rfft.<locals>.<listcomp>c             s   s   | ]\}}|d kV  qdS )r   Nr   )r'   Ú_Úpadr   r   r   r(   Y   s    r   )Zaxis)Ú_tensor_utilZconstant_value_as_shaper   ÚndimsÚanyZdimsr   Zconcatenater&   Úzipr#   r   r+   Úrankr    r!   ÚzerosÚdtypeÚconcatr"   Z
zeros_like)r   r   r$   Ú
is_reverser   Zinput_fft_shapeZpaddingsZouter_paddingsZ
input_rankZ
outer_dimsZfft_paddingsr   r   r   Ú_maybe_pad_for_rfft@   s<    

r5   c                s   d‡ ‡‡fdd„	}ˆj |_ |S )zFWrapper around gen_spectral_ops.rfft* that infers fft_length argument.Nc          	      sØ   t  |ˆ | |g¡¼}t j| tjd} | jtjtjfkrBtd|  ƒ‚| j}|tjkrZtj}n|tjksht	‚tj
}| j ˆ¡ |dkrŽt| ˆƒ}nt  |tj¡}t| ˆ|ƒ} t |¡}|dk	r¾|}ˆ| |||dS Q R X dS )zFWrapper around gen_spectral_ops.rfft* that infers fft_length argument.)Úpreferred_dtypez6RFFT requires tf.float32 or tf.float64 inputs, got: %sN)ZTcomplexÚname)r   Ú
name_scoper   r   Úfloat32r2   Úfloat64Ú
ValueErrorÚ	complex64ÚAssertionErrorÚ
complex128r   Úwith_rank_at_leastr   r   r5   r,   Úconstant_value)r   r$   r7   Ú
real_dtypeÚcomplex_dtypeÚfft_length_static)Údefault_nameÚfft_fnr   r   r   Ú_rffts   s,    


z_rfft_wrapper.<locals>._rfft)NN)Ú__doc__)rE   r   rD   rF   r   )rD   rE   r   r   Ú_rfft_wrapperp   s    rH   c                s   d‡ ‡‡fdd„	}ˆj |_ |S )zGWrapper around gen_spectral_ops.irfft* that infers fft_length argument.Nc          	      s¼   t  |ˆ | |g¡ }t j| tjd} | j ˆ¡ | jtjtjfkrNt	d|  ƒ‚| j}|j
}|dkrnt| ˆƒ}nt  |tj¡}t| ˆ|dd} t |¡}|dk	r¢|}ˆ| |||dS Q R X dS )z/Wrapper irfft* that infers fft_length argument.)r6   z<IRFFT requires tf.complex64 or tf.complex128 inputs, got: %sNT)r4   )ZTrealr7   )r   r8   r   r   r<   r   r?   r2   r>   r;   rA   r%   r   r5   r,   r@   )r   r$   r7   rB   rA   rC   )rD   r   Úifft_fnr   r   Ú_irfft•   s(    

z_irfft_wrapper.<locals>._irfft)NN)rG   )rI   r   rD   rJ   r   )rD   r   rI   r   Ú_irfft_wrapper’   s    rK   r   Úrfftzsignal.rfftzspectral.rfft)Zv1Úirfftzsignal.irfftzspectral.irfftr   Úrfft2dzsignal.rfft2dzspectral.rfft2dÚirfft2dzsignal.irfft2dzspectral.irfft2dé   Úrfft3dzsignal.rfft3dzspectral.rfft3dÚirfft3dzsignal.irfft3dzspectral.irfft3dc             C   s   t  t | ¡| d … ¡S )N)r    Zreduce_prodr   r   )Úgradr0   r   r   r   Ú_fft_size_for_gradÌ   s    rT   ZFFTc             C   s    t  t|dƒ|j¡}t|ƒ| S )Nr   )r    ÚcastrT   r2   Úifft)r*   rS   Úsizer   r   r   Ú	_fft_gradÐ   s    rX   ZIFFTc             C   s0   t  dt  t|dƒ|jj¡ |j¡}t|ƒ| S )Ng      ð?r   )r    rU   rT   r2   rA   Úfft)r*   rS   Úrsizer   r   r   Ú
_ifft_gradÖ   s    r[   ZFFT2Dc             C   s    t  t|dƒ|j¡}t|ƒ| S )Nr   )r    rU   rT   r2   Úifft2d)r*   rS   rW   r   r   r   Ú_fft2d_gradÞ   s    r]   ZIFFT2Dc             C   s0   t  dt  t|dƒ|jj¡ |j¡}t|ƒ| S )Ng      ð?r   )r    rU   rT   r2   rA   Úfft2d)r*   rS   rZ   r   r   r   Ú_ifft2d_gradä   s    r_   ZFFT3Dc             C   s    t  t|dƒ|j¡}t|ƒ| S )NrP   )r    rU   rT   r2   Úifft3d)r*   rS   rW   r   r   r   Ú_fft3d_gradì   s    ra   ZIFFT3Dc             C   s0   t  dt  t|dƒ|jj¡ |j¡}t|ƒ| S )Ng      ð?rP   )r    rU   rT   r2   rA   Úfft3d)r*   rS   rZ   r   r   r   Ú_ifft3d_gradò   s    rc   c                s"   ˆdkst dƒ‚‡ ‡fdd„}|S )z=Returns a gradient function for an RFFT of the provided rank.)r   r   z'Gradient for RFFT3D is not implemented.c          
      s€  | j d }|j‰ ˆ j}t | j d ¡}t d|d d  ˆ ¡}dd„ }‡ fdd„}‡ fd	d
„}|ddd…f }	ˆdkr |ddd…f }
|	||
 ||d ƒ  }n¤ˆdkrD||d ƒ}|||	ƒ}t |t |	¡¡}|}|ddd…f }
t |t |
¡¡}|d }t 	|t 
t t |¡d gtj¡|ggd¡¡||ƒ }||| 7 }t t| j d ˆƒ|¡}ˆ||ƒ}d|| t |¡  dfS )zEA gradient function for RFFT with the provided `rank` and `irfft_fn`.r   r   r   r   c          
   S   s^   t  | t  t  t  |¡d gtj¡t  | ¡gd¡¡}t  |t  t  |¡d d… ddggd¡¡S )Nr   r   éþÿÿÿr   )	r   Zreshaper3   Úonesr0   r   r   r   Útile)ZmatrixÚtÚexpandedr   r   r   Ú_tile_for_broadcasting  s    
z@_rfft_grad_helper.<locals>._grad.<locals>._tile_for_broadcastingc                sZ   t  t  t | ¡d¡| df¡}t  |ddg¡}t dtj t 	|| ˆ ¡ t 	| ˆ ¡ ¡S )z3Computes t_n = exp(sqrt(-1) * pi * n^2 / line_len).r   r   y       €       À)
r   rf   Zexpand_dimsr    ÚrangeZ	transposeÚexpÚnpÚpirU   )ÚlengthÚaÚb)rB   r   r   Ú_mask_matrix  s    z6_rfft_grad_helper.<locals>._grad.<locals>._mask_matrixc                s   t  ddt  | ¡d   ˆ ¡S )zCA sequence of [1+0j, -1+0j, 1+0j, -1+0j, ...] with length `length`.r   r   )r    rU   rj   )rn   )rB   r   r   Ú_ymask   s    z0_rfft_grad_helper.<locals>._grad.<locals>._ymask.Nrd   g      à?)Úinputsr2   rA   r   r   r    rU   ÚmatmulZconjrf   r3   re   r0   r   r   rT   Úreal)ÚoprS   r$   rA   Zinput_shapeZis_evenri   rq   rr   Zy0ZymZextra_termsZ	base_maskZ
tiled_maskZy0_termZym_termZ	inner_dimZ
input_sizeZ	the_irfft)Úirfft_fnr0   )rB   r   Ú_gradÿ   s>    




z _rfft_grad_helper.<locals>._grad)r=   )r0   rw   rx   r   )rw   r0   r   Ú_rfft_grad_helperú   s    Jry   c                s"   ˆ dkst dƒ‚‡ ‡fdd„}|S )z>Returns a gradient function for an IRFFT of the provided rank.)r   r   z(Gradient for IRFFT3D is not implemented.c                sÞ   | j d }t |¡}|dk	r |}|j}|tjkr8tj}n|tjkrHtj}t	 
|d d¡}t | j d ¡d }t dgdt |d | g|¡ t d| g|¡gd¡}t	 t	 t|ˆ ƒ|¡¡}	ˆ||ƒ}
|
t	 |	| |¡ dfS )zEA gradient function for IRFFT with the provided `rank` and `rfft_fn`.r   Nr   r   r   g      ð?g       @)rs   r,   r@   r2   r   r9   r<   r:   r>   r    Úmodr   r   r3   re   Z
reciprocalrU   rT   )rv   rS   r$   rC   rA   rB   Zis_oddZinput_last_dimensionÚmaskrZ   Zthe_rfft)r0   Úrfft_fnr   r   rx   Q  s&    





z!_irfft_grad_helper.<locals>._grad)r=   )r0   r|   rx   r   )r0   r|   r   Ú_irfft_grad_helperL  s     r}   zsignal.fftshiftc          	   C   s²   t  |d¡œ}t  | ¡} |dkr@tt| jjƒƒ}t | ¡d }nXt|t	ƒr^t | ¡| d }n:t 
| ¡}t t |d¡|| |¡}t t | ¡|¡d }t | |||¡S Q R X dS )a+  Shift the zero-frequency component to the center of the spectrum.

  This function swaps half-spaces for all axes listed (defaults to all).
  Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.

  @compatibility(numpy)
  Equivalent to numpy.fft.fftshift.
  https://docs.scipy.org/doc/numpy/reference/generated/numpy.fft.fftshift.html
  @end_compatibility

  For example:

  ```python
  x = tf.signal.fftshift([ 0.,  1.,  2.,  3.,  4., -5., -4., -3., -2., -1.])
  x.numpy() # array([-5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])
  ```

  Args:
    x: `Tensor`, input tensor.
    axes: `int` or shape `tuple`, optional Axes over which to shift.  Default is
      None, which shifts all axes.
    name: An optional name for the operation.

  Returns:
    A `Tensor`, The shifted tensor.
  ÚfftshiftNr   r   )r   r8   r   Útuplerj   r   r-   r   Ú
isinstanceÚintr0   Úwherer    ÚlessÚgatherr
   Úroll)ÚxÚaxesr7   Úshiftr0   r   r   r   r~   t  s    


r~   zsignal.ifftshiftc          	   C   s¸   t  |d¡¢}t  | ¡} |dkrBtt| jjƒƒ}t | ¡d  }n\t|t	ƒrbt | ¡| d  }n<t 
| ¡}t t |d¡|| |¡}t t | ¡|¡d  }t | |||¡S Q R X dS )aÉ  The inverse of fftshift.

  Although identical for even-length x,
  the functions differ by one sample for odd-length x.

  @compatibility(numpy)
  Equivalent to numpy.fft.ifftshift.
  https://docs.scipy.org/doc/numpy/reference/generated/numpy.fft.ifftshift.html
  @end_compatibility

  For example:

  ```python
  x = tf.signal.ifftshift([[ 0.,  1.,  2.],[ 3.,  4., -4.],[-3., -2., -1.]])
  x.numpy() # array([[ 4., -4.,  3.],[-2., -1., -3.],[ 1.,  2.,  0.]])
  ```

  Args:
    x: `Tensor`, input tensor.
    axes: `int` or shape `tuple` Axes over which to calculate. Defaults to None,
      which shifts all axes.
    name: An optional name for the operation.

  Returns:
    A `Tensor`, The shifted tensor.
  Ú	ifftshiftNr   r   )r   r8   r   r   rj   r   r-   r   r€   r   r0   r‚   r    rƒ   r„   r
   r…   )r†   r‡   r7   rˆ   r0   r   r   r   r‰   ¡  s    


r‰   ZRFFTZIRFFTZRFFT2DZIRFFT2D)F)NN)NN)7rG   Ú
__future__r   r   r   Únumpyrl   Ztensorflow.python.frameworkr   r   r   r   r   r,   Ztensorflow.python.opsr   r   r	   r
   r   r    Ztensorflow.python.utilr   Z tensorflow.python.util.tf_exportr   r   r%   r5   rH   rK   rY   rV   r^   r\   rb   r`   rL   Zadd_dispatch_supportrM   rN   rO   rQ   rR   rT   ZRegisterGradientrX   r[   r]   r_   ra   rc   ry   r}   r~   r‰   r   r   r   r   Ú<module>   sz   
0" R(++