
    Vh*                         d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlmZm	Z	 d dl
mZ dgZd Zd	 Zd
 Z G d de      Zy)    N)Tensor)constraints)Distribution)_standard_normallazy_property)_sizeMultivariateNormalc                 j    t        j                  | |j                  d            j                  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matmul	unsqueezesqueeze)bmatbvecs     W/home/dcms/DCMS/lib/python3.12/site-packages/torch/distributions/multivariate_normal.py	_batch_mvr      s)     <<dnnR0199"==    c                 $   |j                  d      }|j                  dd }t        |      }| j                         dz
  }||z
  }||z   }|d|z  z   }|j                  d| }	t	        | j                  dd |j                  |d       D ]  \  }
}|	||
z  |
fz  }	 |	|fz  }	|j                  |	      }t        t        |            t        t        ||d            z   t        t        |dz   |d            z   |gz   }|j                  |      }| j                  d||      }|j                  d|j                  d      |      }|j                  ddd      }t        j                  j                  ||d      j                  d      j                  d      }|j                         }|j                  |j                  dd       }t        t        |            }t        |      D ]  }|||z   ||z   gz  } |j                  |      }|j                  |      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zipreshapelistrangepermuter   linalgsolve_triangularpowsumt)bLbxnbx_batch_shapebx_batch_dimsbL_batch_dimsouter_batch_dimsold_batch_dimsnew_batch_dimsbx_new_shapesLsxpermute_dimsflat_Lflat_xflat_x_swapM_swapM
permuted_Mpermute_inv_dimsi
reshaped_Ms                         r   _batch_mahalanobisr?      s0    	AXXcr]N 'MFFHqLM$}4%5N%M(99N88--.LbhhsmRXX.>r%BC 'Br2&'QDL	L	!B 	U#$%
u%~q9
:	;
u%)>1=
>	? 
	  
L	!BZZAq!FZZFKKNA.F..Aq)K%%fk%GKKANRRSUV  	
A 288CR=)JE"234=! G-1>A3EFFG##$45Jn--r   c                 x   t         j                  j                  t        j                  | d            }t        j                  t        j                  |d      dd      }t        j
                  | j                  d   | j                  | j                        }t         j                  j                  ||d      }|S )N)r   r   r   r   dtypedeviceFr   )
