o
    }o™iM  ã                   @   s¦   d dl Zd dlZd dlm  mZ ddd„Zddd„Zdd	d
„Z	dd„ Z
ddd„Z						ddd„Zd dd„Z						d!dd„Z								d"dd„ZdS )#é    NTc                 C   s´  d}t jjdd}|j\}}}| j\}	}
||	kr||
ks J dƒ‚d| }d| ||ƒ }t  t  ||  ¡d|d ¡ t j¡}t  t  	|¡¡ 
¡ sVt  |dk ¡sVt  ||k¡rZtdƒ‚| ||  }t  |d| d	¡¡ d	¡}|| }t  t  |d¡| dd¡}d|dd…dd…df< |t  |d| d	¡¡ d	¡ }t  |j¡j}|j|d| d
}t  | dk | dk¡ ¡  ¡ }|rÊ|d|  | |  }|d|  | }|rÕt  t  |¡d¡}~||fS )aG  Apply an element-wise piecewise-linear transformation to some variables

    Args:
        x : torch.Tensor
            a tensor with shape (N,k) where N is the batch dimension while k is the dimension of the variable space. This variable span the k-dimensional unit
        hypercube

        q_tilde: torch.Tensor
                is a tensor with shape (N,k,b) where b is the number of bins.
                This contains the un-normalized heights of the bins of the piecewise-constant PDF for dimension k,
                i.e. q_tilde lives in all of R and we don't impose a constraint on their sum yet.
                Normalization is imposed in this function using softmax.

        compute_jacobian : bool, optional
                            determines whether the jacobian should be compute or None is returned

    Returns:
        tuple of torch.Tensor
            pair `(y,h)`.
            - `y` is a tensor with shape (N,k) living in the k-dimensional unit hypercube
            - `j` is the jacobian of the transformation with shape (N,) if compute_jacobian==True, else None.
    Né   ©ÚdimúShape mismatchç      ð?r   é   ú%NaN detected in PWLinear bin indexingéÿÿÿÿ©ÚminÚmaxç        )ÚtorchÚnnÚSoftmaxÚshapeÚclampÚfloorÚtoÚlongÚanyÚisnanÚitemÚAvertedCUDARuntimeErrorÚgatherÚ	unsqueezeÚsqueezeÚrollÚcumsumÚfinfoÚdtypeÚepsÚ
logical_orÚdetachÚfloatÚsumÚlog)ÚxÚq_tildeÚcompute_jacobianÚoutlier_passthruÚlogjÚthird_dimension_softmaxÚNÚkÚbÚNxÚkxÚwÚqÚmxÚoutÚslopesÚq_left_integralsr!   Úoob_mask© r9   ú\/home/ubuntu/.local/lib/python3.10/site-packages/nemo/collections/tts/parts/utils/splines.pyÚpiecewise_linear_transform   s4   
$0r;   c                 C   sÖ  t jjdd}|j\}}}| j\}}	||kr||	ksJ dƒ‚d| }
d|
 ||ƒ }t  t  | ¡ d¡|
 dd¡}d|dd…dd…df< |  d¡|  ¡ }d	||dk < t  	t j
|ddd|d ¡ t j¡}t  t  |¡¡ ¡ s}t  |dk ¡s}t  ||k¡rtd
ƒ‚| d| d¡¡ d¡}| d| d¡¡ d¡}| | | ||
  }t  |j¡j}|j	|d| d}t  | dk | dk¡ ¡  ¡ }|rÕ|d|  | |  }|d|  | }d}|råt  t  | ¡ ¡d¡ }| ¡ |fS )a#  
    Apply inverse of an element-wise piecewise-linear transformation to some
    variables

    Args:
        y : torch.Tensor
            a tensor with shape (N,k) where N is the batch dimension while k is the dimension of the variable space. This variable span the k-dimensional unit hypercube

        q_tilde: torch.Tensor
                is a tensor with shape (N,k,b) where b is the number of bins. This contains the un-normalized heights of the bins of the piecewise-constant PDF for dimension k, i.e. q_tilde lives in all of R and we don't impose a constraint on their sum yet. Normalization is imposed in this function using softmax.

        compute_jacobian : bool, optional
                            determines whether the jacobian should be compute or None is returned

    Returns:
        tuple of torch.Tensor
            pair `(x,h)`.
            - `x` is a tensor with shape (N,k) living in the k-dimensional unit hypercube
            - `j` is the jacobian of the transformation with shape (N,) if compute_jacobian==True, else None.
    r   r   r   r   r   r   Nr	   g       @r   r
   r   )r   r   r   r   r   r   r$   r   r#   r   Úargminr   r   r   r   r   r   r   r   r   r    r!   r"   r%   r&   )Úyr(   r)   r*   r,   r-   r.   r/   ÚNyÚkyr2   r3   r7   Úedgesr'   r!   r8   r+   r9   r9   r:   Ú"piecewise_linear_inverse_transforml   s4   
