B
    ú‹d~; ã               @   st  d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ ddlZddlZddlmZ ddlmZ yddlZW n ek
r    dZY nX yddlZW n ek
rÆ   dZY nX dd	d
ddddddddddddgZe ee ej¡jƒ¡Ze	dddddddddd d!d"d#d$d%d&d'gƒZe	d(ddddd!d"d#d$d%g	ƒZ d)Z!G d*d„ dƒZ"G d+d„ dƒZ#G d,d„ dƒZ$G d-d„ dƒZ%e	d.d/d0d1d2gƒZ&ddddej' ej'dfd3d4„Z(ddddej' ej'fd5d6„Z)ddddej' ej'fd7d8„Z*ddddej' ej'fd9d:„Z+d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRgZ,G dSdT„ dTƒZ-e- j dUe.dV /dWdX„ e,D ƒ¡ƒ dV 7  _ dYdZ„ Z0d[d„ Z1d\d]„ Z2d^d_„ Z3d‰d`da„Z4dbdc„ Z5ddde„ Z6dŠdfd„Z7dgdh„ Z8did
„ Z9d‹djd	„Z:dŒdkd„Z;dldm„ Z<dndo„ Z=ddqd„Z>dŽdrds„Z?dtdu„ Z@ddvd„ZAddwd„ZBd‘dyd„ZCd’dzd„ZDd{d|„ ZEd“d~d„ZFd”dd€„ZGdd‚„ ZHd•dƒd„„ZId–d…d†„ZJd‡dˆ„ ZKdS )—z$
A collection of useful functions.

é    N)Ú
namedtuple)Úpartial)Ú	logsumexpé   )Ú__version__Ú	unitcheckÚresample_equalÚmean_and_covÚquantileÚ
jitter_runÚresample_runÚreweight_runÚunravel_runÚ
merge_runsÚ	kld_errorÚget_enlarge_bootstrapÚ
LoglOutputÚLogLikelihoodÚ	RunRecordÚ
DelayTimerÚIteratorResultZworstZustarZvstarÚloglstarÚlogvolÚlogwtÚlogzÚlogzvarÚhÚncZworst_itÚboundidxÚ	bounditerÚeffÚ
delta_logzÚblobÚIteratorResultShortgœu ˆ<ä7þc               @   sH   e Zd Z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 )r   z²
    Class that encapsulates the output of the likelihood function.
    The reason we need this wrapper is to preserve the blob associated with
    the likelihood function.

    c             C   s$   |r|d | _ |d | _n|| _ dS )a-  
        Initialize the object

        Parameters
        ----------
        v: float or tuple
            if blob_flag is true v have to be a tuple of logl and blob
            if it is False v is just logl
        blob_flag: boolean
            flag to mark whether the v has a blob or not
        r   r   N)Úvalr"   )ÚselfÚvZ	blob_flag© r'   úZ/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/dynesty/utils.pyÚ__init__?   s    
zLoglOutput.__init__c             C   s   t | ƒt |ƒk S )zS
        Comparison override, we just use .val attribute in the comparison
        )Úfloat)r%   Úv1r'   r'   r(   Ú__lt__Q   s    zLoglOutput.__lt__c             C   s   t | ƒt |ƒkS )zS
        Comparison override, we just use .val attribute in the comparison
        )r*   )r%   r+   r'   r'   r(   Ú__gt__W   s    zLoglOutput.__gt__c             C   s   t | ƒt |ƒkS )zS
        Comparison override, we just use .val attribute in the comparison
        )r*   )r%   r+   r'   r'   r(   Ú__le__]   s    zLoglOutput.__le__c             C   s   t | ƒt |ƒkS )zS
        Comparison override, we just use .val attribute in the comparison
        )r*   )r%   r+   r'   r'   r(   Ú__ge__c   s    zLoglOutput.__ge__c             C   s   t | ƒt |ƒkS )zS
        Comparison override, we just use .val attribute in the comparison
        )r*   )r%   r+   r'   r'   r(   Ú__eq__i   s    zLoglOutput.__eq__c             C   s
   t | jƒS )zS
        Comparison override, we just use .val attribute in the comparison
        )r*   r$   )r%   r'   r'   r(   Ú	__float__o   s    zLoglOutput.__float__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r)   r,   r-   r.   r/   r0   r1   r'   r'   r'   r(   r   7   s   c               @   sJ   e Zd Z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S )r   z‡
    Class that calls the likelihood function (using a pool if provided)
    Also if requested it saves the history of evaluations
    NFc             C   sL   || _ || _g | _g | _d| _|| _|| _|| _d| _|| _	|rH|  
¡  dS )a9   Initialize the object.

        Parameters
        ----------
        loglikelihood: function
        ndim: int
            Dimensionality
        pool: Pool (optional)
            Any kind of pool capable of performing map()
        save: bool
            if True the function evaluations will be saved in the hdf5 file
        history_filename: string
            The filename where the history will go
        blob: boolean
            if True we expect the logl output to be a tuple of logl value and
            a blob, otherwise it'll be logl value only
        i'  FN)ÚloglikelihoodÚpoolÚhistory_parsÚhistory_loglÚ
save_everyÚsaveÚhistory_filenameÚndimÚfailed_saver"   Úhistory_init)r%   r6   r=   r7   r;   r<   r"   r'   r'   r(   r)   |   s    zLogLikelihood.__init__c                sh   ˆ j dkr*t‡ fdd„tˆ j|ƒD ƒƒ}n‡ fdd„ˆ j  ˆ j|¡D ƒ}ˆ jrdˆ  dd„ |D ƒ|¡ |S )zÞ
        Evaluate the likelihood function on the list of vectors
        The pool is used if it was provided when the object was created

        Returns
        -------
        ret: The list of LoglOutput objects
        Nc                s   g | ]}t |ˆ jƒ‘qS r'   )r   r"   )Ú.0Ú_)r%   r'   r(   ú
<listcomp>¬   s    z%LogLikelihood.map.<locals>.<listcomp>c                s   g | ]}t |ˆ jƒ‘qS r'   )r   r"   )r@   rA   )r%   r'   r(   rB   °   s   c             S   s   g | ]
}|j ‘qS r'   )r$   )r@   rA   r'   r'   r(   rB   ´   s    )r7   ÚlistÚmapr6   r;   Úhistory_append)r%   ÚparsÚretr'   )r%   r(   rD   ¡   s    	

zLogLikelihood.mapc             C   s.   t |  |¡| jƒ}| jr*|  |jg|g¡ |S )z2
        Evaluate the likelihood f-n once
        )r   r6   r"   r;   rE   r$   )r%   ÚxrG   r'   r'   r(   Ú__call__·   s    zLogLikelihood.__call__c             C   s4   | j  |¡ | j |¡ t| j ƒ| jkr0|  ¡  dS )zd
        Append to the internal history the list of loglikelihood values
        And points
        N)r9   Úextendr8   Úlenr:   Úhistory_save)r%   ÚloglsrF   r'   r'   r(   rE   À   s    zLogLikelihood.history_appendc          	   C   sŒ   t dkrtdƒ‚d| _yRt j| jdd8}|jd| j| jfd| jfd |jd| jfd	d W dQ R X W n tk
