U
    ©Ê¹jä  ã                   @   sV   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	 dgZ
G dd„ deƒZdS )zÍ
This closely follows the implementation in NumPyro (https://github.com/pyro-ppl/numpyro).

Original copyright notice:

# Copyright: Contributors to the Pyro project.
# SPDX-License-Identifier: Apache-2.0
é    N)ÚBetaÚconstraints)ÚDistribution)Úbroadcast_allÚLKJCholeskyc                       sX   e Zd ZdZdejiZejZd‡ fdd„	Z	d‡ fdd„	Z
e ¡ fd	d
„Zdd„ Z‡  ZS )r   a(  
    LKJ distribution for lower Cholesky factor of correlation matrices.
    The distribution is controlled by ``concentration`` parameter :math:`\eta`
    to make the probability of the correlation matrix :math:`M` generated from
    a Cholesky factor proportional to :math:`\det(M)^{\eta - 1}`. Because of that,
    when ``concentration == 1``, we have a uniform distribution over Cholesky
    factors of correlation matrices::

        L ~ LKJCholesky(dim, concentration)
        X = L @ L' ~ LKJCorr(dim, concentration)

    Note that this distribution samples the
    Cholesky factor of correlation matrices and not the correlation matrices
    themselves and thereby differs slightly from the derivations in [1] for
    the `LKJCorr` distribution. For sampling, this uses the Onion method from
    [1] Section 3.

    Example::

        >>> # xdoctest: +IGNORE_WANT("non-deterinistic")
        >>> l = LKJCholesky(3, 0.5)
        >>> l.sample()  # l @ l.T is a sample of a correlation 3x3 matrix
        tensor([[ 1.0000,  0.0000,  0.0000],
                [ 0.3516,  0.9361,  0.0000],
                [-0.1899,  0.4748,  0.8593]])

    Args:
        dimension (dim): dimension of the matrices
        concentration (float or Tensor): concentration/shape parameter of the
            distribution (often referred to as eta)

    **References**

    [1] `Generating random correlation matrices based on vines and extended onion method` (2009),
    Daniel Lewandowski, Dorota Kurowicka, Harry Joe.
    Journal of Multivariate Analysis. 100. 10.1016/j.jmva.2009.04.008
    Úconcentrationç      ð?Nc           
         sÂ   |dk rt d|› d�ƒ‚|| _t|ƒ\| _| j ¡ }t ||f¡}| jd| jd   }tj| jd | jj| jj	d�}t 
| d¡|g¡}|d }| d¡d|  }	t||	ƒ| _tƒ  |||¡ d S )	Né   zDExpected dim to be an integer greater than or equal to 2. Found dim=Ú.ç      à?é   ©ÚdtypeÚdevice)r   éÿÿÿÿ)Ú
ValueErrorÚdimr   r   ÚsizeÚtorchÚSizeÚaranger   r   ÚcatZ	new_zerosÚ	unsqueezer   Ú_betaÚsuperÚ__init__)
Úselfr   r   Úvalidate_argsÚbatch_shapeÚevent_shapeZmarginal_concÚoffsetZ
beta_conc1Z
beta_conc0©Ú	__class__© ú_/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributions/lkj_cholesky.pyr   =   s&    
ÿ
ýzLKJCholesky.__init__c                    sf   |   t|¡}t |¡}| j|_| j |¡|_| j || jf ¡|_tt|ƒj	|| j
dd� | j|_|S )NF)r   )Z_get_checked_instancer   r   r   r   r   Úexpandr   r   r   r   Ú_validate_args)r   r   Z	_instanceÚnewr!   r#   r$   r%   S   s    

  ÿzLKJCholesky.expandc                 C   s®   | j  |¡ d¡}tj|  |¡|j|jd� d¡}||j	ddd� }|ddd d …f  
d¡ t |¡| }t |j¡j}tjdtj|d	 dd
� |d� ¡ }|t |¡7 }|S )Nr   r   T)r   Zkeepdim.r   g        r   r	   ©r   )Úmin)r   Úsampler   r   ZrandnZ_extended_shaper   r   ZtrilZnormZfill_ÚsqrtZfinfoZtinyÚclampÚsumZ
diag_embed)r   Zsample_shapeÚyZu_normalZu_hypersphereÚwÚepsÚ
diag_elemsr#   r#   r$   r*   _   s      ÿþ$zLKJCholesky.samplec                 C   sÖ   | j r|  |¡ |jddd�ddd …f }tjd| jd | jjd�}d| jd  d¡ | j | }tj	|| 
¡  dd�}| jd }| jd	|  }t |¡| }t |d	 |¡}d	| t 
tj¡ }	|	| | }
||
 S )
Nr   éþÿÿÿ)Zdim1Zdim2.r   r	   )r   r(   r   )r&   Z_validate_sampleZdiagonalr   r   r   r   r   r   r-   ÚlogÚlgammaZmvlgammaÚmathÚpi)r   Úvaluer1   ÚorderZunnormalized_log_pdfZdm1ÚalphaÚdenominatorÚ	numeratorZpi_constantZnormalize_termr#   r#   r$   Úlog_probt   s    


zLKJCholesky.log_prob)r   N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ZpositiveZarg_constraintsZcorr_choleskyZsupportr   r%   r   r   r*   r<   Ú__classcell__r#   r#   r!   r$   r      s   %
)r@   r5   r   Ztorch.distributionsr   r   Z torch.distributions.distributionr   Ztorch.distributions.utilsr   Ú__all__r   r#   r#   r#   r$   Ú<module>   s   	