a
    ߙfb                  
   @   s  d dl Z d dlmZ d dlZd dlZd dlmZmZm	Z	 d dl
mZmZ d dlmZ d dlmZ dZee eeZg dZd	Zd
dgZd
dgZdZee eeddZdZee eeddZd)ddZd*ddZdd Z G dd dZ!G dd dZ"ej#$dedd Z%ej#$de eeeeedd Z&ej#$de eeeeedd  Z'ej#$d!d"d
id#d
id$d
igd%d& Z(d'd( Z)dS )+    N)nullcontext)assert_allcloseassert_array_equalassert_array_almost_equal_nulp)convolve_fftconvolve)AstropyUserWarning)units)z>f4z<f4>f8z<f8)Nfillwrap)interpolater   TFboundarynan_treatmentnormalize_kerneldealiasTFr   r   r   preserve_nanc                 C   s"   | d u rt jtdd}nt }|S )NzWThe convolve_fft version of boundary=None is equivalent to the convolve boundary='fill'match)pytestwarnsr   r   )r   ctx r   Jlib/python3.9/site-packages/astropy/convolution/tests/test_convolve_fft.pyexpected_boundary_warning0   s    r   c                 C   s"   |r| dkrt t}nt }|S )Nr   )r   raises
ValueErrorr   )r   r   r   r   r   r   expected_dealias_error<   s    r    c                 C   s"   t | |dt|   dd dS )a  Assert arrays are close to within expected floating point rounding.

    Check that the result is correct at the precision expected for 64 bit
    numbers, taking account that the tolerance has to reflect that all powers
    in the FFTs enter our values.
    
           )ZatolZrtolN)r   npZspacingmax)xyr   r   r   assert_floatcloseG   s    	r'   c                	   @   sf  e Zd Zejeedd Zejeedd Z	ejeedd Z