r†   t	d
ƒ ‚ Y nX dS )z, Initialize the hdf5 storage of evaluations Nz3h5py module is required for saving history of callsr   Úw)ÚmodeÚparam)ZmaxshapeÚlogl)Nz!Failed to initialize history file)
Úh5pyÚRuntimeErrorÚhistory_counterÚFiler<   Zcreate_datasetr:   r=   ÚOSErrorÚprint)r%   Úfpr'   r'   r(   r?   Ê   s    zLogLikelihood.history_initc          	   C   sê   | j s| jsdS y°tj| jdd–}t| jƒ}|d j| j| dd |d j| j| dd t	 
| j¡|d | d…dd…f< t	 
| j¡|d | d…< g | _g | _|  j|7  _W dQ R X W n$ tk
rä   t d¡ d	| _ Y nX dS )
zO
        Save the actual history from an internal buffer into the file
        NÚa)rO   rP   r   )ÚaxisrQ   z:Failed to save history of evaluations. Will not try again.T)r>   r;   rR   rU   r<   rK   r9   ÚresizerT   ÚnpÚarrayr8   rV   ÚwarningsÚwarn)r%   rX   Únaddr'   r'   r(   rL   Ú   s     
"zLogLikelihood.history_savec             C   s   | j  ¡ }d|kr|d= |S )z#Get state information for pickling.r7   )Ú__dict__Úcopy)r%   Ústater'   r'   r(   Ú__getstate__ò   s    
zLogLikelihood.__getstate__)NFNF)r2   r3   r4   r5   r)   rD   rI   rE   r?   rL   rd   r'   r'   r'   r(   r   v   s      
	
c               @   s:   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )r   z›
    This is the dictionary like class that saves the results of the nested
    run so it is basically a collection of various lists of
    quantities
    Fc             C   s\   i }ddddddddd	d
ddddddg}|r<|  dddg¡ x|D ]}g ||< qBW || _dS )z^
        If dynamic is true. We initialize the class for
        a dynamic nested run
        ÚidÚur&   rQ   r   r   r   r   r   r   r   ÚitÚnr   Úscaler"   ÚbatchÚbatch_nliveÚbatch_boundsN)rJ   ÚD)r%   Zdynamicrm   ÚkeysÚkr'   r'   r(   r)     s2    
zRunRecord.__init__c             C   s*   x$|  ¡ D ]}| j|  || ¡ q
W dS )zƒ
        append new information to the RunRecord in the form a dictionary
        i.e. run.append(dict(batch=3, niter=44))
        N)rn   rm   Úappend)r%   ZnewDro   r'   r'   r(   rp   %  s    zRunRecord.appendc             C   s
   | j | S )N)rm   )r%   ro   r'   r'   r(   Ú__getitem__-  s    zRunRecord.__getitem__c             C   s   || j |< d S )N)rm   )r%   ro   r&   r'   r'   r(   Ú__setitem__0  s    zRunRecord.__setitem__c             C   s
   | j  ¡ S )N)rm   rn   )r%   r'   r'   r(   rn   3  s    zRunRecord.keysN)F)	r2   r3   r4   r5   r)   rp   rq   rr   rn   r'   r'   r'   r(   r   ú   s   
$c               @   s    e Zd ZdZdd„ Zdd„ ZdS )r   zE Utility class that allows us to detect a certain
    time has passedc             C   s   || _ t ¡ | _dS )z¢ Initialise the time with delay of dt seconds

        Parameters
        ----------

        delay: float
            The number of seconds in the timer
        N)ÚdelayÚtimeÚ	last_time)r%   rs   r'   r'   r(   r)   ;  s    	zDelayTimer.__init__c             C   s&   t   ¡ }|| j | jkr"|| _dS dS )a?  
        Returns true if more than self.dt seconds has passed
        since the initialization or last call of successful is_time()

        Returns
        -------
        ret: bool
             True if specified amout of time has passed since the
             initialization or last successful is_time() call
        TF)rt   ru   rs   )r%   Zcurtr'   r'   r(   Úis_timeG  s
    zDelayTimer.is_timeN)r2   r3   r4   r5   r)   rv   r'   r'   r'   r(   r   7  s   ÚPrintFnArgsÚniterÚ	short_strÚmid_strÚlong_strc
       
      C   sD   |	dkr$t | ||||||||d	 nt|	| ||||||||d
 dS )aú  
    The default function used to print out results in real time.

    Parameters
    ----------

    results : tuple
        Collection of variables output from the current state of the sampler.
        Currently includes:
        (1) particle index,
        (2) unit cube position,
        (3) parameter position,
        (4) ln(likelihood),
        (5) ln(volume),
        (6) ln(weight),
        (7) ln(evidence),
        (8) Var[ln(evidence)],
        (9) information,
        (10) number of (current) function calls,
        (11) iteration when the point was originally proposed,
        (12) index of the bounding object originally proposed from,
        (13) index of the bounding object active at a given iteration,
        (14) cumulative efficiency, and
        (15) estimated remaining ln(evidence).

    niter : int
        The current iteration of the sampler.

    ncall : int
        The total number of function calls at the current iteration.

    add_live_it : int, optional
        If the last set of live points are being added explicitly, this
        quantity tracks the sorted index of the current live point being added.

    dlogz : float, optional
        The evidence stopping criterion. If not provided, the provided
        stopping value will be used instead.

    stop_val : float, optional
        The current stopping criterion (for dynamic nested sampling). Used if
        the `dlogz` value is not specified.

    nbatch : int, optional
        The current batch (for dynamic nested sampling).

    logl_min : float, optional
        The minimum log-likelihood used when starting sampling. Default is
        `-np.inf`.

    logl_max : float, optional
        The maximum log-likelihood used when stopping sampling. Default is
        `np.inf`.

    N)Úadd_live_itÚdlogzÚstop_valÚnbatchÚlogl_minÚlogl_max)Úprint_fn_fallbackÚprint_fn_tqdm)
Úresultsrx   Úncallr|   r}   r~   r   r€   r   Úpbarr'   r'   r(   Úprint_fn]  s(    A
r‡   c	             C   s¸  | j }	| j}
| j}| j}| j}| j}| j}|dkr8tj}|dkrT|dkrTt 	|¡}ntj
}|
dkrjtj }
|	dkrztj }	g }|d k	r–| d |¡¡ t|ƒ}|d k	r¶| d |¡¡ | d |¡¡ | d |¡¡ | d |¡¡ | d	 |¡¡ | |d
 ¡ | d ||	|¡¡ | d ||	|¡¡ | d |
|¡¡ | d |
|¡¡ t|ƒ}|d k	rˆ| d ||¡¡ | d ||¡¡ n | d |¡¡ | d |¡¡ t||||dS )Ng    €„.Ag        g    €„.Áz+{:d}zbatch: {:d}zbound: {:d}znc: {:d}zncall: {:d}zeff(%): {:6.3f}éÿÿÿÿz%loglstar: {:6.3f} < {:6.3f} < {:6.3f}zlogl*: {:6.1f}<{:6.1f}<{:6.1f}zlogz: {:6.3f} +/- {:6.3f}zlogz: {:6.1f}+/-{:.1f}zdlogz: {:6.3f} > {:6.3f}zdlogz: {:6.1f}>{:6.1f}zstop: {:6.3f})rx   ry   rz   r{   )r   r   r   r!   r   r   r    r\   ÚinfÚsqrtÚnanrp   ÚformatrC   rw   )r„   rx   r…   r|   r}   r~   r   r€   r   r   r   r   r!   r   r   r    Úlogzerrr{   ry   rz   r'   r'   r(   Úget_print_fn_argsµ  sV    

rŽ   c
             C   sF   t |||||||||	d	}
| jd |
j¡dd |  |
j| j ¡ dS )zL
    This is a function that does the status printing using tqdm module
    )r|   r}   r~   r   r€   r   z | F)ÚrefreshN)rŽ   Zset_postfix_strÚjoinr{   Úupdaterx   rh   )r†   r„   rx   r…   r|   r}   r~   r   r€   r   Úfn_argsr'   r'   r(   rƒ   ô  s    rƒ   c	             C   s$  t | ||||||||d	}	|	j|	j|	j|	jf\}}
}}d |¡g| }d |¡}d |¡}d |
¡}
tj 	¡ rŠt
tdƒrŠtjddd }nd	}|t|ƒkrÀtj d
| d|t|ƒ d   ¡ nV|t|ƒkròtj d
| d|t|ƒ d   ¡ n$tj d
|
 d|t|
ƒ d   ¡ tj ¡  dS )zl
    This is a function that does the status printing using just
    standard printing into the console
    )r|   r}   r~   r   r€   r   z