r   r$   choleskyflip	transposeeyer   rB   rC   r%   )PLfL_invIdLs        r   _precision_to_scale_trilrM   O   s    			uzz!X6	7BOOEJJr84b"=E	1772;aggahh	?B%%eRu%=AHr   c                   t    e Zd ZdZej
                  ej                  ej                  ej                  dZej
                  Z	dZ
	 	 	 	 d fd	Zd fd	Zedefd       Zedefd       Zedefd	       Zedefd
       Zedefd       Zedefd       Z ej.                         fdedefdZd Zd Z x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_trilTc                    |j                         dk  rt        d      |d u|d uz   |d uz   dk7  rt        d      |h|j                         dk  rt        d      t        j                  |j                  d d |j                  d d       }|j                  |dz         | _        n|h|j                         dk  rt        d	      t        j                  |j                  d d |j                  d d       }|j                  |dz         | _        ng|j                         dk  rt        d
      t        j                  |j                  d d |j                  d d       }|j                  |dz         | _        |j                  |dz         | _	        | j                  j                  dd  }t        | -  |||       ||| _        y |%t        j                  j                  |      | _        y t        |      | _        y )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   broadcast_shapesr   expandrR   rP   rQ   rO   super__init___unbroadcasted_scale_trilr$   rD   rM   )	selfrO   rP   rQ   rR   rU   batch_shapeevent_shape	__class__s	           r   rZ   zMultivariateNormal.__init__   s    779q=DEET)j.DED(
 f  !~~!# =   001A1A#21F		RUSUWK(//h0FGDO* $$&* =   00!'',ciinK &7%=%=kH>T%UD"##%) =   00 &&s+SYYs^K %5$;$;K(<R$SD!::kE12hhnnRS)kO!-7D**-2\\-B-BCT-UD*-EFV-WD*r   c                    | j                  t        |      }t        j                  |      }|| j                  z   }|| j                  z   | j                  z   }| j
                  j                  |      |_        | j                  |_        d| j                  v r | j                  j                  |      |_	        d| j                  v r | j                  j                  |      |_
        d| j                  v r | j                  j                  |      |_        t        t        |7  || j                  d       | j                  |_        |S )NrP   rR   rQ   FrT   )_get_checked_instancer	   r   Sizer^   rO   rX   r[   __dict__rP   rR   rQ   rY   rZ   _validate_args)r\   r]   	_instancenew	loc_shape	cov_shaper_   s         r   rX   zMultivariateNormal.expand   s   (();YGjj-$"2"22	$"2"22T5E5EE	((//),(,(F(F%$--/$($:$:$A$A)$LC!4==(!__33I>CN.#'#8#8#?#?	#JC  #/)) 	0 	
 "00
r   returnc                     | j                   j                  | j                  | j                  z   | j                  z         S N)r[   rX   _batch_shape_event_shaper\   s    r   rR   zMultivariateNormal.scale_tril   s:    --44 1 11D4E4EE
 	
r   c                     t        j                  | j                  | j                  j                        j	                  | j
                  | j                  z   | j                  z         S rk   )r   r   r[   mTrX   rl   rm   rn   s    r   rP   z$MultivariateNormal.covariance_matrix   sQ    ||**D,J,J,M,M

&""T%6%669J9JJ
K	Lr   c                     t        j                  | j                        j                  | j                  | j
                  z   | j
                  z         S rk   )r   cholesky_inverser[   rX   rl   rm   rn   s    r   rQ   z#MultivariateNormal.precision_matrix   sE    %%d&D&DELL 1 11D4E4EE
 	
r   c                     | j                   S rk   rO   rn   s    r   meanzMultivariateNormal.mean       xxr   c                     | j                   S rk   rt   rn   s    r   modezMultivariateNormal.mode   rv   r   c                     | j                   j                  d      j                  d      j                  | j                  | j
                  z         S )Nr   r   )r[   r&   r'   rX   rl   rm   rn   s    r   variancezMultivariateNormal.variance   sA     **..q1SWVD%%(9(99:	
r   sample_shapec                     | j                  |      }t        || j                  j                  | j                  j                        }| j                  t        | j                  |      z   S )NrA   )_extended_shaper   rO   rB   rC   r   r[   )r\   r{   r   epss       r   rsamplezMultivariateNormal.rsample   sL    $$\2uDHHNN488??Sxx)D$B$BCHHHr   c                 x   | j                   r| j                  |       || j                  z
  }t        | j                  |      }| j                  j                  dd      j                         j                  d      }d| j                  d   t        j                  dt        j                  z        z  |z   z  |z
  S )Nr   r   dim1dim2g      r   r   )rd   _validate_samplerO   r?   r[   diagonallogr'   rm   mathpi)r\   valuediffr:   half_log_dets        r   log_probzMultivariateNormal.log_prob   s    !!%(txxt==tD**33"3EIIKOOPRS 	 t((+dhhq477{.CCaGH<WWr   c                 ^   | j                   j                  dd      j                         j                  d      }d| j                  d   z  dt        j                  dt
        j                  z        z   z  |z   }t        | j                        dk(  r|S |j                  | j                        S )Nr   r   r   g      ?r   g      ?r   )
r[   r   r   r'   rm   r   r   r   rl   rX   )r\   r   Hs      r   entropyzMultivariateNormal.entropy  s    **33"3EIIKOOPRS 	 $##A&&#TWW0E*EFUt  !Q&H88D--..r   )NNNNrk   )__name__
__module____qualname____doc__r   real_vectorpositive_definitelower_choleskyarg_constraintssupporthas_rsamplerZ   rX   r   r   rR   rP   rQ   propertyru   rx   rz   r   rb   r   r   r   r   __classcell__)r_   s   @r   r	   r	   X   s5   "J &&(::'99!00	O %%GK
 7Xr& 
F 
 

 L6 L L
 
& 
 

 f   f   
& 
 
 -7EJJL IE IV I
X/r   )r   r   r   torch.distributionsr    torch.distributions.distributionr   torch.distributions.utilsr   r   torch.typesr   __all__r   r?   rM   r	    r   r   <module>r      sB       + 9 E   
 >/.ds/ s/r   