B
    s=ba                 @   sn   d dl Zd dlZd dlmZ d dlmZ ejejejdddZdd Z	dd
dZ
dd Zdd Zdd ZdS )    N)nn)
functional)plog_plog_qc             C   s   t j| ||  ddS )N)dim)torchsum)r   r   r    r   9/Users/wangjiarui/Desktop/Learn/CS236/HW/HW2_VAE/probs.pyKL_categorical   s    r   c             C   s@   dt jt |t | d ||  t | | |  dd S )aE  
	Compute the KL divergence of two scaled (NOT TILTED) multivariate Gaussian
		KL( N(mu1, diag(var1)) || N(mu2, diag(var2)) )
	:param mu1: torch.Tensor, of shape [...,dim]
	:param var1: torch.Tensor, of shape [...,dim]
	:param mu2: torch.Tensor, of shape [..., dim]
	:param var2: torch.Tensor, of shape [..., dim]
	:return:
	g      ?   r   )r   )r	   r
   logsquare)Zmu1Zvar1Zmu2Zvar2r   r   r   KL_gaussians	   s    
r   
   c          	   C   s`   g }| j d }| j d }x<t|D ]0}|tjj| | t|| d|g q"W t|S )z
	Sample from Multivariate Gaussian with reparameterization
	:param mu: torch.Tensor, of shape [batch, dim]
	:param var: torch.Tensor, of shape [batch, dim]
	:param num_sample: int
	:return: torch.Tensor, of shape [batch, num_sample, dim]
	r   r   )loccovariance_matrix)	shaperangeappendr	   distributionsMultivariateNormaldiagrsamplestack)muvar
num_sampleret
batch_sizer   ir   r   r   sample_from_gaussian_repram   s    

r#   c       
         s   |j d }tjjtd|||  d  fddt|D }g }xBt|D ]6\}}t	j
| | t	|| |g}	||	 qPW t	j|ddS )z
	:param mu: torch.Tensor, of shape [k, dim]
	:param var: torch.Tensor, of shape [k, dim]
	:param ws: torch.Tensor, of shape [k,]
	:return: torch.Tensor, of shape [num_sample, dim]
	r   )sizer   c                s   g | ]}t  |kqS r   )npr
   ).0r"   )idxr   r   
<listcomp>5   s    z0sample_from_mixture_gaussian.<locals>.<listcomp>)r   )r   r%   randomchoicearangedetachnumpyr   	enumerater	   r   r   r   sampler   cat)
r   r   wsr   kcountsr    Zgaussian_idnumberzr   )r'   r   sample_from_mixture_gaussian,   s    
"r6   c             C   sH   t jtttjd  t t | t ||  d|   ddS )z
	Compute the log of Gaussian pdf
	:param mu: torch.Tensor, of shape [..., dim]
	:param var: torch.Tensor, of shape [..., dim]
	:param x: torch.Tensor, of shape [..., dim]
	:return:
	   r   )r   )r	   r
   r%   r   sqrtpir   )r   r   xr   r   r   log_gaussian_pdf>   s    <r;   c          
   C   st   |j d }|ddddf }tj||dd}t| ||}tj|ddd }|ttj|t||d   dd S )z
	Compute the log of mixture of Gaussian pdf
	:param mu: torch.Tensor, of shape [..., k, dim]
	:param var: torch.Tensor, of shape [..., k, dim]
	:param weight: torch.Tensor, of shape [..., k]
	:param x: torch.Tensor, pf shape [..., dim]
	:return:
	r   .N)r   r   ).N)r   r	   repeat_interleaver;   maxr   r
   exp)r   r   weightr:   r2   Zlog_gaussiansZlog_gaussian_maxr   r   r   log_mixture_gaussian_pdfK   s    	
rA   )r   )r-   r%   r	   r   torch.nnr   FTensorr   r   r#   r6   r;   rA   r   r   r   r   <module>   s   