iter: {:d}z | ú|Úget_terminal_size)éP   é   )Úfallbackr   éÈ   úú é   N)rŽ   rx   ry   rz   r{   rŒ   r   ÚsysÚstderrÚisattyÚhasattrÚshutilr”   rK   ÚwriteÚflush)r„   rx   r…   r|   r}   r~   r   r€   r   r’   ry   rz   r{   Úcolumnsr'   r'   r(   r‚     s2    


&&r‚   )rQ   zarray[float]zLog likelihoodrx   )Ú
samples_itz
array[int]zIthe sampling iteration when the sample was proposed (e.g., iteration 570)rx   )Ú
samples_idz
array[int]z5The unique ID of the sample XXX (within nlive points)N)Ú	samples_nz
array[int]zCThe number of live points at the point when the sample was proposedrx   )Ú	samples_uzarray[float]zEThe coordinates of live points in the
    unit cube coordinate systemz
niter,ndim)Z	samples_vzarray[float]zThe coordinates of live pointsz
niter,ndim)Úsamplesr]   z>the location (in original coordinates). Identical to samples_vz
niter,ndim)rx   Úintznumber of iterationsN)r…   r©   zTotal number likelihood callsN)r   r]   z$Array of cumulative log(Z) integralsrx   )r   r]   zArray of uncertainty of log(Z)rx   )r   r]   zArray of log-posterior weightsrx   )r    r*   zSampling efficiencyN)Únliver©   z&Number of live points for a static runN)r   zarray[float]zLogvolumes of dead pointsrx   )Úinformationzarray[float]zInformation Integral Hrx   )Úboundzarray[object]zHthe set of bounding objects used to condition proposals for the base runZnbound)Z
bound_iterz
array[int]zGindex of the bound being used for an iteration that generated the pointrx   )Zsamples_boundz
array[int]zCThe index of the bound that the corresponding sample was drawn fromrx   )Úsamples_batchz
array[int]z7Tracks the batch during which the samples were proposedrx   )rl   zarray[tuple]z.The log-likelihood bounds used to run a batch.r   )rk   z
array[int]z/The number of live points used for  given batchr   )ri   zarray[float]z"Scalar scale applied for proposalsrx   )r"   zarray[]z;The auxiliary blobs computed by the log-likelihood functionrx   c                   sœ   e Zd ZdZedd„ eD ƒƒZdd„ Zdd„ Zdd	„ Z	‡ f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d„Zdd „ Z‡  ZS )"ÚResultsa
  
    Contains the full output of a run along with a set of helper
    functions for summarizing the output.
    The object is meant to be unchangeable record of the static or
    dynamic nested run.

    Results attributes (name, type, description, array size):
    c             C   s   g | ]}|d  ‘qS )r   r'   )r@   rA   r'   r'   r(   rB   v  s    zResults.<listcomp>c             C   sÚ   g | _ d| _t|tƒr | ¡ }n|}xN|D ]F\}}|| j ks@t‚|tjksRt|ƒ‚| j  |¡ t	| |t
 
|¡ƒ q*W ddddg}x"|D ]}|| j kr†td| ƒ‚q†W d| j kr¶d| _nd| j krÈd	| _ntd
ƒ‚d	| _dS )zÛ
        Initialize the results using the list of key value pairs
        or a dictionary
        Results([('logl', [1, 2, 3]), ('samples_it',[1,2,3])])
        Results(dict(logl=[1, 2, 3], samples_it=[1,2,3]))
        Fr§   r¥   rQ   r¨   zKey %s must be providedrª   r¦   TzITrying to construct results object without nlive or samples_n informationN)Ú_keysÚ_initializedÚ
isinstanceÚdictÚitemsÚAssertionErrorr®   Ú_ALLOWEDrp   Úsetattrrb   Ú
ValueErrorÚ_dynamic)r%   Ú
key_valuesZkey_values_listro   r&   Úrequired_keysr'   r'   r(   r)   x  s*    





zResults.__init__c             C   s   t |  ¡  ¡ ƒS )N)r®   Úasdictr³   )r%   r'   r'   r(   Ú__copy__š  s    zResults.__copy__c             C   s   |   ¡ S )zY
        return a copy of the object
        all numpy arrays will be copied too
        )r¼   )r%   r'   r'   r(   rb   ž  s    zResults.copyc                s,   |d dkr| j rtdƒ‚tƒ  ||¡ d S )Nr   rA   zCannot set attributes directly)r°   rS   ÚsuperÚ__setattr__)r%   ÚnameÚvalue)Ú	__class__r'   r(   r¾   ¥  s    zResults.__setattr__c             C   s    || j krt| |ƒS t|ƒ‚d S )N)r¯   ÚgetattrÚKeyError)r%   r¿   r'   r'   r(   rq   ª  s    

zResults.__getitem__c                s8   t ttttˆjƒƒƒƒd ‰ d ‡ ‡fdd„ˆjD ƒ¡S )Nr   Ú
c                s(   g | ] }|  ˆ ¡d  ttˆ|ƒƒ ‘qS )z: )ÚrjustÚreprrÂ   )r@   ro   )Úmr%   r'   r(   rB   ³  s    z$Results.__repr__.<locals>.<listcomp>)ÚmaxrC   rD   rK   r¯   r   )r%   r'   )rÇ   r%   r(   Ú__repr__°  s    zResults.__repr__c             C   s
   || j kS )N)r¯   )r%   Úkeyr'   r'   r(   Ú__contains__µ  s    zResults.__contains__c             C   s   | j S )z6 Return the list of attributes/keys stored in Results )r¯   )r%   r'   r'   r(   rn   ¸  s    zResults.keysc                s   ‡ fdd„ˆ j D ƒS )zS
Return the list of items in the results object as list of key,value pairs
        c             3   s   | ]}|t ˆ |ƒfV  qd S )N)rÂ   )r@   ro   )r%   r'   r(   ú	<genexpr>À  s    z Results.items.<locals>.<genexpr>)r¯   )r%   r'   )r%   r(   r³   ¼  s    zResults.itemsc                s   t ‡ fdd„ˆ jD ƒƒS )zE
        Return contents of the Results object as dictionary
        c             3   s"   | ]}|t   tˆ |ƒ¡fV  qd S )N)rb   rÂ   )r@   ro   )r%   r'   r(   rÌ   Ç  s    z!Results.asdict.<locals>.<genexpr>)r²   r¯   )r%   r'   )r%   r(   r»   Â  s    zResults.asdictc             C   s   | j S )z Return true if the results was constructed using dynamic
        nested sampling run with (potentially) variable number of
        live-points)r¸   )r%   r'   r'   r(   Ú	isdynamicÉ  s    zResults.isdynamicc             C   s.   | d | d d  }t  |¡}|| ¡  }|S )zD
        Return the importance weights for the each sample.
        r   r   rˆ   )r\   ÚexpÚsum)r%   r   Úwtr'   r'   r(   Úimportance_weightsÏ  s    
zResults.importance_weightsNc             C   s$   |dkrt ƒ }t| d |  ¡ |dS )zF
        Return the equally weighted samples in random order.
        Nr¨   )Úrstate)Úget_random_generatorr   rÑ   )r%   rÒ   r'   r'   r(   Úsamples_equalØ  s
    zResults.samples_equalc          	   C   s†   | j r<d | d t | d ¡| d | d d | d d ¡}n:d | d	 | d t | d ¡| d | d d | d d ¡}td
| ƒ dS )zHReturn a formatted string giving a quick summary
        of the results.zAniter: {:d}
