B
    z‹dí<  ã               @   s¨   d Z ddlmZmZmZ ddlZddlZddlm	Z	 ddl
mZmZ ddlmZ dZd	d
„ Zdd„ Zdd„ Zdd„ ZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )z%
Defines various pytest unit tests.

é    )Úabsolute_importÚprint_functionÚdivisionN)ÚRandomStateé   )ÚSamplerÚmake_ladder)ÚPooléüÿÿÿc             C   s   t  | t  || ¡¡ d S )Né   )ÚnpÚdot)ÚxÚicov© r   úZ/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/ptemcee/tests.pyÚlogprob_gaussian   s    r   c             C   s"   t  | ¡ ¡ st jS t| |ƒS d S )N)r   ÚarrayÚanyÚnanr   )r   r   r   r   r   Úlogprob_gaussian_nan   s    r   c             C   s(   t  | ¡dk  ¡ rt j S t| |ƒS d S )Nr   )r   r   r   Úinfr   )r   r   r   r   r   Úlogprob_gaussian_inf!   s    r   c             C   s´   | d dkrRd}x(t d| d d ƒD ]}|t |¡7 }q$W | d t tj¡ | S d}x&t d| d dƒD ]}|t |¡7 }qhW | d d t d¡ | d d t tj¡  | S d S )Nr   r   r   )Úranger   ÚlogÚpi)ÚndimZlogfactorialÚir   r   r   Úlog_unit_sphere_volume)   s    r   c               @   s   e Zd Zddd„Zdd„ ZdS )ÚLogLikeGaussianFc             C   s   || _ || _|| _dS )až  
        Initialize a gaussian PDF with the given inverse covariance matrix.  If
        not ``None``, ``cutoff`` truncates the PDF at the given number of sigma
        from the origin (i.e., the PDF is non-zero only on an ellipse aligned
        with the principal axes of the distribution).  Without this cutoff,
        thermodynamic integration with a flat prior is logarithmically
        divergent.

        N)r   Útest_nanÚtest_inf)Úselfr   r    r!   r   r   r   Ú__init__8   s    zLogLikeGaussian.__init__c             C   s(   | j rt}n| jrt}nt}||| jƒS )N)r    r   r!   r   r   r   )r"   r   Úfr   r   r   Ú__call__G   s    zLogLikeGaussian.__call__N)FF)Ú__name__Ú
__module__Ú__qualname__r#   r%   r   r   r   r   r   7   s   
r   c               @   s   e Zd Zddd„Zdd„ ZdS )ÚLogPriorGaussianNc             C   s   || _ || _d S )N)r   Úcutoff)r"   r   r*   r   r   r   r#   S   s    zLogPriorGaussian.__init__c             C   sB   t || jƒ}| jd k	r:| | j| j d kr4tj S dS ndS d S )Nr   r   )r   r   r*   r   r   )r"   r   Zcontourr   r   r   r%   W   s    
zLogPriorGaussian.__call__)N)r&   r'   r(   r#   r%   r   r   r   r   r)   R   s   
r)   c               @   sv   e Zd ZdZedd„ ƒZddd„Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚTestsNc             C   sN  t jdd d| _d| _d| _d| _d| _d| _t  | j¡| _	dt j
 | j| j¡ }t  |¡}||jt  | ¡ ¡ 7 }t  ||¡| _t j | j¡| _t  | j¡| _| j| j }t j
 || j¡}|t jj|d	d
 |df¡ }|t j
 |¡ |df¡d| j  9 }|| j | _t  ||¡| _| j | j| j| j¡| _| j | j| j| j¡| _d S )NÚraise)Úalléd   é   é
   éú   iè  g      à?éÿÿÿÿ)Úaxisr   )r   ZseterrÚnwalkersr   ÚntempsÚTmaxr*   ÚNZzerosÚmeanÚrandomZrandZtriuÚTZdiagZdiagonalr   ÚcovÚlinalgÚinvr   ÚeyeÚ	icov_unitZrandnZnormÚreshapeÚp0_unitÚp0)ÚclsZsqrtcovZnsamplesr   r   r   r   Úsetup_classf   s,    