ejeedd Zejeed	d
 Zejeedd ZejdejdgddejdejdgddfZejg dddejg dddfZeeeeddeeZejed edd Zejeedd Zdd Zdd Zdd Z dd Z!d d! Z"ejeed"d# Z#d$S )%TestConvolve1Dc              
   C   s   t jg dddtj }t jg ddd}t|d` t||d4 t||||||d}|j|jkshJ W d   n1 s|0    Y  W d   n1 s0    Y  dS )	zW
        Test that convolve_fft works correctly when input array is a Quantity
              ?      @      @      @r,         @       @float64dtype皙?g333333?r4   r   r   r   r   N)r#   arrayuZphr   r    r   Zunitselfr   r   r   r   r%   r&   zr   r   r   test_quantityU   s    zTestConvolve1D.test_quantityc              
   C   s   t jg ddd}t jdgdd}t|dZ t||d. t||||||d}t|| W d   n1 sn0    Y  W d   n1 s0    Y  dS )	zV
        Test that a unit kernel with a single element returns the same array
        r*          @      @r0   r1   r*   r5   r6   r   Nr#   r7   r   r    r   r'   r9   r   r   r   test_unity_1_noneg   s    z TestConvolve1D.test_unity_1_nonec              
   C   s   t jg ddd}t jg ddd}t|dZ t||d. t||||||d}t|| W d   n1 sp0    Y  W d   n1 s0    Y  dS )	z|
        Test that a unit kernel with three elements returns the same array
        (except when boundary is None).
        r=   r0   r1   r"   r*   r"   r5   r6   r   Nr@   r9   r   r   r   test_unity_3z   s    zTestConvolve1D.test_unity_3c              
   C   sz  t jg ddd}t jg ddd}t|d4 t||d t||||||d}|||f}t jg dddt jg d	ddt jg d
ddt jg dddd}	|	d |	d |	d |	d d}
t|
 D ]}|
| |
|d d|d f< qt|
 D ]*}|d dkr|
| |
d|d |d f< qt||
|  W d   n1 sL0    Y  W d   n1 sl0    Y  dS )z
        Test that the different modes are producing the correct results using
        a uniform kernel with three elements
        r*   r"   r?   r0   r1   r*   r*   r*   r5   r6   r   r*   r+   r?   gUUUUUU?UUUUUU?r*   r+   r+   r+   rH   rH   rH   )sum_fill_zerosaverage_fill_zerossum_wrapaverage_wraprL   rN   rK   rM   ))r   r   T)r   r   T)r   r   F)r   r   Fr   r      N   )r#   r7   r   r    r   listkeysr'   )r:   r   r   r   r   r%   r&   r;   
answer_keyanswer_dictZresult_dictkr   r   r   test_uniform_3   s4    
	zTestConvolve1D.test_uniform_3c           
      C   sT  t jg ddd}t jg ddd}t|d t||d t||||||d}t jg dddt jg dddt jg dddt jg d	ddt jg d
ddt jg dddt jg d	ddt jg dddd}|rd}	nd}	|dkr|	d7 }	n|	d7 }	t|||	  W d   n1 s&0    Y  W d   n1 sF0    Y  dS )z
        Test that the different modes are producing the correct results using
        a uniform, non-unity kernel with three elements
        rD   r0   r1   )      ?rW   rW   r5   r6   r   rW   r>         ?rG   )r>   r>   r>   rJ   rW   rH   rY   )sum	sum_zerossum_nozerosaveragerM   rN   average_zerosaverage_nozerosr^   r[   r   _wrap_zerosNr@   )
r:   r   r   r   r   r%   r&   r;   rT   rS   r   r   r   test_halfity_3   s2    
zTestConvolve1D.test_halfity_3c              	   C   s   t jdt jdgdd}t jg ddd}t|d$ t||||||d}W d   n1 s\0    Y  |r|t |d	 s|J t |}t|g d
 dS )
        Test that a unit kernel with three elements returns the same array
        (except when boundary is None). This version includes a NaN value in
        the original array.
        r*   r?   r0   r1   rB   r5   r   NrP   rD   r#   r7   nanr   r   isnan
nan_to_numr'   r:   r   r   r   r   r%   r&   r;   r   r   r   test_unity_3_withnan   s    	$
z#TestConvolve1D.test_unity_3_withnanr*   r?   r0   r1   rD   r   )invaloutvalc           
   	   C   s   |}t jdgdd}t|d$ t||||||d}	W d   n1 sH0    Y  |rht |	d shJ t |	}	t|	| dS )rd   r*   r0   r1   r5   r   NrP   )r#   r7   r   r   rg   rh   r'   )
r:   r   r   r   r   rk   rl   r%   r&   r;   r   r   r   test_unity_1_withnan  s    
$
z#TestConvolve1D.test_unity_1_withnanc                 C   s  t jdt jdgdd}t jg ddd}t|d$ t||||||d}W d   n1 s\0    Y  |r|t |d	 s|J t jg d
ddt jg d
ddt jg d
ddt jg d
ddt jg dddt jg dddt jg dddt jg dddt jg dddt jg dddt jg dddt jg dddd}t| D ](}	d|	v rN||	 d d ||	d < qN|rd}
nd}
|dkr|
d7 }
n|
d7 }
|dkr|
d7 }
t |}||
 | }|dkr|d	 rd|rdnd |d	< t	|| | dS )z
        Test that the different modes are producing the correct results using
        a uniform kernel with three elements. This version includes a NaN
        value in the original array.
        r*   r?   r0   r1   rE   r5   r   NrP   rF   r=   rI   rJ   )rO   rO   rO   rZ   rG   rX   )r[   r]   r\   Zsum_nozeros_interpnanr^   rM   rN   average_wrap_interpnanr`   Zaverage_nozeros_interpnanr_   Zaverage_zeros_interpnanr[   r>   
_interpnanr^   r   ra   rb   r   r      )
r#   r7   rf   r   r   rg   rQ   rR   isfiniter'   )r:   r   r   r   r   r%   r&   r;   rT   keyrS   posnsZanswerr   r   r   test_uniform_3_withnan!  sN    	$