ncall: {:d}
eff(%): {:6.3f}
logz: {:6.3f} +/- {:6.3f}rx   r…   r    r   rˆ   r   zMnlive: {:d}
niter: {:d}
ncall: {:d}
eff(%): {:6.3f}
logz: {:6.3f} +/- {:6.3f}rª   zSummary
=======
N)r¸   rŒ   r\   rÏ   rW   )r%   Úresr'   r'   r(   Úsummaryâ  s    

zResults.summary)N)r2   r3   r4   r5   ÚsetÚ_RESULTS_STRUCTURErµ   r)   r¼   rb   r¾   rq   rÉ   rË   rn   r³   r»   rÍ   rÑ   rÔ   rÖ   Ú__classcell__r'   r'   )rÁ   r(   r®   l  s    "	

r®   z

rÄ   c             C   s   g | ]}d t |ƒ ‘qS )z| )Ústr)r@   rA   r'   r'   r(   rB   ÿ  s    rB   c             C   sL   g }x>|   ¡ D ]2\}}||kr.| ||f¡ q| ||| f¡ qW t|ƒS )zx This is an utility method that takes a Result object and
substituted certain keys in it. It returns a copy object!
    )r³   rp   r®   )r„   Zkw_dictZnew_listro   rN   r'   r'   r(   Úresults_substitute  s    rÛ   c             C   s¦   d}d}|dk	r,|dkr,|dks$t ‚|dfS |dkrX|dk	rX|dksP|dksPt ‚d|fS |dkr‚|dkr‚| dkrxd|fS |dfS n |dks’|dkrš||fS tdƒ‚dS )z:
    Determine the enlarge, bootstrap for a given run
    g      ô?é   Nr   r   ZunifzREnlarge and bootstrap together do not make sense unless bootstrap=0 or enlarge = 1)r´   r·   )ÚsampleZenlargeZ	bootstrapZDEFAULT_ENLARGEZDEFAULT_UNIF_BOOTSTRAPr'   r'   r(   r     s    
c             C   sœ   |dk	r(|dk	r(t  ||¡dkr(tdƒ‚|dk	s8|dk	r”t j| td}|dk	rlt  |¡| krdtdƒ‚d||< |dk	r˜t  |¡| krŠtdƒ‚d||< nd}|S )z¥
    Return a boolean mask for dimensions that are either
    periodic or reflective. It will be true for normal dimension
    and false for periodic/reflective
    Nr   z?You have specified a parameter as both periodic and reflective.)Údtypez3Incorrect periodic variable index (larger than ndimF)r\   Zintersect1dr·   ÚonesÚboolrÈ   )r=   ZperiodicZ
reflectiveÚ
nonboundedr'   r'   r(   Úget_nonbounded1  s"    
râ   c             C   s:   d }| d kr2t d ks|st} nt   ¡ }tt|d} || fS )N)r†   )Útqdmr‡   r   )Z
print_funcÚprint_progressr†   r'   r'   r(   Úget_print_funcN  s    rå   c             C   s&   t | tjjƒr| S tj tj | ¡¡S )zJ
    Return a random generator (using the seed provided if available)
    )r±   r\   ÚrandomÚ	GeneratorZPCG64)Úseedr'   r'   r(   rÓ   Y  s    rÓ   c             C   s"   t j | jdddd¡ |¡}|S )zz
    Return the list of seeds to initialize random generators
    This is useful when distributing work across a pool
    r   l   ÿÿÿÿ é   )Úsize)r\   ræ   ZSeedSequenceÚintegersÚspawn)rÒ   ZnitemsÚseedsr'   r'   r(   Úget_seed_sequenceb  s    rî   c             C   s*   t  | |  ¡  ¡}| ¡ d |d  ¡  S )a7  
    Compute the number of effective samples from an array of unnormalized
    log-weights. We use Kish Effective Sample Size (ESS)  formula.

    Parameters
    ----------
    logwt: numpy array
        Array of unnormalized weights

    Returns
    -------
    int
        The effective number of samples
    r›   )r\   rÎ   rÈ   rÏ   )r   ÚWr'   r'   r(   Úget_neff_from_logwtl  s    rð   c             C   sf   |dkr |   ¡ dko|  ¡ dk S | | }| |  }|  ¡ dko`| ¡ dk o`|  ¡ dko`| ¡ dk S dS )z™Check whether `u` is inside the unit cube. Given a masked array
    `nonbounded`, also allows periodic boundaries conditions to exceed
    the unit cube.Nr   r   g      à¿g      ø?)ÚminrÈ   )rf   rá   ZunbZubr'   r'   r(   r   „  s    
$c             C   sD   t  | d¡dk }t  | | d¡| |< dt  | |  d¡ | | < | S )a  
    Iteratively reflect a number until it is contained in [0, 1].

    This is for priors with a reflective boundary condition, all numbers in the
    set `u = 2n +/- x` should be mapped to x.

    For the `+` case we just take `u % 1`.
    For the `-` case we take `1 - (u % 1)`.

    E.g., -0.9, 1.1, and 2.9 should all map to 0.9.

    Parameters
    ----------
    u: array-like
        The array of points to map to the unit cube

    Returns
    -------
    u: array-like
       The input array, modified in place.
    r›   r   )r\   Úmod)rf   Z	idxs_evenr'   r'   r(   Úapply_reflect•  s    ró   c             C   sX   t j| |dd}| | }t  |¡}t  |d ¡}||d |  t  d|||¡ }||fS )a•  
    Compute the weighted mean and covariance of the samples.

    Parameters
    ----------
    samples : `~numpy.ndarray` with shape (nsamples, ndim)
        2-D array containing data samples. This ordering is equivalent to
        using `rowvar=False` in `~numpy.cov`.

    weights : `~numpy.ndarray` with shape (nsamples,)
        1-D array of sample weights.

    Returns
    -------
    mean : `~numpy.ndarray` with shape (ndim,)
        Weighted sample mean vector.

    cov : `~numpy.ndarray` with shape (ndim, ndim)
        Weighted sample covariance matrix.

    Notes
    -----
    Implements the formulae found `here <https://goo.gl/emWFLR>`_.

    r   )ÚweightsrZ   r›   zi,ij,ik)r\   ZaveragerÏ   Zeinsum)r¨   rô   ÚmeanZdxZwsumZw2sumZcovr'   r'   r(   r	   ±  s    
 c       	      C   s¼   |dkrt ƒ }t |¡}t|d d ƒtkr6t d¡ ||d  }t|ƒ}| ¡ t 	|¡ | }tj
|td}d\}}x6||k r¬|| || k r¢|||< |d7 }qx|d7 }qxW | | | ¡S )aâ  
    Resample a set of points from the weighted set of inputs
    such that they all have equal weight. The points are also
    randomly shuffled.

    Each input sample appears in the output array either
    `floor(weights[i] * nsamples)` or `ceil(weights[i] * nsamples)` times,
    with `floor` or `ceil` randomly selected (weighted by proximity).

    Parameters
    ----------
    samples : `~numpy.ndarray` with shape (nsamples,)
        Set of unequally weighted samples.

    weights : `~numpy.ndarray` with shape (nsamples,)
        Corresponding weight of each sample.

    rstate : `~numpy.random.Generator`, optional
        `~numpy.random.Generator` instance.

    Returns
    -------
    equal_weight_samples : `~numpy.ndarray` with shape (nsamples,)
        New set of samples with equal weights in random order.

    Examples
    --------
    >>> x = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]])
    >>> w = np.array([0.6, 0.2, 0.15, 0.05])
    >>> utils.resample_equal(x, w)
    array([[ 1.,  1.],
           [ 1.,  1.],
           [ 1.,  1.],
           [ 3.,  3.]])

    Notes
    -----
    Implements the systematic resampling method described in `Hol, Schon, and
    Gustafsson (2006) <doi:10.1109/NSSPW.2006.4378824>`_.
   Nrˆ   g      ð?z3Weights do not sum to 1 and have been renormalized.)rÞ   )r   r   r   )rÓ   r\   ÚcumsumÚabsÚSQRTEPSr^   r_   rK   ræ   ÚarangeÚzerosr©   Zpermutation)	r¨   rô   rÒ   Zcumulative_sumZnsamplesZ	positionsÚidxÚiÚjr'   r'   r(   r   Ø  s     *



c             C   sÐ   t  | ¡} t  |¡}t  |dk ¡s0t  |dk¡r8tdƒ‚|dkrTt  | td| ƒ¡S t  |¡}t| ƒt|ƒkrvtdƒ‚t  | ¡}|| }t  |¡dd… }||d  }t  	d|¡}t  
||| | ¡ ¡ }|S dS )	a  
    Compute (weighted) quantiles from an input set of samples.

    Parameters
    ----------
    x : `~numpy.ndarray` with shape (nsamps,)
        Input samples.

    q : `~numpy.ndarray` with shape (nquantiles,)
       The list of quantiles to compute from `[0., 1.]`.

    weights : `~numpy.ndarray` with shape (nsamps,), optional
        The associated weight from each sample.

    Returns
    -------
    quantiles : `~numpy.ndarray` with shape (nquantiles,)
        The weighted sample quantiles computed at `q`.

    g        g      ð?z#Quantiles must be between 0. and 1.Ng      Y@z+Dimension mismatch: len(weights) != len(x).rˆ   r   )r\   Z
