
    x-j?                        d dl mZ d dlZd dlmZ d dlmZ d dlZd dlm	Z	 d dl
mZ erd dlmZ d dlmZ  G d	 d
ej                  ZddZddZdS )    )annotationsN)Sequence)TYPE_CHECKING)convert_dtype)distribution)Tensor)_DTypeLiteralc                       e Zd ZU dZded<   ded<   ded<   ded<   ded	<   	 	 	 dd fdZedd            Zedd            Zg fddZ	g fddZ
ddZddZddZddZ xZS ) MultivariateNormala  The Multivariate Normal distribution is a type multivariate continuous distribution defined on the real set, with parameter: `loc` and any one
    of the following parameters characterizing the variance: `covariance_matrix`, `precision_matrix`, `scale_tril`.

    Mathematical details

    The probability density function (pdf) is

    .. math::

        p(X ;\mu, \Sigma) = \frac{1}{\sqrt{(2\pi)^k |\Sigma|}} \exp(-\frac{1}{2}(X - \mu)^{\intercal} \Sigma^{-1} (X - \mu))

    In the above equation:

    * :math:`X`: is a k-dim random vector.
    * :math:`loc = \mu`: is the k-dim mean vector.
    * :math:`covariance_matrix = \Sigma`: is the k-by-k covariance matrix.

    Args:
        loc(int|float|Tensor): The mean of Multivariate Normal distribution. If the input data type is int or float, the data type of `loc` will be
            convert to a 1-D Tensor the paddle global default dtype.
        covariance_matrix(Tensor|None): The covariance matrix of Multivariate Normal distribution. The data type of `covariance_matrix` will be convert
            to be the same as the type of loc.
        precision_matrix(Tensor|None): The inverse of the covariance matrix. The data type of `precision_matrix` will be convert to be the same as the
            type of loc.
        scale_tril(Tensor|None): The cholesky decomposition (lower triangular matrix) of the covariance matrix. The data type of `scale_tril` will be
            convert to be the same as the type of loc.

    Examples:
        .. code-block:: python

            >>> import paddle
            >>> from paddle.distribution import MultivariateNormal
            >>> paddle.set_device("cpu")
            >>> paddle.seed(100)

            >>> rv = MultivariateNormal(loc=paddle.to_tensor([2.,5.]), covariance_matrix=paddle.to_tensor([[2.,1.],[1.,2.]]))

            >>> print(rv.sample([3, 2]))
            Tensor(shape=[3, 2, 2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[[-0.00339603,  4.31556797],
              [ 2.01385283,  4.63553190]],
             [[ 0.10132277,  3.11323833],
              [ 2.37435842,  3.56635118]],
             [[ 2.89701366,  5.10602522],
              [-0.46329355,  3.14768648]]])

            >>> print(rv.mean)
            Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [2., 5.])

            >>> print(rv.variance)
            Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
            [1.99999988, 2.        ])

            >>> print(rv.entropy())
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            3.38718319)

            >>> rv1 = MultivariateNormal(loc=paddle.to_tensor([2.,5.]), covariance_matrix=paddle.to_tensor([[2.,1.],[1.,2.]]))
            >>> rv2 = MultivariateNormal(loc=paddle.to_tensor([-1.,3.]), covariance_matrix=paddle.to_tensor([[3.,2.],[2.,3.]]))
            >>> print(rv1.kl_divergence(rv2))
            Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
            1.55541301)
    r   locTensor | Nonecovariance_matrixprecision_matrix
scale_trilr	   dtypeNfloat | Tensorc                   t          j                    | _        t          |t          t
          f          rt          j        |g| j                  }nt          |j                  | _        |                                dk     r|	                    d          }d | _
        d | _        d | _        |d u|d uz   |d uz   dk    rt          d          ||                                dk     rt          d          t          j        || j                  }t          j        |j        d d         |j        d d                   }|                    g ||j        d         |j        d                   | _        nQ||                                dk     rt          d	          t          j        || j                  }t          j        |j        d d         |j        d d                   }|                    g ||j        d         |j        d                   | _
        n|                                dk     rt          d
          t          j        || j                  }t          j        |j        d d         |j        d d                   }|                    g ||j        d         |j        d                   | _        |                    g |d          | _        | j        j        dd          }||| _        n;|%t           j                            |          | _        nt-          |          | _        t/                                          ||           d S )Nr      )r   zTExactly one of covariance_matrix or precision_matrix or scale_tril may be specified.   zZscale_tril matrix must be at least two-dimensional, with optional leading batch dimensionszZcovariance_matrix must be at least two-dimensional, with optional leading batch dimensionszYprecision_matrix must be at least two-dimensional, with optional leading batch dimensions)paddleget_default_dtyper   
