o
    i1                     @   st   d dl Z d dlmZmZm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 d dlmZ G dd	 d	eZdS )
    N)DictListUnion)ComplexTensor)einsum)stack)
AbsEnhLoss)AbsLossWrapperc                       s|   e Zd Z	ddedef fddZedd Zdd	 Zi fd
e	e
ej e
e f de	e
ej e
e f defddZ  ZS )MixITSolver      ?	criterionweightc                    s   t    || _|| _dS )zMixture Invariant Training Solver.

        Args:
            criterion (AbsEnhLoss): an instance of AbsEnhLoss
            weight (float): weight (between 0 and 1) of current loss
                for multi-task learning.
        N)super__init__r   r   )selfr   r   	__class__ Z/home/ubuntu/.local/lib/python3.10/site-packages/espnet2/enh/loss/wrappers/mixit_solver.pyr      s   

zMixITSolver.__init__c                 C   s   dS )Nmixitr   )r   r   r   r   name   s   zMixITSolver.namec                 G   s4   |D ]}t |tst|t|}qt|g|R  S N)
isinstancer   torch
zeros_likecomplex_einsum)r   equationoperandsopr   r   r   _complex_einsum"   s
   
zMixITSolver._complex_einsumrefinfothersc                    s  t |}|d |d j t|d t}|t|d tksJ |s7tj|d ddtj|dd}tj}nt|d ddt|dd}j}t	t
jt|d}tj fdd|D dd|j}	| d	kru|d
|	|n| d	kr|d|	|g }
t|	jd D ]|
tfddtD   qtj|
dd}
tj|
dd\}}| }t|	d|}| r|j}t }| |jj dj < | |d|ifS )a  MixIT solver.

        Args:
            ref (List[torch.Tensor]): [(batch, ...), ...] x n_spk
            inf (List[torch.Tensor]): [(batch, ...), ...] x n_est
        Returns:
            loss: (torch.Tensor): minimum loss with the best permutation
            stats: dict, for collecting training status
            others: dict, in this PIT solver, permutation order will be returned
           r   N   )dim)repeatc                    s4   g | ]}t jjjt j|t j d dddqS ))dtypedevice)num_classesr$   r   )r   nn
functionalone_hottensorint64	transpose).0asm)r(   num_refr   r   
<listcomp>N   s    z'MixITSolver.forward.<locals>.<listcomp>   zari,bil->abrlzari,bil...->abrl...c              	      s2   g | ]} d d |f  d d |f qS r   )r   )r0   s)est_sum_mixturei
ref_tensorr   r   r   r3   f   s    $_perm)lenr(   r   r   r   r   r   complex_stackr   list	itertoolsproductrangetor'   r%   shapeappendsumminmeanindex_select
is_complexrealdictdetachr   r   )r   r    r!   r"   num_infrH   
inf_tensor	einsum_fnall_assignmentsall_mixture_matrixlosseslossr:   statsr   )r(   r6   r7   r2   r8   r   r   forward(   sb   
		zMixITSolver.forward)r   )__name__
__module____qualname__r   floatr   propertyr   r   r   r   r   Tensorr   r   rT   __classcell__r   r   r   r   r
      s$    

r
   )r>   typingr   r   r   r   torch_complex.tensorr    espnet2.enh.layers.complex_utilsr   r   r   r<   $espnet2.enh.loss.criterions.abs_lossr   %espnet2.enh.loss.wrappers.abs_wrapperr	   r
   r   r   r   r   <module>   s    