z%TestConvolve1D.test_uniform_3_withnanc                 C   s^   t jdt jdgdd}t g d}t jj|g dd}t||dd	t jd
}t|g d d S )Nr*   r?   r0   r1   rP   rP   rP   r   rP   r   maskr   r   r   r   
fill_valuerP   rO      )r#   r7   rf   mamasked_arrayr   r'   )r:   r7   kernelr~   resultr   r   r   test_nan_interpolatee  s    z#TestConvolve1D.test_nan_interpolatec                 C   sH   t jdt jdgdd}t g d}t||dddd}t|g d	 d S )
Nr*   r?   r0   r1   ru   r   r   ry   rG   r#   r7   rf   r   r'   r:   r7   r   r   r   r   r   test_nan_fillr  s    zTestConvolve1D.test_nan_fillc                 C   sH   t jdt jdgdd}t g d}t||dddd}t|g d	 d S )
Nr*   r?   r0   r1   ru   r   rP   ry   )r*   竪?r   r   r   r   r   r   test_nan_fill_two  s    z TestConvolve1D.test_nan_fill_twoc                 C   s   t jg ddd}t g d}t jj|g dd}t||ddd	}t|g d
 t||ddd	}t|| t jg ddd}t g d}t jj|g dd}t||ddd	}t|g d t||ddd	}t|| dS )zF
        Check whether convolve_fft works with masked arrays.
        r=   r0   r1   ru   rv   rw   r   r"   )r   rz   )rW   rO   rY   )rP   rO   rP   N)r#   r7   r}   r~   r   r'   r   )r:   r7   r   r~   r   Zconvolve_resultZmasked_kernelr   r   r   test_masked_array  s,    
z TestConvolve1D.test_masked_arrayc                 C   s2   g d}g d}t ||tjd}t|g d dS )zP
        Check if convolve_fft works when passing a normalize function.
        r{   )r|   r|   r|   )r   )r|         N)r   r#   r$   r'   r   r   r   r   test_normalize_function  s    z&TestConvolve1D.test_normalize_functionc                 C   st   t g d}t dg}d}|d |d g}|D ]<}	||	 }