$0rA   r   Fc                 C   sº   ||ksJ ‚|| }| |k| |k @ }| }t  | ¡}	t  | ¡}
| | |	|< d|
|< t| | | | ||d d …f ||d d …f |d\}}|| | |	|< |sW||
|< |	|
fS d }
|	|
fS )Nr   )Úinverse)r   Ú
zeros_likeÚpiecewise_quadratic_transform)r'   Úw_tildeÚv_tildeÚupperÚlowerrB   Ú_rangeÚinside_interval_maskÚoutside_interval_maskÚoutputsÚlog_jÚoutputÚ_log_jr9   r9   r:   Ú'unbounded_piecewise_quadratic_transformÀ   s(   


üÿrP   c                 C   sb   | t j| dddd  } t  | ¡d } t j| dd d…f | ddd …f  d | ddd}| | S )	Nr	   T)r   Úkeepdimr   g:Œ0âŽyE>.r   r   )r   r   Úexpr%   )Úvr2   Úv_sumr9   r9   r:   Úweighted_softmaxÛ   s   4rU   c                 C   s8  t j|dd}t||ƒ}t j|dd}d|d< t |ddd¡}t j|dd	d
…f |dd
d…f  d | dd}d|d< t |ddd¡}	|sPt  ||  d¡¡}
n	t  ||  d¡¡}
t  |d|
¡ 	d¡}t  |d|
¡ 	d¡}t  |d|
¡ 	d¡}t  |d|
d	 ¡ 	d¡}t  |	d|
¡ 	d¡}|sÛ| | |j
t  |j¡jd }|d d ||  | || |  | }t  |||¡j
t  |j¡jd ¡ }|j
t  |j¡jdt  |j¡j d}||fS || | d }|| }||  }| t  |d d| |  ¡ d|  }|| | }|j
t  |j¡jdt  |j¡j d}|d
fS )aú  Element-wise piecewise-quadratic transformation
    Args:
        x : torch.Tensor
            *, The variable spans the D-dim unit hypercube ([0,1))
        w_tilde : torch.Tensor
            * x K defined in the paper
        v_tilde : torch.Tensor
            * x (K+1) defined in the paper
        inverse : bool
            forward or inverse
    Returns:
        c : torch.Tensor
            *, transformed value
        log_j : torch.Tensor
            *, log determinant of the Jacobian matrix
    r	   r   r   ©.r	   ©r   r   Úconstantr   .r   Nr   )r   r
   é   )r   ÚsoftmaxrU   r   ÚFÚpadÚsearchsortedr   r   r   r   r   r    r!   Úlerpr&   Úsqrt)r'   rE   rF   rB   r2   rS   Úw_cumsumÚw_cumsum_shiftÚcdfÚ	cdf_shiftÚ	bin_indexÚw_bÚw_bn1Úv_bÚv_bp1Úcdf_bn1ÚalphaÚcrM   Úar/   Úinvr9   r9   r:   rD   ã   s:   