isinstancefloatint	to_tensorr   dimreshaper   r   r   
ValueErrorcastbroadcast_shapeshapeexpandr   _unbroadcasted_scale_trillinalgcholeskyprecision_to_scale_trilsuper__init__)selfr   r   r   r   batch_shapeevent_shape	__class__s          g/var/www/html/banglarbhumi/venv/lib/python3.11/site-packages/paddle/distribution/multivariate_normal.pyr+   zMultivariateNormal.__init__e   s    -//
cE3<(( 	2"C5
;;;CC&sy11DJ7799q==++d##C!% $T)j.DED(
  f   !~~!## =    ZtzBBBJ 0 "%sy"~ K )//J+Jz/3JZ5Eb5IJ DOO * $$&&** =   !',=TZ P P P 0!',cin K &7%=%= %+B/ &+B/& &D""  ##%%)) =    &{+;4:NNN 0 &ss+SYss^ K %5$;$; $*2. %*2.% %D! ::00R011hnRSS)!-7D***-3]-C-C!. .D** .E . .D* 	k22222    returnc                    | j         S )zdMean of Multivariate Normal distribution.

        Returns:
            Tensor: mean value.
        )r   r,   s    r0   meanzMultivariateNormal.mean   s     xr1   c                    t          j        | j                                      d                              | j        | j        z             S )zlVariance of Multivariate Normal distribution.

        Returns:
            Tensor: variance value.
        r   )r   squarer&   sumr%   _batch_shape_event_shaper4   s    r0   variancezMultivariateNormal.variance   s<     M$899SWWVD%(99::	
r1   r$   Sequence[int]c                    t          j                    5  |                     |          cddd           S # 1 swxY w Y   dS )  Generate Multivariate Normal samples of the specified shape. The final shape would be ``sample_shape + batch_shape + event_shape``.

        Args:
            shape (Sequence[int], optional): Prepended shape of the generated samples.

        Returns:
            Tensor, Sampled data with shape `sample_shape` + `batch_shape` + `event_shape`. The data type is the same as `self.loc`.
        N)r   no_gradrsample)r,   r$   s     r0   samplezMultivariateNormal.sample   s     ^ 	' 	'<<&&	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	's   6::c                `   t          |t                    st          d          |                     |          }t	          j        t	          j        |          | j                  }| j        t	          j	        | j
        |                    d                                        d          z   S )r>   z%sample shape must be Sequence object.)r$   r   r   )r   r   	TypeError_extend_shaper   r"   normalr   r   matmulr&   	unsqueezesqueeze)r,   r$   output_shapeepss       r0   r@   zMultivariateNormal.rsample   s     %** 	ECDDD))%00k&-l;;;4:NNNx&-*CMM",=,=
 

'"++ 	r1   valuec                h   t          j        || j                  }|| j        z
  }t	          | j        |          }| j                            dd                                                              d          }d| j	        d         t          j        dt          j        z            z  |z   z  |z
  S )zLog probability density function.

        Args:
          value (Tensor): The input tensor.

        Returns:
          Tensor: log probability. The data type is the same as `self.loc`.
        r   r   r   axis1axis2g      r   r   )r   r"   r   r   batch_mahalanobisr&   diagonallogr8   r:   mathpi)r,   rK   diffMhalf_log_dets        r0   log_probzMultivariateNormal.log_prob   s     E444txd<dCC*33"B3GGSUUSWW 	 D%a(48AK+@+@@1DE	
r1   c                P    t          j        |                     |                    S )zProbability density function.

        Args:
            value (Tensor): The input tensor.

        Returns:
            Tensor: probability. The data type is the same as `self.loc`.
        )r   exprX   )r,   rK   s     r0   probzMultivariateNormal.prob  s      z$--..///r1   c                \   | j                             dd                                                              d          }d| j        d         z  dt          j        dt
          j        z            z   z  |z   }t          | j                  dk    r|S |	                    | j                  S )a  Shannon entropy in nats.

        The entropy is

        .. math::

            \mathcal{H}(X) = \frac{n}{2} \log(2\pi) + \log {\det A} + \frac{n}{2}

        In the above equation:

        * :math:`\Omega`: is the support of the distribution.

        Returns:
            Tensor, Shannon entropy of Multivariate Normal distribution. The data type is the same as `self.loc`.
        r   r   rM         ?r   g      ?r   )
