o
    9i                     @   sJ   d dl Zd dlZG dd dZG dd deZG dd deZdd	 ZdS )
    Nc                   @   s   e Zd Zdd Zdd ZdS )AbstractDistributionc                 C      t  NNotImplementedErrorself r	   Q/data/cameron/vidgen/generative-models/sgm/modules/distributions/distributions.pysample      zAbstractDistribution.samplec                 C   r   r   r   r   r	   r	   r
   mode	   r   zAbstractDistribution.modeN)__name__
__module____qualname__r   r   r	   r	   r	   r
   r      s    r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )DiracDistributionc                 C   s
   || _ d S r   value)r   r   r	   r	   r
   __init__   s   
zDiracDistribution.__init__c                 C      | j S r   r   r   r	   r	   r
   r      r   zDiracDistribution.samplec                 C   r   r   r   r   r	   r	   r
   r      r   zDiracDistribution.modeN)r   r   r   r   r   r   r	   r	   r	   r
   r      s    r   c                   @   s@   e Zd ZdddZdd ZdddZg d	fd
dZdd ZdS )DiagonalGaussianDistributionFc                 C   s   || _ tj|ddd\| _| _t| jdd| _|| _td| j | _t| j| _	| jr@t
| jj| j jd | _	| _d S d S )N      dimg      >g      4@      ?device)
parameterstorchchunkmeanlogvarclampdeterministicexpstdvar
zeros_liketor   )r   r   r$   r	   r	   r
   r      s   z%DiagonalGaussianDistribution.__init__c                 C   s*   | j | jt| j jj| jjd  }|S )Nr   )r!   r&   r   randnshaper)   r   r   )r   xr	   r	   r
   r   %   s   
z#DiagonalGaussianDistribution.sampleNc                 C   s   | j r	tdgS |d u r%dtjt| jd| j d | j g dd S dtjt| j|j d|j | j|j  d | j |j g dd S )N        r   r   g      ?r   r      r   )r$   r   Tensorsumpowr!   r'   r"   )r   otherr	   r	   r
   kl+   s&   
zDiagonalGaussianDistribution.klr.   c                 C   sR   | j r	tdgS tdtj }dtj|| j t|| j	 d| j
  |d S )Nr-   g       @r   r   r   )r$   r   r0   nplogpir1   r"   r2   r!   r'   )r   r   dimslogtwopir	   r	   r
   nll>   s    z DiagonalGaussianDistribution.nllc                 C   r   r   )r!   r   r	   r	   r
   r   G   r   z!DiagonalGaussianDistribution.mode)Fr   )r   r   r   r   r   r4   r:   r   r	   r	   r	   r
   r      s    

	r   c                    s   d | |||fD ]}t |tjr|  nq dusJ d fdd||fD \}}dd| | t||  | | d t|    S )a*  
    source: https://github.com/openai/guided-diffusion/blob/27c20a8fab9cb472df5d6bdd6c8d11c8f430b924/guided_diffusion/losses.py#L12
    Compute the KL divergence between two gaussians.
    Shapes are automatically broadcasted, so batches can be compared to
    scalars, among other use cases.
    Nz&at least one argument must be a Tensorc                    s,   g | ]}t |tjr|nt| qS r	   )
isinstancer   r0   tensorr)   ).0r,   r<   r	   r
   
<listcomp>[   s    znormal_kl.<locals>.<listcomp>r   g      r   )r;   r   r0   r%   )mean1logvar1mean2logvar2objr	   r>   r
   	normal_klK   s*   

rE   )numpyr5   r   r   r   objectr   rE   r	   r	   r	   r
   <module>   s    3