2($&(&rD   r   çü©ñÒMbP?c
                 C   sL   |d u r	t }
i }nt}
||dœ}|
d| |||||||	dœ|¤Ž\}}||fS )N)ÚtailsÚ
tail_bound)ÚinputsÚunnormalized_widthsÚunnormalized_heightsÚunnormalized_derivativesrB   Úmin_bin_widthÚmin_bin_heightÚmin_derivativer9   )Úrational_quadratic_splineÚ'unconstrained_rational_quadratic_spline)rq   rr   rs   rt   rB   ro   rp   ru   rv   rw   Ú	spline_fnÚspline_kwargsrL   Ú	logabsdetr9   r9   r:   Ú&piecewise_rational_quadratic_transform%  s$   
ø	
÷r}   çíµ ÷Æ°>c                 C   s*   | d  |7  < t j|d | kddd S )NrV   ©.Nr	   r   r   )r   r%   )Úbin_locationsrq   r!   r9   r9   r:   r]   G  s   r]   Úlinearc
                 C   sî   | | k| |k@ }
|
 }t  | ¡}t  | ¡}|dkr@tj|dd}t t d|	 ¡d ¡}||d< ||d< | | ||< d||< ntd |¡ƒ‚t	| |
 ||
d d …f ||
d d …f ||
d d …f || || ||||	d	\||
< ||
< ||fS )
Nr   )r   r   )r\   r   ©.r   rV   r   z{} tails are not implemented.)rq   rr   rs   rt   rB   ÚleftÚrightÚbottomÚtopru   rv   rw   )
r   rC   r[   r\   Únpr&   rR   ÚRuntimeErrorÚformatrx   )rq   rr   rs   rt   rB   ro   rp   ru   rv   rw   rJ   rK   rL   r|   rX   r9   r9   r:   ry   L  s6   


ôry   r   c           '      C   sÚ  t  | ¡|k st  | ¡|krtdƒ‚|jd }|	| dkr!tdƒ‚|
| dkr+tdƒ‚tj|dd}|	d|	|  |  }t j|dd}tj|dd	d
d}|| | | }||d< ||d< |ddd …f |dd d…f  }|t 	|¡ }tj|dd}|
d|
|  |  }t j|dd}tj|dd	d
d}|| | | }||d< ||d< |ddd …f |dd d…f  }|r¾t
|| ƒd }nt
|| ƒd }| d|¡d }| d|¡d }| d|¡d }|| }| d|¡d }| d|¡d }|ddd …f  d|¡d }| d|¡d }|r—| | || d|   |||   }|| | | || d|    }| | |  }| d¡d| |  }|dk ¡ sGJ ‚d| | t  |¡  }|| | } |d|  }!||| d|  |!  }"| d¡|| d¡ d| |!  |d|  d¡   }#t  |#¡dt  |"¡  }$| |$ fS | | | }%|%d|%  }!|||% d¡ ||!   }&||| d|  |!  }"||&|"  } | d¡||% d¡ d| |!  |d|%  d¡   }#t  |#¡dt  |"¡  }$| |$fS )Nz-Input to a transform is not within its domainr	   r   z2Minimal bin width too large for the number of binsz3Minimal bin height too large for the number of binsr   r   rW   rX   r   )r\   ÚmodeÚvaluer‚   rV   .r   r   rY   r   )r   r   r   Ú
ValueErrorr   r[   rZ   r   r\   Úsoftplusr]   r   ÚpowÚallr_   r&   )'rq   rr   rs   rt   rB   rƒ   r„   r…   r†   ru   rv   rw   Únum_binsÚwidthsÚ	cumwidthsÚderivativesÚheightsÚ
cumheightsÚbin_idxÚinput_cumwidthsÚinput_bin_widthsÚinput_cumheightsÚdeltaÚinput_deltaÚinput_derivativesÚinput_derivatives_plus_oneÚinput_heightsrl   r/   rk   ÚdiscriminantÚrootrL   Útheta_one_minus_thetaÚdenominatorÚderivative_numeratorr|   ÚthetaÚ	numeratorr9   r9   r:   rx   {  sœ   
  ÿ
þÿÿ
ÿþÿ
ÿ
ÿþÿrx   )TT)r   r   F)F)FNr   rn   rn   rn   )r~   )Fr   r   rn   rn   rn   )Fr   r   r   r   rn   rn   rn   )Únumpyr‡   r   Útorch.nn.functionalr   Ú
functionalr[   r;   rA   rP   rU   rD   r}   r]   ry   rx   r9   r9   r9   r:   Ú<module>   s@   

R
T
G
ö
"

ö4ô