r&   rQ   rR   r8   r:   rS   rT   lenr9   r%   )r,   rW   Hs      r0   entropyzMultivariateNormal.entropy  s    " *33"B3GGSUUSWW 	 $#A&&#TW0E0E*EF 	
 t !!Q&&H88D-...r1   otherc                   | j         |j         k    r| j        |j        k    rt          d          | j                            dd                                                              d          }|j                            dd                                                              d          }t          t          t          | j        j
                                      }|d         |d         c|d<   |d<   t          j        | j        | j                            |                    }t          j        |j        |j                            |                    }t          j                            ||                              dd                              d          }|t!          |j        | j        |j        z
            z  }||z
  d|| j        d         z
  z  z   S )a^  The KL-divergence between two poisson distributions with the same `batch_shape` and `event_shape`.

        The probability density function (pdf) is

        .. math::

            KL\_divergence(\lambda_1, \lambda_2) = \log(\det A_2) - \log(\det A_1) -\frac{n}{2} +\frac{1}{2}[tr [\Sigma_2^{-1} \Sigma_1] + (\mu_1 - \mu_2)^{\intercal} \Sigma_2^{-1}  (\mu_1 - \mu_2)]

        Args:
            other (MultivariateNormal): instance of Multivariate Normal.

        Returns:
            Tensor, kl-divergence between two Multivariate Normal distributions. The data type is the same as `self.loc`.

        zmKL divergence of two Multivariate Normal distributions should share the same `batch_shape` and `event_shape`.r   r   rM   r]   r   )r9   r:   r!   r&   rQ   rR   r8   listranger^   r$   r   rF   	transposer'   solverP   r   )r,   ra   half_log_det_1half_log_det_2new_perm	cov_mat_1	cov_mat_2expectations           r0   kl_divergencez MultivariateNormal.kl_divergence/  s   " !333!U%777   *33"B3GGSUUSWW 	 +442R4HHSUUSWW 	
 c$"@"FGGHHII%-b\8B<"hrlM**44X>>
 
	 M++55h??
 
	
 M	955XBbX))SWW 	
 	(+TX	-A
 
 	
 [4#4Q#7789	
r1   )NNN)r   r   r   r   r   r   r   r   )r2   r   )r$   r<   r2   r   )rK   r   r2   r   )ra   r   r2   r   )__name__
__module____qualname____doc____annotations__r+   propertyr5   r;   rA   r@   rX   r[   r`   rm   __classcell__)r/   s   @r0   r   r      si        ? ?B KKK$$$$####
 ,0*.$(U3 U3 U3 U3 U3 U3 U3n    X 

 

 

 X

 -/ 
' 
' 
' 
' 
' .0     "
 
 
 
.	0 	0 	0 	0/ / / /<7
 7
 7
 7
 7
 7
 7
 7
r1   r   Pr   r2   c                   t           j                            t          j        | d                    }t          j        |d          }t	          t          t          |j                                      }|d         |d         c|d<   |d<   t          j        ||          }t          j	        | j        d         | j
                  }t           j                            ||d          }|S )zConvert precision matrix to scale tril matrix

    Args:
        P (Tensor): input precision matrix

    Returns:
        Tensor: scale tril matrix
    )r   r   r   r   r   Fupper)r   r'   r(   fliprc   rd   r^   r$   re   eyer   triangular_solve)ru   Lftmpri   L_invIdLs          r0   r)   r)   i  s     
		Ax 8 8	9	9B
+b(
#
#CE#ci..))**H!)"x|HRL(2,S(++E	AGBKqw	/	/	/B&&ub&>>AHr1   bLbxc                   |j         d         }|j         dd         }t          |          }|                                 dz
  }||z
  }||z   }|d|z  z   }|j         d|         }	t          | j         dd         |j         |d                   D ]\  }
}|	||
z  |
fz  }	|	|fz  }	|                    |	          }t          t          |                    t          t          ||d                    z   t          t          |dz   |d                    z   |gz   }|                    |          }|                     d||f          }|                    d|j         d         |f          }|                    d          }t          j	        
                    ||d	                              d                              d          }|                                }|                    |j         dd                   }t          t          |                    }t          |          D ]}|||z   ||z   gz  }|                    |          }|                    |          S )
aa  
    Computes the squared Mahalanobis distance of the Multivariate Normal distribution with cholesky decomposition of the covariance matrix.
    Accepts batches for both bL and bx.

    Args:
        bL (Tensor): scale trial matrix (batched)
        bx (Tensor): difference vector(batched)

    Returns:
        Tensor: squared Mahalanobis distance
    r   Nr   r   r   r   )r   r   r   Frw   )r$   r^   r   zipr    rc   rd   re   r   r'   r{   powr8   t)r   r   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_swaprV   
permuted_Mpermute_inv_dimsi
reshaped_Ms                         r0   rP   rP   |  sy    	AXcrc]N ''MFFHHqLM$}4%5N%M(99N8---.LbhssmRX.>r.A%BCC ' 'Br2&QDL	L	!	!B 	U#$$%%
u%~q99
:
:	;
u%)>1==
>
>	? 
	  
l	#	#BZZQ
##FZZV\!_a011F""9--K&&v{%&HH	Q	R 
 	

A 28CRC=))JE"23344=!! G G-1>A3EFF%% J n---r1   )ru   r   r2   r   )r   r   r   r   r2   r   )
__future__r   rS   collections.abcr   typingr   r   paddle.base.data_feederr   paddle.distributionr   r   paddle._typing.dtype_liker	   Distributionr   r)   rP    r1   r0   <module>r      s   # " " " " "  $ $ $ $ $ $              1 1 1 1 1 1 , , , , , , 8777777I
 I
 I
 I
 I
2 I
 I
 I
X
   &7. 7. 7. 7. 7. 7.r1   