t||
|||d}|r`t|| q2t|||
  q2dS )zp
        Check that if normalize_kernel is False then the normalization
        tolerance is respected.
        r{   r*   g-C6?r!   )r   r   Znormalization_zero_tolN)r#   r7   r   r'   )r:   r   r   r   r   r7   Zbase_kernelZnormalization_rtolZ
norm_errorerrr   r   r   r   r   test_normalization_is_respected  s    	z.TestConvolve1D.test_normalization_is_respectedN)$__name__
__module____qualname__r   markparametrizeoption_namesoptionsr<   rA   rC   rV   rc   option_names_preserve_nanoptions_preserve_nanrj   r#   r7   rf   infZinputsZoutputsrQ   	itertoolsproductBOUNDARY_OPTIONSNANTREATMENT_OPTIONSZoptions_unity1withnanrm   rt   r   r   r   r   r   r   r   r   r   r   r(   S   sJ   



)
)


C	r(   c                   @   s   e Zd Zejeedd Zejeedd Z	ejeedd Z
ejeedd Zejeed	d
 Zdd Zdd Zejdedd ZdS )TestConvolve2Dc              
   C   s   t jg dg dg dgdd}t jdggdd}t|dZ t||d. t||||||d	}t|| W d
   n1 s~0    Y  W d
   n1 s0    Y  d
S )zD
        Test that a 1x1 unit kernel returns the same array
        r=   r+   r,   r-   r.   r/         "@r0   r1   r*   r5   r6   r   Nr@   r9   r   r   r   test_unity_1x1_none  s    
z"TestConvolve2D.test_unity_1x1_nonec              
   C   s   t jg dg dg dgdd}t jg dg dg dgdd}t|dZ t||d	. t||||||d
}t|| W d   n1 s0    Y  W d   n1 s0    Y  dS )zl
        Test that a 3x3 unit kernel returns the same array (except when
        boundary is None).
        r=   r   r   r0   r1   r"   r"   r"   rB   r5   r6   r   Nr@   r9   r   r   r   test_unity_3x3  s(    

zTestConvolve2D.test_unity_3x3c                 C   s  t jg dg dg dgdd}t jg dg dg dgdd}t|dF t||d t|||||rrt jnd	||d
}t jg dg dg dgdd}t jg dg dg dgddt jg dg dg dgddd}	|	d | |	d< |	d d |	d< |	d d |	d< |	d |	d< |r(d}
nd}
|dkr@|
d7 }
n|dkrR|
d7 }
|	|
 }t|| W d   n1 sz0    Y  W d   n1 s0    Y  dS )zu
        Test that the different modes are producing the correct results using
        a 3x3 uniform kernel.
        r"   r"   r?   )r*   r"   r"   r"   r>   r"   r0   r1   rE   r5   r6   r   )r   r   rz   r   r   r+   r-   r+   r-   r   r-   rF   r?   r-   r,   r?   r?   r>   r-   r-   r-   r[   rM   r[   r^   rM   r   rN   average_withzerossum_withzerosr   ra   r   
_withzerosN)r#   r7   r   r    r   rf   r'   )r:   r   r   r   r   r%   r&   r;   wrT   rS   ar   r   r   test_uniform_3x3  sh    







zTestConvolve2D.test_uniform_3x3c              	   C   s   t jg ddt jdgg dgdd}t jg dg dg dgdd}t|d	$ t||||||d
}W d   n1 sx0    Y  |rt |d sJ t |}t |}t|| dS )z
        Test that a 3x3 unit kernel returns the same array (except when
        boundary is None). This version includes a NaN value in the original
        array.
        r=   r+   r-   r   r0   r1   r   rB   r5   r   NrP   rP   re   ri   r   r   r   test_unity_3x3_withnan<  s.    	


$

z%TestConvolve2D.test_unity_3x3_withnanc              
   C   sD  t jg ddt jdgg dgdd}t jg dg dg dgdd}t|d8 t|||||rl|d	krlt jnd
||d}W d   n1 s0    Y  |rt |d sJ t jg dg dg dgdd}t jg dg dg dgdd}	t jg dg dg dgddt jg dg dg dgddd}
|
d |	 |
d< |
d | |
d< |
d d |
d< |
d d |
d< |
d d |
d< |
d d |
d < |
d |
d!< |
d d" d |
d#< |
d |
d$< |
d d" d |
d%< |rd}nd}|d&kr|d'7 }n|d(kr|d)7 }|d	kr|d*7 }|
|  t t |}t|| ||  dS )+z
        Test that the different modes are producing the correct results using
        a 3x3 uniform kernel. This version includes a NaN value in the
        original array.
        r   r*   r"   r   r0   r1   rE   r5   r   r   )r   r   rz   r   r   Nr   )r?   r,   r?   )r,   r/   r,   r   r   rF   r   r   r   r   r[   r^   Zaverage_interpnanrM   r/   rn   r   rN   r   Zaverage_withzeros_interpnanr   	   Zsum_interpnanZsum_withzeros_interpnanZsum_wrap_interpnanr   ra   r   r   ro   )	r#   r7   rf   r   r   rg   whererq   r'   )r:   r   r   r   r   r%   r&   r;   Zw_nZw_zrT   rS   rs   r   r   r   test_uniform_3x3_withnan[  s    	


$







z'TestConvolve2D.test_uniform_3x3_withnanc                 C   sN   t ttf, tjg dtd}t|| W d   n1 s@0    Y  dS )zN Test that convolve_fft raises an exception if a too-large array is passed in.)   r   r   r1   N)r   r   r   MemoryErrorr#   emptycomplexr   )r:   Zarrr   r   r   test_big_fail  s    zTestConvolve2D.test_big_failc                 C   s   d}t j|dd}d|ddddd	f< t jd
dd}d|d< tjtddN t||dddd}t|j| t||dddd}|jdv sJ W d   n1 s0    Y  t||dddd}t|jt |t |j  t||dddd}|jdv sJ dS )z
        Test that convolve_fft pads to _next_fast_lengths and does not expand all dimensions
        to length of longest side (#11242/#10047).
        )rP   i  i  r0   r1   r*   r   iX  ib  i,  i0  )rP      r   )r   r|   r|   z=psf_pad was set to False, which overrides the boundary='fill'r   TF)Z
return_fftpsf_padfft_pad))rP       )rP   i    N))rO   r   r   )rO   r   r   )	r#   Zzerosr   r   r   r   r   shaper7   )r:   r   Zimgr   Zimg_fftr   r   r   test_padding  s     ,zTestConvolve2D.test_paddingr   c                 C   s   t jg dg dg dgdd}t jg dg dg dgdd}t|d" t|||d	d
d}W d    n1 sr0    Y  |dv rt|t jg dg dg dgdd n8|dkrt|t jg dg dg dgdd ntdd S )N)r"   r"   r+   )r*   r>   r"   )r"   r?   r"   floatr1   )r*         r*   )r   r"   r   r5   r   F)r   r   r   Nr   )r*   g      r>   )r*   r"   g      )g       r   r   r   )r"   g       r-   )r,   r"         )r>   r?   r   zInvalid boundary specification)r#   r7   r   r   r'   r   )r:   r   r%   r&   r;   r   r   r   test_non_normalized_kernel  s>    


$

z)TestConvolve2D.test_non_normalized_kernelN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s   


3

Vr   r   c                 C   s   t jg ddd}t jg ddd}t| d  t||| dd}W d   n1 sT0    Y  | d	v rt|t jg d
ddd n"| dkrt|t jg dddd dS )zT
    Make sure that asymmetric convolution
    functions go the right direction
    )r?   r"   r*   r
   r1   r{   r5   F)r   r   Nr   )r-         $@r>   r   r!   r   )r   r   r,   )r#   r7   r   r   r   )r   r%   r&   r;   r   r   r   test_asymmetric_kernel  s    .r   )r   r   r   r   r2   c           
   	   C   s   g d}g d}t j||d}t j||d}d|j_d|j_t| d$ t||| |||d}	W d   n1 sp0    Y  t t j||d|ksJ t t j||d|ksJ dS )zF
    Test that convolve_fft works correctly when inputs are lists
    r)   r3   r1   Fr5   r   N)r#   r7   flags	writeabler   r   all)
r   r   r   r   r2   r7   r   r%   r&   r;   r   r   r   test_input_unmodified  s    
$r   c              	   C   s"  dddt jdddg}g d}t j||d}t j||d}d|j_d|j_| }	| }
t| d	$ t||| |||d
}W d   n1 s0    Y  t |}t |}| }| }t 	|	| || ksJ t 	|
| || ksJ t 	t || sJ t 	t || sJ dS )z>
    Test that convolve_fft doesn't modify the input data
    r*   r+   r,   r.   r/   r3   r1   Fr5   r   N)
r#   rf   r7   r   r   copyr   r   rg   r   )r   r   r   r   r2   r7   r   r%   r&   Zx_copyZy_copyr;   Zarray_is_nanZkernel_is_nanZarray_not_nanZkernel_not_nanr   r   r   test_input_unmodified_with_nan$  s(    
$

r   error_kwargr   r   r   c                 C   s   t jg dg dg dgdd}t jdggdd}t||dd|k sLJ tt&}t||fd	di|  W d    n1 s0    Y  t|jd
t	| 
 d  dksJ d S )Nr=   r   r   r
   r1   r*   r   r5   r   zWith boundary='wrap', r   z cannot be enabled.)r#   r7   r   r   r   r   r   strvaluerQ   rR   )r   r%   r&   r   r   r   r   %test_convolve_fft_boundary_wrap_errorO  s    
4r   c                  C   s   t jg dg dg dgdd} t jdggdd}tt}t| |dd W d    n1 s`0    Y  t|jd	ks|J d S )
Nr=   r   r   r
   r1   r*   extendr5   z@The 'extend' option is not implemented for fft-based convolution)r#   r7   r   r   NotImplementedErrorr   r   r   )r%   r&   r   r   r   r   'test_convolve_fft_boundary_extend_error]  s    
,r   )N)NF)*r   
contextlibr   r   Znumpyr#   Znumpy.testingr   r   r   Zastropy.convolution.convolver   r   Zastropy.utils.exceptionsr   Zastropyr	   r8   ZVALID_DTYPESrQ   r   ZVALID_DTYPE_MATRIXr   r   ZNORMALIZE_OPTIONSZPRESERVE_NAN_OPTIONSr   r   r   r   r   r    r'   r(   r   r   r   r   r   r   r   r   r   r   r   r   <module>   st   

   	  


$