$zTests.setup_classFc          
   C   s`  |rny0|  |¡}x | | j¡D ]}dstdƒ‚qW W n4 tk
rh } zt|ƒ|krVdS ‚ W dd}~X Y nX nb|  |¡}xT| | j¡D ]B}|j|j }	t 	|j
tj k¡rÂt 	|j
tj k¡sÊtdƒ‚t 	|	dk¡ræt 	|	dk¡sîtdƒ‚|j
j|j
j  kr|jjdd… ks$n td	ƒ‚|jjd | jks@td	ƒ‚|	jd |j
jd d krlt|	jƒdksttd	ƒ‚t 	|jdk¡sŽtd
ƒ‚t 	t |j¡dk¡s®tdƒ‚t 	t |j¡dk ¡sˆtdƒ‚qˆW t 	| ¡ dk¡sìtdƒ‚|s\t |j¡dkstdƒ‚t |j¡dks&tdƒ‚t |jd d|jjd f¡}
| jt | j¡ t| jƒ dt tj | j¡¡  }| jd t dtj ¡ dt tj | j¡¡  }| ¡ \}}t |||  ¡d| k sètd  ||| |¡ƒ‚dt! }t 	tj|
dd| j d | jd  |k ¡s&tdƒ‚t 	tj|
dd| j d | jd  |k ¡s\tdƒ‚dS )a*  
        Check that the sampler is behaving itself.

        Parameters
        ----------
        sampler : Sampler
            The sampler to check.
        p0 : float, optional
            The initial positions at which to start the sampler's walkers.
        weak : bool, optional
            If ``True``, just check that the sampler ran without errors; don't
            check any of the results.
        fail : :class:`Exception`, optional
            If specified, assert that the sampler fails with the given
            exception type.

        Fz"Sampler should have failed by now.Nz?Invalid posterior/likelihood values; outside posterior support.r   r   zInvalid swap ratios.r2   zSampler output shapes invalid.zNegative temperatures!zTemperatures have coalesced.z!Temperatures incorrectly ordered.z Invalid autocorrelation lengths.gš™™™™™¹?zAcceptance fraction < 0.1z+Temperature swap acceptance fraction < 0.1.)r   .g      à?r   é   z3Evidence incorrect: {:g}+/{:g} versus correct {:g}.r0   )r3   zMean incorrect.)ZrowvarzCovariance incorrect.)"ÚchainZiterater7   ÚAssertionErrorÚ	ExceptionÚtypeZswaps_acceptedZswaps_proposedr   r-   ZlogPr   Úshaper   r   ÚlenÚbetasÚdiffZget_actsr8   Újump_acceptance_ratioÚswap_acceptance_ratior@   r   r*   r   r<   Zdetr;   r   Zlog_evidence_estimateÚabsÚformatÚlogprecision)r"   ÚsamplerrB   ÚweakÚfailrF   r   ÚeÚensembleÚratiosÚdataZ
log_volumeZgaussian_integralZlogZZdlogZZmaxdiffr   r   r   Úcheck_samplerˆ   sb    

*0.
4$$zTests.check_samplerc          
   C   sf   t | j| jt| jƒt| j| jdt| j| j| j	dd}d| j | j
d d d< | j|| j
td d S )N)r*   )r6   )rL   g    €„.Ar   )rB   rU   )r   r4   r   r   r?   r)   r*   r   r5   r6   rA   rZ   Ú
ValueError)r"   rS   r   r   r   Útest_prior_supportà   s    
zTests.test_prior_supportc          
   C   sd   t | j| jt| jddt| j| jdt| j| j| j	dd}d| j
d d d< | j|| j
td d S )	NT)r!   )r*   )r6   )rL   r2   r   )rB   rU   )r   r4   r   r   r?   r)   r*   r   r5   r6   rA   rZ   r[   )r"   rS   r   r   r   Útest_likelihood_supportê   s    
zTests.test_likelihood_supportc          
   C   sh   t | j| jt| jddt| j| jdt| j| j| j	dd}d| j
d d d d …< | j|| j
td d S )	NT)r    )r*   )r6   )rL   r   r2   )rB   rU   )r   r4   r   r   r?   r)   r*   r   r5   r6   rA   rZ   r[   )r"   rS   r   r   r   Útest_nan_logprobö   s    
zTests.test_nan_logprobc          	   C   sV   t | j| jt| jddt| j| jdt| j| jt	j
ƒd}| j|t	 | j¡dd dS )a  
        If a walker has any parameter negative, ``logprobfn`` returns
        ``-np.inf``.  Start the ensembles in the all-positive part of the
        parameter space, then run for long enough for sampler to migrate into
        negative parts.  (We can't start outside the posterior support, or the
        sampler will fail).  The sampler should be happy with this; otherwise,
        a FloatingPointError will be thrown by Numpy.  Don't bother checking
        the results because this posterior is difficult to sample.

        T)r!   )r*   )rL   )rB   rT   N)r   r4   r   r   r?   r)   r*   r   r5   r   r   rZ   rP   rA   )r"   rS   r   r   r   Útest_inf_logprob  s
    
zTests.test_inf_logprobc          
   C   s°   t | j| jt| jƒt| j| jdt| j| j| j	dd}t
j| jd d d< | j|| jtd t
j| jd d d< | j|| jtd t
j | jd d d< | j|| jtd d S )N)r*   )r6   )rL   r2   r   )rB   rU   )r   r4   r   r   r?   r)   r*   r   r5   r6   r   r   rA   rZ   r[   r   )r"   rS   r   r   r   Útest_inf_nan_params  s    
zTests.test_inf_nan_paramsc          
   C   sT   t | j| jt| jƒt| j| jdt| j| j| j	dt
dƒjd}| j|| jd d S )N)r*   )r6   r   )rL   Zmapper)rB   )r   r4   r   r   r   r)   r*   r   r5   r6   r	   ÚmaprZ   rB   )r"   rS   r   r   r   Útest_parallel'  s    
zTests.test_parallelc          
   C   sL   t | j| jt| jƒt| j| jdt| j| j| j	dd}| j
|| jd d S )N)r*   )r6   )rL   )rB   )r   r4   r   r   r   r)   r*   r   r5   r6   rZ   rB   )r"   rS   r   r   r   Útest_temp_inf/  s
    
zTests.test_temp_infc             C   sN   t | j| jt| jƒt| j| jddt| j| j| j	dd}| j
|| jd d S )N)r*   T)r6   )ÚadaptiverL   )rB   )r   r4   r   r   r   r)   r*   r   r5   r6   rZ   rB   )r"   rS   r   r   r   Útest_gaussian_adapt6  s    
zTests.test_gaussian_adaptc             C   sæ  t | j| jt| jƒt| j| jddt| j| j| j	dd}d}d}d}| 
| jt|ƒ¡}| | jt|ƒ|¡}| | jt|ƒ|¡}t || jf¡}t || j| j| jf¡}	x>t|ƒD ]2}
xt|ƒD ]}| ¡  qÀW |j|	|
< |j||
< q²W t || jf¡}t || j| j| jf¡}x2tt ||¡ƒD ]\}
}|j||
< |j||
< q"W | |¡\}}|j|k ¡ sjtdƒ‚|j|k ¡ s‚td	ƒ‚|j|	k ¡ sštd
ƒ‚|j|k ¡ s²td
ƒ‚|j|k ¡ sÊtdƒ‚|j|k ¡ sâtdƒ‚dS )zP
        Test that various ways of running the sampler are equivalent.

        )r*   T)r6   )rd   rL   r0   r   r   z#Jump acceptance ratios don't match.z#Swap acceptance ratios don't match.zChains don't match.zLadders don't match.N)r   r4   r   r   r   r)   r*   r   r5   r6   rW   rB   r   rF   Úsampler   Úemptyr   Ústepr   rL   Ú	enumerateÚ	itertoolsÚisliceÚrunrN   r-   rG   rO   )r"   rS   r7   Úthin_byÚseedrW   rF   ZsamplesZbetas1Úx1r   Ú_Zbetas2Zx2rV   ÚjrÚsrr   r   r   Útest_ensemble>  s<    


zTests.test_ensemblec       	      C   sÌ  t | j| jt| jƒt| j| jddt| j| j| j	dd}d}d}d}| 
| jt|ƒ|¡}| |¡\}}d|k ¡ r€|dk ¡ s„t‚d|k ¡ rœ|dk ¡ s t‚|jjd |ks´t‚| |¡\}}d|k ¡ rÚ|dk ¡ sÞt‚d|k ¡ rö|dk ¡ sút‚|jjd d| kst‚| 
| jt|ƒ|¡}| d| ¡\}}d|k ¡ rV|dk ¡ sZt‚d|k ¡ rv|dk ¡ szt‚|jjd d| ks”t‚|j|jk ¡ s®td	ƒ‚|j|jk ¡ sÈtd
ƒ‚d S )N)r*   T)r6   )rd   rL   r0   r   r   r   zChains don't match.zLadders don't match.)r   r4   r   r   r   r)   r*   r   r5   r6   rF   rB   r   rl   r-   rG   r   rJ   rL   )	r"   rS   r7   rm   rn   Zchain1rq   rr   Zchain2r   r   r   Útest_resumeg  s0    
  zTests.test_resume)FF)r&   r'   r(   rS   ÚclassmethodrD   rZ   r\   r]   r^   r_   r`   rb   rc   re   rs   rt   r   r   r   r   r+   c   s   "
X
)r+   )Ú__doc__Ú
__future__r   r   r   rj   Únumpyr   Znumpy.random.mtrandr   rS   r   r   Zinterruptible_poolr	   rR   r   r   r   r   Úobjectr   r)   r+   r   r   r   r   Ú<module>   s   