atleast_1dÚanyr·   Z
percentilerC   rK   Úargsortrö   rp   ZinterpÚtolist)rH   Úqrô   rû   ÚswZcdfZ	quantilesr'   r'   r(   r
     s     



c             C   s~   |   ¡ r| j}t|ƒ}n^| j}| j}t| jƒ}||krJtj|td| }n,||| krnt 	t 
|dd¡|¡}ntdƒ‚||fS )aš   Helper function for calculating the number of samples

    Parameters
    ----------
    res : :class:`~dynesty.results.Results` instance
        The :class:`~dynesty.results.Results` instance taken from a previous
        nested sampling run.

    Returns
    -------
    nsamps: int
        The total number of samples/iterations
    samples_n: array
        Number of live points at a given iteration

    )rÞ   r   rˆ   zTFinal number of samples differs from number of iterations and number of live points.)rÍ   r¦   rK   rx   rª   r   r\   rß   r©   Úminimumrù   r·   )rÕ   r¦   Únsampsrx   rª   r'   r'   r(   Ú_get_nsamps_samples_nM  s    

r  c       	      C   sø   t | ƒ}tj|td}g g  }}t | ¡dk |dd…< t |¡d }t |ƒdkrì|d d }|d }| | | ¡ x\|dd… D ]L}||d krœ|d7 }q€q€| ||d g¡ | | |d  ¡ |}|d }q€W | ||d f¡ t |¡}| ||fS )a“  
    Find all instances where the number of live points is either constant
    or increasing.
    Return the mask,
    the values of nlive when nlives starts to decrease
    The ranges of decreasing nlives
    v=[3,2,1,13,13,12,23,22];
    > print(dynesty.utils._find_decrease(v))
    (array([ True, False, False,  True,  True, False,  True, False]),
    [3, 13, 23],
    [[0, 3], [4, 6], (6, 8)])

    )rÞ   r   r   N)rK   r\   rú   rà   ÚdiffZnonzerorp   r]   )	r¦   r  Ú
nlive_flagÚnlive_startÚboundsÚidsZboundlÚlastZcurir'   r'   r(   Ú_find_decreaseq  s(    

r  Fc          	   C   s^  |dkrt ƒ }t| ƒ\}}| j}|r>tj|td}g g  }}nt|ƒ\}}}t |¡}	|j|| dd|	|< t	|ƒ}
xšt
|
ƒD ]Ž}|| }|| }||d |d … }|jd|d d}| ¡ }||d  }|t ||d ¡ }|dd… |dd…  }||	|d |d …< q~W t |	¡ ¡ }t||d	\}}}}|||t t |d¡¡|d
œ}t| |ƒ}|S )a™  
    Probes **statistical uncertainties** on a nested sampling run by
    explicitly generating a *realization* of the prior volume associated
    with each sample (dead point). Companion function to :meth:`resample_run`.

    Parameters
    ----------
    res : :class:`~dynesty.results.Results` instance
        The :class:`~dynesty.results.Results` instance taken from a previous
        nested sampling run.

    rstate : `~numpy.random.Generator`, optional
        `~numpy.random.Generator` instance.

    approx : bool, optional
        Whether to approximate all sets of uniform order statistics by their
        associated marginals (from the Beta distribution). Default is `False`.

    Returns
    -------
    new_res : :class:`~dynesty.results.Results` instance
        A new :class:`~dynesty.results.Results` instance with corresponding
        weights based on our "jittered" prior volume realizations.

    N)rÞ   r   )rY   Úbr   g      ð?)ri   rê   rˆ   )rQ   r   )r   r   r   r   r   )rÓ   r  rQ   r\   rß   rà   r  rú   ÚbetarK   ÚrangeZexponentialrö   rp   ÚlogÚcompute_integralsrŠ   ÚmaximumrÛ   )rÕ   rÒ   Úapproxr  r¦   rQ   r  r  r	  Zt_arrZnunifrü   Znstartr¬   ZsnZy_arrZycsumZuorderZrorderr   Úsaved_logwtÚ
saved_logzÚsaved_logzvarÚsaved_hÚ
substituteÚnew_resr'   r'   r(   r     s<    


c             C   sH  | dk	st ‚|dk	st ‚t dg| g¡}tj|dd}|| t t |¡ ¡ }|t d¡ }tj|dd }t |dd… |dd… ¡| }|dk	rž|| }tj 	|¡}|d }	t 
t |dd… |	 | ¡|dd…  t |dd… |	 | ¡|dd…   ¡}
|
|	t ||	 ¡  }tj|dd}t t 
|| ¡¡}||||fS )aG  
    Compute weights, logzs and variances using quadratic estimator.
    Returns logwt, logz, logzvar, h

    Parameters:
    -----------
    logl: array
        array of log likelihoods
    logvol: array
        array of log volumes
    reweight: array (or None)
        (optional) reweighting array to reweight posterior
    Ngœu ˆ<ä7þr   )Úprependg      à?r   rˆ   )r´   r\   Úconcatenater  Úlog1prÎ   Úmathr  Ú	logaddexpÚ
accumulaterö   r÷   )rQ   r   ÚreweightZloglstar_padÚdlogvolÚlogdvolZlogdvol2r  r  ZlogzmaxZh_part1r  Údhr  r'   r'   r(   r  û  s&     $*r  c             C   sž   t || |gddgd}t || ¡| }t ||¡}	t | |	 | ¡|  t ||	 | ¡|  }
|
t ||	 ¡||   |	 }|| }|||  }||	||fS )a  
    This is the calculation of weights and logz/var estimates one step at the
    time.
    Importantly the calculation of H is somewhat different from
    compute_integrals as incomplete integrals of H() of require knowing Z

    Return logwt, logz, logzvar, h
    g      à?g      à¿)rY   r  )r   r\   r  r  rÎ   )r   Zloglstar_newr   r   r   r!  r   r"  r   Zlogz_newZlztermZh_newr#  Zlogzvar_newr'   r'   r(   Úprogress_integration:  s    r$  c       +         sò  |dkrt ƒ }tˆ jƒ}ˆ  ¡ r8ˆ j}ˆ j}ˆ j}d}n„ˆ j}ˆ j}	||	krdt	j
