B
    zdn                  @   s`   d Z ddlZddlZddlmZmZ ddlmZ ddlm	Z	m
Z
 ddlmZ G dd	 d	eZdS )
z,Classes for parallel tempered Markov chains.    N)create_bit_generators
array2dict)ParallelTemperedChain)	ChainDatadetect_dtypes   )BaseSamplerc               @   s   e Zd ZdZdddZdddZedd	 Zed
d Zedd Z	edd Z
e
jdd Z
dd ZdddZedd Zedd ZdS )ParallelTemperedSamplera\  Evolves a collection of parallel tempered Markov chains.

    Parameters
    ----------
    parameters : tuple or list
        Names of the parameters to sample.
    model : object
        Model object.
    nchains : int
        The number of chains to create per temperature. Must be greater than
        zero.
    betas : numpy.ndarray of floats
        The betas (= 1 / temperatures) to use. All betas must be between [0,1].
        Must provide at least one. If one is not included in the betas, a
        warning will be printed.
    swap_interval : int, optional
        How often to calculate temperature swaps. Default is 1 (= swap on every
        iteration).
    proposals : list, optional
        List of proposals to use. Any parameters that do not have a proposal
        provided will use the ``default_propsal``.
    default_proposal : an epsie.Proposal class, optional
        The default proposal to use for parameters not in ``proposals``.
        Default is :py:class:`epsie.proposals.Normal`.
    default_proposal_args : dict, optional
        Dictionary of arguments to pass to the default proposal.
    seed : int, optional
        Seed for the random number generator. If None provided, will create
        one.
    pool : Pool object, optional
        Specify a process pool to use for parallelization. Default is to use a
        single core.
    r   Nc             C   sd   || _ || _| |||	 |
| _|| _t|ttfr:|g}t|tj	sPt
|}| |||| d S )N)
parametersmodelZset_proposalsseedpool
isinstancefloatintnumpyZndarrayarraycreate_chains)selfr
   r   nchainsbetasswap_interval	proposalsadaptive_annealerZdefault_proposalZdefault_proposal_argsr   r    r   e/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/epsie/samplers/ptsampler.py__init__@   s    
z ParallelTemperedSampler.__init__c                s@   |dk rt dt|jd} fddt|D _dS )aP  Creates a list of :py:class:`chain.ParallelTemperedChain`.

        Parameters
        ----------
        nchains : int
            The number of parallel tempered chains to create.
        betas : array
            Array of inverse temperatures to use for each parallel tempered
            chain.
        swap_interval : int, optional
            How often to calculate temperature swaps. Default is 1 (= swap on
            every iteration).
        adaptive_annealer : object, optional
            Adaptive anneler adjusting temperatures on the go.
            Default is `None`.
        r   znchains must be >= 1)r   c                s8   g | ]0\}}t jjd d jD  ||dqS )c             S   s   g | ]}t |qS r   )copydeepcopy).0pr   r   r   
<listcomp>j   s    zDParallelTemperedSampler.create_chains.<locals>.<listcomp>.<listcomp>)r   r   r   Zbit_generatorZchain_id)r   r
   r   r   )r   Zcidbg)r   r   r   r   r   r   r!   h   s   z9ParallelTemperedSampler.create_chains.<locals>.<listcomp>N)
ValueErrorr   r   	enumerateZ_chains)r   r   r   r   r   Zbitgensr   )r   r   r   r   r   r   R   s
    z%ParallelTemperedSampler.create_chainsc                s   t  fddt jD S )zThe betas used for each chain. Shape is (nchains, ntemps).
        If temperatures are being dynamically adjusted each chain will
        have a different set of temperatures.
        c                s   g | ]} j | jqS r   )chainsr   )r   i)r   r   r   r!   v   s    z1ParallelTemperedSampler.betas.<locals>.<listcomp>)r   r   ranger   )r   r   )r   r   r   p   s    zParallelTemperedSampler.betasc             C   s   | j jd S )z(Returns the number of temperatures used.r   )r   shape)r   r   r   r   ntempsx   s    zParallelTemperedSampler.ntempsc             C   s
   d| j  S )z1The temperatures used. Shape is (nchains, ntemps)g      ?)r   )r   r   r   r   temperatures}   s    z$ParallelTemperedSampler.temperaturesc             C   s   | j d jS )z6Returns the swap interval used for parallel tempering.r   )r%   r   )r   r   r   r   r      s    z%ParallelTemperedSampler.swap_intervalc             C   s   x| j D ]
}||_qW dS )zSets the swap interval to use.N)r%   r   )r   intervalcr   r   r   r      s    c             C   sj   t | jd |}tt| t|| jd}|| j x$t	| jD ]\}}t ||||< qDW t
|jjS )a:  Concatenates dictionary attributes over all of the chains.

        This is a convenience function used by properties such as
        ``current_positions`` to gather all of the dictionary attributes from
        the chains.

        Parameters
        ----------
        attr : str
            The name of the attribute to get from the chains. The attribute
            is assumed to return a dictionary.

        Returns
        -------
        dict :
            Dictionary mapping parameters to arrays. The arrays have shape
            ``ntemps x nchains``.
        r   )Zdtypesr)   )getattrr%   r   listkeysr   r)   extendr   r$   r   dataT)r   attrdoutiichainr   r   r   _concatenate_dicts   s    
z*ParallelTemperedSampler._concatenate_dictsc                sJ   dkr"t t fdd| j}nt t fdd| j}tj|ddS )a  Concatenates the given attribute over all of the chains.

        This is a convenience function used by properties such as ``positions``
        to gather all of the array attributes from the chains.

        Parameters
        ----------
        attr : str
            The name of the attribute to get from the chains. The attribute
            is assumed to return a (structred) array.
        item : str or array index, optional
            Get a particular item from the (structred) array from each chain
            before concatenating.

        Returns
        -------
        array :
            The returned array has shape ``ntemps x nchains x niterations``.
        Nc                s
   t |  S )N)r-   )x)r3   r   r   <lambda>       z=ParallelTemperedSampler._concatenate_arrays.<locals>.<lambda>c                s   t |   S )N)r-   )r9   )r3   itemr   r   r:      r;   r   )Zaxis)r.   mapr%   r   stack)r   r3   r<   Zarrsr   )r3   r<   r   _concatenate_arrays   s    z+ParallelTemperedSampler._concatenate_arraysc             C   s   | j dkrdS | dS )zThe history of the temperature acceptance from all of the chains.

        If ntemps is 1, just returns None.

        .. note::
           This does not return a structured array, since there is only
           one field.
        r   Ntemperature_acceptance)r)   r?   )r   r   r   r   r@      s    

z.ParallelTemperedSampler.temperature_acceptancec             C   s   | j dkrdS | dS )zThe history of all the temperature swaps from all of the chains.

        If ntemps is 1, just returns None.

        .. note::
           This does not return a structured array, since there is only
           one field.
        r   Ntemperature_swaps)r)   r?   )r   r   r   r   rA      s    

z)ParallelTemperedSampler.temperature_swaps)r   NNNNNN)r   N)N)__name__
__module____qualname____doc__r   r   propertyr   r)   r*   r   setterr8   r?   r@   rA   r   r   r   r   r	      s   !  
 

r	   )rE   r   r   Zepsier   r   Zepsie.chainr   Zepsie.chain.chaindatar   r   baser   r	   r   r   r   r   <module>   s   