a
    MSic                     @   sP   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	 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)constraintsBeta)Distribution)broadcast_allc                       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 )LKJCholeskya  
    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 propotional to :math:`\det(M)^{\eta - 1}`. Because of that,
    when ``concentration == 1``, we have a uniform distribution over Cholesky
    factors of correlation matrices. 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.

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

    Example::

        >>> 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`,
    Daniel Lewandowski, Dorota Kurowicka, Harry Joe.
    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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   cat	new_zeros	unsqueezer   _betasuperr   __init__)
selfr   r   validate_argsbatch_shapeevent_shapeZmarginal_concoffsetZ
beta_conc1Z
beta_conc0	__class__ \/var/www/html/django/DPS/env/lib/python3.9/site-packages/torch/distributions/lkj_cholesky.pyr   7   s    
zLKJCholesky.__init__c                    sf   |  t|}t|}| j|_| j||_| j|| jf |_tt|j	|| j
dd | j|_|S )NF)r   )_get_checked_instancer   r   r   r   r   expandr   r   r   r    _validate_args)r   r   	_instancenewr"   r$   r%   r'   G   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   keepdim.r   g        r   r	   r   )min)r   sampler   r   randn_extended_shaper   r   trilnormfill_sqrtfinfotinyclampsum
diag_embed)r   sample_shapeyZu_normalZu_hypersphereweps
diag_elemsr$   r$   r%   r.   Q   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   )dim1dim2.r   r	   )r   r,   r   )r(   _validate_samplediagonalr   r   r   r   r   r   r8   loglgammamvlgammamathpi)r   valuer>   orderZunnormalized_log_pdfZdm1alphadenominator	numeratorZpi_constantnormalize_termr$   r$   r%   log_probf   s    


zLKJCholesky.log_prob)r   N)N)__name__
__module____qualname____doc__r   positivearg_constraintscorr_choleskysupportr   r'   r   r   r.   rO   __classcell__r$   r$   r"   r%   r      s   !

r   )rS   rG   r   Ztorch.distributionsr   r    torch.distributions.distributionr   torch.distributions.utilsr   r   r$   r$   r$   r%   <module>   s   	