|	td| }d}n0||	| krŒt	 t	 |dd¡|¡}d}ntdƒ‚t	jt|ƒtd}t	 t	j t	jfg¡}|dd…df }
t	 ˆ j¡}g }g }xH|D ]@}|ˆ j|k }t	 |
| t	j k¡r| |¡ qæ| |¡ qæW t|ƒt|ƒ }}t	 |¡t	 |¡ }}|dkr”|dkr”t	 ||jd||d ||jd||d ¡}n<|dkr´||jd||d }n|dkrÈtd	ƒ‚ntd
ƒ‚t	 tˆ jƒ¡‰t	 ‡ ‡fdd„|D ƒ¡‰tˆƒ}ˆ jˆ }t	 |¡}ˆ| ‰ˆ jˆ }|rt	j|td}t	j|dd\}}x¾t||ƒD ]¦\}}ˆ j|k}|| d }|
| }tˆ j| ƒ}|||k||k @   |7  < ||k}t	 |¡}|| } t	jt	 |¡|  td}!|!ddd… d }"||  |"7  < qZW n|ˆ }t	 t	 ||d  ¡¡}#t||#d\}$}%}&}'dtˆ jˆ ƒ t ˆ jˆ ƒ }(t!tˆ jˆ ƒˆ jˆ |(ˆ j"ˆ ˆ j#ˆ ˆ jˆ ˆ j$ˆ ˆ j%ˆ |t	 &|$¡||#t	 &|%¡t	 't	 (t	 &|&¡d¡¡t	 &|'¡d})t)|)ƒ}*|rê|*ˆfS |*S dS )aœ  
    Probes **sampling uncertainties** on a nested sampling run using bootstrap
    resampling techniques to generate a *realization* of the (expected) prior
    volume(s) associated with each sample (dead point). This effectively
    splits a nested sampling run with `K` particles (live points) into a
    series of `K` "strands" (i.e. runs with a single live point) which are then
    bootstrapped to construct a new "resampled" run. Companion function to
    :meth:`jitter_run`.

    Parameters
    ----------
    res : :class:`~dynesty.results.Results` instance
        The :class:`~dynesty.results.Results` instance taken from a previous
        nested sampling run.

    rstate : `~numpy.random.Generator`, optional
        `~numpy.random.Generator` instance.

    return_idx : bool, optional
        Whether to return the list of resampled indices used to construct
        the new run. Default is `False`.

    Returns
    -------
    new_res : :class:`~dynesty.results.Results` instance
        A new :class:`~dynesty.results.Results` instance with corresponding
        samples and weights based on our "bootstrapped" samples and
        (expected) prior volumes.

    NT)rÞ   Fr   rˆ   zTFinal number of samples differs from number of iterations and number of live points.)rê   zTThe provided `Results` does not include any points initially sampled from the prior!z=The provided `Results` does not appear to have any particles!c                s   g | ]}ˆˆ j |k ‘qS r'   )r¥   )r@   rû   )rÕ   Úsamp_idxr'   r(   rB   ²  s    z resample_run.<locals>.<listcomp>)Zreturn_countsr   g      ð?)rQ   r   g      Y@)rx   r…   r    r"   r¨   r¥   r¤   r§   r¦   r   rQ   r   r   r   r«   )*rÓ   rK   r…   rÍ   r¦   r­   rl   rª   rx   r\   rß   r©   r  rù   r·   rú   r]   r‰   Úuniquer¥   rþ   rp   rë   r  rQ   rÿ   ÚziprÈ   Zcount_nonzerorö   r  r  rÏ   r²   r"   r¨   r¤   r§   ÚasarrayrŠ   r  r®   )+rÕ   rÒ   Ú
return_idxr  r¦   r­   rl   Zadded_final_liverª   rx   Zbatch_llminr
  Zbase_idsZ	addon_idsrü   ÚsbatchÚnbaser`   Zlive_idxrM   Zidx_sortrQ   Zsamp_nZuidxsZuidxs_nZuidxZuidx_nÚselÚlowerÚupperZendselZendsel_nÚchunkZcountersZ	nlive_endr   r  r  r  r  r    Znew_res_dictr  r'   )rÕ   r%  r(   r   S  s¬     









 c          	   C   sj   |dkr| d }|| }| d }| d }t |||d\}}}}	|||t t |d¡¡|	dœ}
t| |
ƒ}|S )a  
    Reweight a given run based on a new target distribution.

    Parameters
    ----------
    res : :class:`~dynesty.results.Results` instance
        The :class:`~dynesty.results.Results` instance taken from a previous
        nested sampling run.

    logp_new : `~numpy.ndarray` with shape (nsamps,)
        New target distribution evaluated at the location of the samples.

    logp_old : `~numpy.ndarray` with shape (nsamps,)
        Old target distribution evaluated at the location of the samples.
        If not provided, the `logl` values from `res` will be used.

    Returns
    -------
    new_res : :class:`~dynesty.results.Results` instance
        A new :class:`~dynesty.results.Results` instance with corresponding
        weights based on our reweighted samples.

    NrQ   r   )rQ   r   r   r   )r   r   r   r   r   )r  r\   rŠ   r  rÛ   )rÕ   Zlogp_newZlogp_oldZlogrwtr   rQ   r  r  r  r  r  r  r'   r'   r(   r   û  s    
Tc             C   s  | j }d}yt|ƒ| j| j kr$d}W n tk
r:   Y nX t | j¡dk ¡ dkr^t	 
d¡ g }tt |¡ƒ}x–tt |¡ƒD ]‚\}}||k}t|ƒ}	| j| }
|r
|	d }t d¡ dt |¡  }|dkrö|d t d	¡ }t ||¡}nt t d	¡g¡}n|	}t d¡ dt |¡  }t|
|d
\}}}}d|	 t| j| ƒ }td|| j| || j| | j | | j| | j| | j| ||
||t |¡|d}y| j| |d< | j|d< W n tk
rÔ   Y nX | t|ƒ¡ |r‚tj d|d › d|› d¡ q‚W |S )a  
    Unravels a run with `K` live points into `K` "strands" (a nested sampling
    run with only 1 live point). **WARNING: the anciliary quantities provided
    with each unraveled "strand" are only valid if the point was initialized
    from the prior.**

    Parameters
    ----------
    res : :class:`~dynesty.results.Results` instance
        The :class:`~dynesty.results.Results` instance taken from a previous
        nested sampling run.

    print_progress : bool, optional
        Whether to output the current progress to `~sys.stderr`.
        Default is `True`.

    Returns
    -------
    new_res : list of :class:`~dynesty.results.Results` instances
        A list of new :class:`~dynesty.results.Results` instances
        for each individual strand.

    TFr   zPThe likelihood seem to have plateaus. The unraveling such runs may be inaccurater   r›   g      ð?rˆ   g      à?)rQ   r   g      Y@)rª   rx   r…   r    r¨   r¥   r¤   r§   r"   r   rQ   r   r   r   r«   r­   rl   z	Strand: ú/z     ) r¥   rK   rx   rª   ÚAttributeErrorr\   r  rQ   rÏ   r^   r_   r&  Ú	enumerater  r  rù   rp   r]   r  r…   r²   r¨   r¤   r§   r"   rŠ   r­   rl   r®   rœ   r   r¡   )rÕ   rä   ZidxsZ
added_liver  ZnstrandsÚcounterrû   Zstrandr  rQ   rx   Zlogvol_deadZlogvol_liver   r  r  r  r  r    Zrdictr'   r'   r(   r   +  sf    

"c          	   C   s  t | ƒ}d}g }g }xV| D ]N}y*t |jdk¡r<| |¡ n
| |¡ W q tk
rf   | |¡ Y qX qW t |ƒt |ƒ }}|dkr–|dkr–| }g }t |ƒdkr€xÂt |ƒdkrfg }	t |ƒ}
d}x”||
k rXy2|| ||d   }}t||dd}|	 |¡ W n$ tk
r&   |	 || ¡ Y nX |d7 }|d7 }|rÆtj	 
d|› d|› d¡ qÆW t |	¡}q¦W t|d |d d	d}n|d }t |ƒ}
xjt|ƒD ]^\}}||
d k rÀt||dd}nt||d	d}|d7 }|rštj	 
d|› d|› d¡ qšW t|ƒ}|S )
aU  
    Merges a set of runs with differing (possibly variable) numbers of
    live points into one run.

    Parameters
    ----------
    res_list : list of :class:`~dynesty.results.Results` instances
        A list of :class:`~dynesty.results.Results` instances returned from
        previous runs.

    print_progress : bool, optional
        Whether to output the current progress to `~sys.stderr`.
        Default is `True`.

    Returns
    -------
    combined_res : :class:`~dynesty.results.Results` instance
        The :class:`~dynesty.results.Results` instance for the combined run.

    r   r   r›   F)Úcompute_auxzMerge: r0  z     T)rK   r\   rþ   r­   rp   r1  Ú
_merge_twoÚ
IndexErrorrœ   r   r¡   rb   r2  Úcheck_result_static)Zres_listrä   Úntotr3  Z
rlist_baseZ	rlist_addÚrr+  r`   Z	rlist_newZnrunsrü   Úr1Úr2rÕ   r'   r'   r(   r   •  sX    
 c             C   s˜   t | ƒd }t|ƒ}| j}d}|j|kr:t ||k¡r:d}t t |dd¡|¡}|j|krlt ||k¡rld}|r”|  ¡ }||d< || |d< t	|ƒ} | S )zª If the run was from a dynamic run but had constant
    number of live points, return a new Results object with
    nlive parameter, so we could use it as static run
    r   FTr   rˆ   rª   rx   )
