U
    ©Ê¹jú)  ã                   @   sj   d dl Z d dlZd dlmZ d dlmZ d dlmZmZ dgZ	dd„ Z
dd	„ Zd
d„ ZG dd„ deƒZdS )é    N)Úconstraints)ÚDistribution)Ú_standard_normalÚlazy_propertyÚMultivariateNormalc                 C   s   t  | | d¡¡ d¡S )a»  
    Performs a batched matrix-vector product, with compatible but different batch shapes.

    This function takes as input `bmat`, containing :math:`n \times n` matrices, and
    `bvec`, containing length :math:`n` vectors.

    Both `bmat` and `bvec` may have any number of leading dimensions, which correspond
    to a batch shape. They are not necessarily assumed to have the same batch shape,
    just ones which can be broadcasted.
    éÿÿÿÿ)ÚtorchÚmatmulZ	unsqueezeZsqueeze)ZbmatZbvec© r
   úf/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/distributions/multivariate_normal.pyÚ	_batch_mv   s    r   c                 C   s�  |  d¡}|jdd… }t|ƒ}|  ¡ d }|| }|| }|d|  }|jd|… }	t| jdd… |j|d… ƒD ]\}
}|	||
 |
f7 }	qt|	|f7 }	| |	¡}tt|ƒƒtt||dƒƒ tt|d |dƒƒ |g }| |¡}|  d||¡}| d|  d¡|¡}| ddd¡}t	j
j||dd� d¡ d¡}| ¡ }| |jdd… ¡}tt|ƒƒ}t|ƒD ]}||| || g7 }�q`| |¡}| |¡S )	aK  
    Computes the squared Mahalanobis distance :math:`\mathbf{x}^\top\mathbf{M}^{-1}\mathbf{x}`
    for a factored :math:`\mathbf{M} = \mathbf{L}\mathbf{L}^\top`.

    Accepts batches for both bL and bx. They are not necessarily assumed to have the same batch
    shape, but `bL` one should be able to broadcasted to `bx` one.
    r   Né   éþÿÿÿé   r   F©Úupper)ÚsizeÚshapeÚlenÚdimÚzipZreshapeÚlistÚrangeZpermuter   ÚlinalgÚsolve_triangularÚpowÚsumÚt)ZbLZbxÚnZbx_batch_shapeZbx_batch_dimsZbL_batch_dimsZouter_batch_dimsZold_batch_dimsZnew_batch_dimsZbx_new_shapeZsLÚsxZpermute_dimsZflat_LZflat_xZflat_x_swapZM_swapÚMZ
permuted_MZpermute_inv_dimsÚiZ
reshaped_Mr
   r
   r   Ú_batch_mahalanobis   sB    
&


ÿþýÿ
ÿ
r"   c                 C   sZ   t j t  | d¡¡}t  t  |d¡dd¡}t j| jd | j| jd�}t jj	||dd�}|S )N)r   r   r   r   ©ÚdtypeÚdeviceFr   )
r   r   ÚcholeskyÚflipZ	transposeÚeyer   r$   r%   r   )ÚPZLfZL_invZIdÚLr
   r
   r   Ú_precision_to_scale_trilK   s
    r+   c                       s¸   e Zd ZdZejejejejdœZejZ	dZ
d‡ fdd„	Zd‡ fdd„	Zed	d
„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZe ¡ fdd„Zdd„ Zdd„ Z‡  ZS )r   a™  
    Creates a multivariate normal (also called Gaussian) distribution
    parameterized by a mean vector and a covariance matrix.

    The multivariate normal distribution can be parameterized either
    in terms of a positive definite covariance matrix :math:`\mathbf{\Sigma}`
    or a positive definite precision matrix :math:`\mathbf{\Sigma}^{-1}`
    or a lower-triangular matrix :math:`\mathbf{L}` with positive-valued
    diagonal entries, such that
    :math:`\mathbf{\Sigma} = \mathbf{L}\mathbf{L}^\top`. This triangular matrix
    can be obtained via e.g. Cholesky decomposition of the covariance.

    Example:

        >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_LAPACK)
        >>> # xdoctest: +IGNORE_WANT("non-deterministic")
        >>> m = MultivariateNormal(torch.zeros(2), torch.eye(2))
        >>> m.sample()  # normally distributed with mean=`[0,0]` and covariance_matrix=`I`
        tensor([-0.2102, -0.5429])

    Args:
        loc (Tensor): mean of the distribution
        covariance_matrix (Tensor): positive-definite covariance matrix
        precision_matrix (Tensor): positive-definite precision matrix
        scale_tril (Tensor): lower-triangular factor of covariance, with positive-valued diagonal

    Note:
        Only one of :attr:`covariance_matrix` or :attr:`precision_matrix` or
        :attr:`scale_tril` can be specified.

        Using :attr:`scale_tril` will be more efficient: all computations internally
        are based on :attr:`scale_tril`. If :attr:`covariance_matrix` or
        :attr:`precision_matrix` is passed instead, it is only used to compute
        the corresponding lower triangular matrices using a Cholesky decomposition.
    )ÚlocÚcovariance_matrixÚprecision_matrixÚ
scale_trilTNc                    s„  |  ¡ dk rtdƒ‚|d k	|d k	 |d k	 dkr8tdƒ‚|d k	r†|  ¡ dk rTtdƒ‚t |jd d… |jd d… ¡}| |d ¡| _n’|d k	rÔ|  ¡ dk r¢td	ƒ‚t |jd d… |jd d… ¡}| |d ¡| _nD|  ¡ dk rètd
ƒ‚t |jd d… |jd d… ¡}| |d ¡| _| |d ¡| _	| j	jdd … }t
ƒ j|||d� |d k	�r\|| _n$|d k	�rvtj |¡| _n
t|ƒ| _d S )Nr   z%loc must be at least one-dimensional.zTExactly one of covariance_matrix or precision_matrix or scale_tril may be specified.r   zZscale_tril matrix must be at least two-dimensional, with optional leading batch dimensionsr   r   )r   r   zZcovariance_matrix must be at least two-dimensional, with optional leading batch dimensionszYprecision_matrix must be at least two-dimensional, with optional leading batch dimensions)r   ©Úvalidate_args)r   Ú
ValueErrorr   Zbroadcast_shapesr   Úexpandr/   r-   r.   r,   ÚsuperÚ__init__Ú_unbroadcasted_scale_trilr   r&   r+   )Úselfr,   r-   r.   r/   r1   Úbatch_shapeÚevent_shape©Ú	__class__r
   r   r5   �   sX    ÿþÿÿ ÿ ÿÿ ÿ

zMultivariateNormal.__init__c                    s²   |   t|¡}t |¡}|| j }|| j | j }| j |¡|_| j|_d| jkr^| j	 |¡|_	d| jkrv| j
 |¡|_
d| jkrŽ| j |¡|_tt|ƒj|| jdd� | j|_|S )Nr-   r/   r.   Fr0   )Z_get_checked_instancer   r   ÚSizer9   r,   r3   r6   Ú__dict__r-   r/   r.   r4   r5   Ú_validate_args)r7   r8   Z	_instanceÚnewZ	loc_shapeZ	cov_shaper:   r
   r   r3   º   s&    





  ÿzMultivariateNormal.expandc                 C   s   | j  | j| j | j ¡S ©N)r6   r3   Ú_batch_shapeÚ_event_shape©r7   r
   r
   r   r/   Í   s    ÿzMultivariateNormal.scale_trilc                 C   s&   t  | j| jj¡ | j| j | j ¡S r@   )r   r	   r6   ZmTr3   rA   rB   rC   r
   r
   r   r-   Ó   s     ÿþz$MultivariateNormal.covariance_matrixc                 C   s    t  | j¡ | j| j | j ¡S r@   )r   Zcholesky_inverser6   r3   rA   rB   rC   r
   r
   r   r.   Ù   s    ÿz#MultivariateNormal.precision_matrixc                 C   s   | j S r@   ©r,   rC   r
   r
   r   Úmeanß   s    zMultivariateNormal.meanc                 C   s   | j S r@   rD   rC   r
   r
   r   Úmodeã   s    zMultivariateNormal.modec                 C   s    | j  d¡ d¡ | j| j ¡S )Nr   r   )r6   r   r   r3   rA   rB   rC   r
   r
   r   Úvarianceç   s    ÿ
þÿzMultivariateNormal.variancec                 C   s2   |   |¡}t|| jj| jjd�}| jt| j|ƒ S )Nr#   )Z_extended_shaper   r,   r$   r%   r   r6   )r7   Zsample_shaper   Úepsr
   r
   r   Úrsampleï   s    
zMultivariateNormal.rsamplec                 C   sf   | j r|  |¡ || j }t| j|ƒ}| jjddd� ¡  d¡}d| jd t	 dt	j
 ¡ |  | S )Nr   r   ©Zdim1Zdim2g      à¿r   r   )r>   Z_validate_sampler,   r"   r6   ÚdiagonalÚlogr   rB   ÚmathÚpi)r7   ÚvalueÚdiffr    Úhalf_log_detr
   r
   r   Úlog_probô   s    

ÿzMultivariateNormal.log_probc                 C   sb   | j jddd� ¡  d¡}d| jd  dt dtj ¡  | }t| jƒdkrR|S | 	| j¡S d S )Nr   r   rJ   g      à?r   g      ð?r   )
r6   rK   rL   r   rB   rM   rN   r   rA   r3   )r7   rQ   ÚHr
   r
   r   Úentropyþ   s    ÿ&zMultivariateNormal.entropy)NNNN)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Zreal_vectorZpositive_definiteZlower_choleskyZarg_constraintsZsupportZhas_rsampler5   r3   r   r/   r-   r.   ÚpropertyrE   rF   rG   r   r<   rI   rR   rT   Ú__classcell__r
   r
   r:   r   r   T   s:   $ü    ú9






)rM   r   Ztorch.distributionsr   Z torch.distributions.distributionr   Ztorch.distributions.utilsr   r   Ú__all__r   r"   r+   r   r
   r
   r
   r   Ú<module>   s   2	