r  rÈ   rx   rê   r\   Úallr  rù   r»   r®   )rÕ   r¦   rª   rx   Zstandard_runZ
nlive_testZresdictr'   r'   r(   r7  ë  s    r7  Újitterc       
      C   s”   | j | jd  }|dkr(t| ||d}n,|dkrLt| |dd\}}|| }ntdƒ‚|d |d	 d  }t t |¡||  ¡}	|rŒ|	|fS |	S d
S )a½  
    Computes the `Kullback-Leibler (KL) divergence
    <https://en.wikipedia.org/wiki/Kullback-Leibler_divergence>`_ *from* the
    discrete probability distribution defined by `res` *to* the discrete
    probability distribution defined by a **realization** of `res`.

    Parameters
    ----------
    res : :class:`~dynesty.results.Results` instance
        :class:`~dynesty.results.Results` instance for the distribution we
        are computing the KL divergence *from*.

    error : {`'jitter'`, `'resample'`}, optional
        The error method employed, corresponding to :meth:`jitter_run` or
        :meth:`resample_run`. Default is `'jitter'`.

    rstate : `~numpy.random.Generator`, optional
        `~numpy.random.Generator` instance.

    return_new : bool, optional
        Whether to return the realization of the run used to compute the
        KL divergence. Default is `False`.

    approx : bool, optional
        Whether to approximate all sets of uniform order statistics by their
        associated marginals (from the Beta distribution). Default is `False`.

    Returns
    -------
    kld : `~numpy.ndarray` with shape (nsamps,)
        The cumulative KL divergence defined *from* `res` *to* a
        random realization of `res`.

    new_res : :class:`~dynesty.results.Results` instance, optional
        The :class:`~dynesty.results.Results` instance corresponding to
        the random realization we computed the KL divergence *to*.

    rˆ   r=  )rÒ   r  ÚresampleT)rÒ   r)  z.Input `'error'` option '{error}' is not valid.r   r   N)r   r   r   r   r·   r\   rö   rÎ   )
rÕ   ÚerrorrÒ   Ú
return_newr  Zlogp2r  r%  Zlogp1Úkldr'   r'   r(   r     s    -
c       (         s  t | j| j| j| j| j| j| jd}t|d ƒ}|  	¡ r@| j
}nV| j| j }}||krjtj|td| }n,||| krŽt t |dd¡|¡}ntdƒ‚|  	¡ sªd|  ¡ krÀ| j|d< | j|d	< n,tj|td|d< t tj tjfg¡|d	< t |j|j|j|j|j|j|jd}t|d ƒ}	| 	¡ r.|j
}
nZ|j|j }}|	|krZtj|td| }
n.|	|| kr€t t |	dd¡|¡}
ntd
ƒ‚| 	¡ s d| ¡ kr¶|j|d< |j|d	< n,tj|	td|d< t tj tjfg¡|d	< t g g g g g g g g g g g g g g d‰t |d	 |d	 k¡r,|d	 }d}n"t |d	 |d	 f¡}t|d	 ƒ}d\}}|d | |d |  }}|| |
|  }}||	 }t |d	 |d  ¡}t |d	 |d  ¡}xJt|ƒD ]<}||kræ||kræ|| }n||krö|}n|}||kr,|}|}|d7 }ˆd  |d | ¡ n*|}|}|d7 }ˆd  |d | | ¡ x$dD ]}ˆ|  || | ¡ q\W ˆd  |¡ y|d | }|| }W n  tk
rÂ   tj}d}Y nX y|d | }|
| }W n  tk
rü   tj}d}Y nX qÂW d}d}d}d}t ˆd ¡}t ˆd ¡}xÈtt ||ƒƒD ]¶\}\} }|s’||d… | k}!|! !¡ }"|"dkr’|"}|t "d|d  ¡ }d}|s°|t# "|d | ¡8 }n|t $t %|| ¡ ¡ }ˆd  |¡ |r@|d8 }|dkr@d}q@W d| t!ˆd ƒ }#t |t &ˆd ¡|#t &ˆd ¡t &ˆd ¡t &ˆd ¡t &|¡t &ˆd ¡d}$x$dD ]}t &ˆ| ¡|$d| < qdW |rt'|$d |$d d\|$d< |$d< }%|$d < t (t )|%d¡¡|$d!< t &ˆd ¡‰ ‡ ‡fd"d#„t *ˆd ¡D ƒ}&tj|&td|$d$< t+|$ƒ}'|'S )%a7  
    Internal method used to merges two runs with differing (possibly variable)
    numbers of live points into one run.

    Parameters
    ----------
    res1 : :class:`~dynesty.results.Results` instance
        The "base" nested sampling run.

    res2 : :class:`~dynesty.results.Results` instance
        The "new" nested sampling run.

    compute_aux : bool, optional
        Whether to compute auxiliary quantities (evidences, etc.) associated
        with a given run. **WARNING: these are only valid if `res1` or `res2`
        was initialized from the prior *and* their sampling bounds overlap.**
        Default is `False`.

    Returns
    -------
    res : :class:`~dynesty.results.Results` instances
        :class:`~dynesty.results.Results` instance from the newly combined
        nested sampling run.

    )re   rf   r&   rQ   r   rg   r"   re   )rÞ   r   rˆ   z^Final number of samples differs from number of iterations and number of live points in `res1`.rl   rj   r	  z^Final number of samples differs from number of iterations and number of live points in `res2`.)re   rf   r&   rQ   r   r   r   r   r   r   rg   rh   rj   r"   )r   r   rQ   r   rh   Fg        Ng      ð?Tr   g      Y@r   r&   r"   )rx   r…   r    r¨   rQ   r   rl   r"   )re   rg   rh   rf   rj   Zsamples_)r   rQ   r   r   r«   r   c                s&   g | ]}t t ˆ ˆd  |k ¡ƒ‘qS )rj   )rK   r\   r&  )r@   rü   )Úcombined_idÚcombined_infor'   r(   rB   5  s   z_merge_two.<locals>.<listcomp>rk   ),r²   r¥   r§   r¨   rQ   r…   r¤   r"   rK   rÍ   r¦   rx   rª   r\   rß   r©   r  rù   r·   rn   r­   rl   rú   r]   r‰   r<  r  rñ   r  rp   r6  r2  r'  rÏ   r  r  r  rÎ   r(  r  rŠ   r  r&  r®   )(Zres1Zres2r4  Z	base_infor+  Zbase_nrx   rª   Znew_infoZnnewZnew_nr	  ZboffsetZidx_baseZidx_newZlogl_bZlogl_nZnlive_bZnlive_nr8  Zllmin_bZllmin_nrü   Zadd_idxZfrom_runZcurkZplateau_modeZplateau_counterZplateau_logdvolr   Z
logl_arrayZnlive_arrayZcurlZplateau_maskZnplateaur    r9  Zcombined_logzvarrk   rÕ   r'   )rB  rC  r(   r5  L  s   














 r5  c             C   s&   | \}}}}t |ƒ}t|||d|dS )zb Internal `pool.map`-friendly wrapper for :meth:`kld_error`
    used by :meth:`stopping_function`.T)rÒ   r@  r  )rÓ   r   )Úargsr„   r?  r  ZrseedrÒ   r'   r'   r(   Ú
_kld_errorB  s    rE  c          	      s0  t  ¡  t  d¡ t  dt¡ W dQ R X |dkr6i }|dkrBt}| dd¡}d|  krbdkstn td|› dƒ‚| d	d
¡}|dk r¦|dk r¦td|› d|› dƒ‚| dd¡}|dkrØ|dk rØtd|› d|› dƒ‚| dd¡}|dkrütd|› dƒ‚|dk rt  d¡ | dd¡‰ˆdkr6tdˆ› dƒ‚| dd¡‰ ‡fdd „t|ƒD ƒ}	‡fd!d „t|ƒD ƒ}
‡ fd"d „t|ƒD ƒ}t	||ƒ}t
|	|
||ƒ}t|t|ƒƒ}t d#d „ |D ƒ¡j\}}t |¡}|| }t |¡t |¡ }}|| | }|| d| |  }|r$|dk|||ffS |dkS dS )$av  
    The old stopping function utilized by :class:`DynamicSampler`.
    Zipped parameters are passed to the function via :data:`args`.
    Assigns the run a stopping value based on a weighted average of the
    stopping values for the posterior and evidence::
        stop = pfrac * stop_post + (1.- pfrac) * stop_evid
    The evidence stopping value is based on the estimated evidence error
    (i.e. standard deviation) relative to a given threshold::
        stop_evid = evid_std / evid_thresh
    The posterior stopping value is based on the fractional error (i.e.
    standard deviation / mean) in the Kullback-Leibler (KL) divergence
    relative to a given threshold::
        stop_post = (kld_std / kld_mean) / post_thresh
    Estimates of the mean and standard deviation are computed using `n_mc`
    realizations of the input using a provided `'error'` keyword (either
    `'jitter'` or `'resample'`).
    Returns the boolean `stop <= 1`. If `True`, the :class:`DynamicSampler`
    will stop adding new samples to our results.
    Parameters
    ----------
    results : :class:`Results` instance
        :class:`Results` instance.
    args : dictionary of keyword arguments, optional
        Arguments used to set the stopping values. Default values are
        `pfrac = 1.0`, `evid_thresh = 0.1`, `post_thresh = 0.02`,
        `n_mc = 128`, `error = 'jitter'`, and `approx = True`.
    rstate : `~numpy.random.Generator`, optional
        `~numpy.random.Generator` instance.
    M : `map` function, optional
        An alias to a `map`-like function. This allows users to pass
        functions from pools (e.g., `pool.map`) to compute realizations in
        parallel. By default the standard `map` function is used.
    return_vals : bool, optional
        Whether to return the stopping value (and its components). Default
        is `False`.
    Returns
    -------
    stop_flag : bool
        Boolean flag indicating whether we have passed the desired stopping
        criteria.
    stop_vals : tuple of shape (3,), optional
        The individual stopping values `(stop_post, stop_evid, stop)` used
        to determine the stopping criteria.
    ÚoncezEThis an old stopping function that will be removed in future releasesNÚpfracg      ð?g        zThe provided `pfrac` z is not between 0. and 1.Úevid_threshgš™™™™™¹?zThe provided `evid_thresh` z, is not non-negative even though `pfrac` is Ú.Úpost_threshg{®Gáz”?zThe provided `post_thresh` Ún_mcé€   r   zThe number of realizations z must be greater than 1.é   z`Using a small number of realizations might result in excessively noisy stopping value estimates.r?  r=  >   r=  r>  zThe chosen `'error'` option z is not valid.r  Tc                s   g | ]}ˆ ‘qS r'   r'   )r@   rü   )r„   r'   r(   rB   ©  s    z)old_stopping_function.<locals>.<listcomp>c                s   g | ]}ˆ ‘qS r'   r'   )r@   rü   )r?  r'   r(   rB   ª  s    c                s   g | ]}ˆ ‘qS r'   r'   )r@   rü   )r  r'   r(   rB   «  s    c             S   s"   g | ]\}}|d  |j d  f‘qS )rˆ   )r   )r@   rA  rÕ   r'   r'   r(   rB   ¯  s   )r^   Úcatch_warningsÚfilterwarningsr_   ÚDeprecationWarningrD   Úgetr·   r  rî   r'  rC   rE  r\   r]   ÚTZstdrõ   )r„   rD  rÒ   ÚMZreturn_valsrG  rH  rJ  rK  ZrlistZ
error_listZapprox_listrí   ÚoutputsZkld_arrZlnz_arrZlnz_stdZ	stop_evidZkld_meanZkld_stdZ	stop_postÚstopr'   )r  r?  r„   r(   Úold_stopping_functionP  s\    2







rV  c          	   C   sÒ   t | dƒ}t |¡}W dQ R X |d }|d }d}|d }||krLtdƒ‚|tkrft d|› d	¡ |dk	rv|j}nt}t|dƒr¦||j	g}	|j
dk	r¬|	 |j
¡ n|g}	x |	D ]}
||
_||
_||
j_q²W |S )
aö  
    Restore the dynamic sampler from a file.
    It is assumed that the file was created using .save() method
    of DynamicNestedSampler or as a result of checkpointing during
    run_nested()

    Parameters
    ----------
    fname: string
        Filename of the save file.
    pool: object(optional)
        The multiprocessing pool-like object that supports map()
        calls that will be used in the restored object.

    Returns
    -------
    Static or dynamic nested sampling object

    ÚrbNÚsamplerÚversionr   Úformat_versionzIncorrect format versionz,The dynesty version in the checkpoint file (z`)does not match the current dynesty version({DYNESTY_VERSION}). That is *NOT* guaranteed to work)ÚopenÚpickle_moduleÚloadrS   ÚDYNESTY_VERSIONr^   r_   rD   rŸ   rX  Zbatch_samplerrp   rS  r7   r6   )Úfnamer7   rX   rÕ   rX  Zsave_verZdynesty_format_versionZfile_format_versionZmapperZsamplersZcursampr'   r'   r(   Úrestore_samplerÃ  s0    
	


r`  c          	   C   sz   d}| t |dœ}|d }y2t|dƒ}t ||¡ W dQ R X t ||¡ W n*   yt |¡ W n   Y nX ‚ Y nX dS )zË
    Save the state of the dynamic sampler in a file

    Parameters
    ----------
    sampler: object
        Dynamic or Static nested sampler
    fname: string
        Filename of the save file.

    r   )rX  rY  rZ  z.tmpÚwbN)r^  r[  r\  ÚdumpÚosÚrenameÚunlink)rX  r_  rZ  rm   Z	tmp_fnamerX   r'   r'   r(   Úsave_samplerþ  s    rf  )N)N)N)N)NF)NNN)NF)N)T)T)r=  NFF)F)NNNF)N)Lr5   rœ   r^   r  rb   rt   rc  r    Úcollectionsr   Ú	functoolsr   Úpickler\  Únumpyr\   Zscipy.specialr   Ú_versionr   r^  rã   ÚImportErrorrR   Ú__all__rŠ   r*   ZfinfoZfloat64Zepsrø   r   r#   Z	_LOWL_VALr   r   r   r   rw   r‰   r‡   rŽ   rƒ   r‚   rØ   r®   rÚ   r   rÛ   r   râ   rå   rÓ   rî   rð   r   ró   r	   r   r
   r  r  r   r  r$  r   r   r   r   r7  r   r5  rE  rV  r`  rf  r'   r'   r'   r(   Ú<module>   s  





? ="R;( $"
	

'
F
/$,
^
?
 )
0
j
V   
@
 w   
o
;