o
    piU                     @   s   d Z ddlZddlZddlZddlmZ ejZG dd dZdd Z	dd	 Z
G d
d dZG dd dZdd Zdd Z			dddZG dd dZG dd dZdS )u  A popular speaker recognition/diarization model (LDA and PLDA).

Authors
 * Anthony Larcher 2020
 * Nauman Dawalatabad 2020

Relevant Papers
 - This implementation of PLDA is based on the following papers.

 - PLDA model Training
    * Ye Jiang et. al, "PLDA Modeling in I-Vector and Supervector Space for Speaker Verification," in Interspeech, 2012.
    * Patrick Kenny et. al, "PLDA for speaker verification with utterances of arbitrary duration," in ICASSP, 2013.

 - PLDA scoring (fast scoring)
    * Daniel Garcia-Romero et. al, “Analysis of i-vector length normalization in speaker recognition systems,” in Interspeech, 2011.
    * Weiwei-LIN et. al, "Fast Scoring for PLDA with Uncertainty Propagation," in Odyssey, 2016.
    * Kong Aik Lee et. al, "Multi-session PLDA Scoring of I-vector for Partially Open-Set Speaker Detection," in Interspeech 2013.

Credits
    This code is adapted from: https://projets-lium.univ-lemans.fr/sidekit/
    N)linalgc                   @   s   e Zd ZdZ						d(ddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd)d d!Zd"d# Zd$d% Zd&d' ZdS )*StatObject_SBa  A utility class for PLDA class used for statistics calculations.

    This is also used to pack deep embeddings and meta-information in one object.

    Arguments
    ---------
    modelset : list
        List of model IDs for each session as an array of strings.
    segset : list
        List of session IDs as an array of strings.
    start : int
        Index of the first frame of the segment.
    stop : int
        Index of the last frame of the segment.
    stat0 : torch.Tensor
        An ndarray of float64. Each line contains 0-th order statistics
        from the corresponding session.
    stat1 : torch.Tensor
        An ndarray of float64. Each line contains 1-st order statistics
        from the corresponding session.
    Nc                 C   s   |d u r6t jddd| _t jddd| _t jddd| _t jddd| _t jg td| _t jg td| _	d S || _|| _|| _|| _|| _|| _	d S )Nr   |Odtype)
numpyemptymodelsetsegsetstartstoparray	STAT_TYPEstat0stat1)selfr	   r
   r   r   r   r    r   ]/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/speechbrain/processing/PLDA_LDA.py__init__7   s   

zStatObject_SB.__init__c                 C   s   d}|d| j   d 7 }|d| j  d 7 }|d| j  d 7 }|d| j  d 7 }|d| j  d 7 }|d| j  d 7 }|d7 }|S )	Nz------------------------------
z
modelset: 
zsegset: z
seg start:z	seg stop:zstat0:zstat1:)r	   __repr__r
   r   r   r   r   r   chr   r   r   r   P   s   zStatObject_SB.__repr__c                 C   @   t |d}t| |tj W d   dS 1 sw   Y  dS )zSaves stats in pickle format.

        Arguments
        ---------
        filename : path
            Path where the pickle file will be stored.
        wbNopenpickledumpHIGHEST_PROTOCOL)r   filenameoutputr   r   r   save_stat_object[   s   "zStatObject_SB.save_stat_objectc                 C      | j | j|k S )zReturn segments of a given model.

        Arguments
        ---------
        mod_id : str
            ID of the model for which segments will be returned.

        Returns
        -------
        segments
        )r
   r	   r   mod_idr   r   r   get_model_segsetsf      zStatObject_SB.get_model_segsetsc                 C   r#   )zReturn start of segment of a given model.

        Arguments
        ---------
        mod_id : str
            ID of the model for which start will be returned.

        Returns
        -------
        start of segment
        )r   r	   r$   r   r   r   get_model_startt   r'   zStatObject_SB.get_model_startc                 C   r#   )zReturn stop of segment of a given model.

        Arguments
        ---------
        mod_id : str
            ID of the model which stop will be returned.

        Returns
        -------
        stop of segment
        )r   r	   r$   r   r   r   get_model_stop   r'   zStatObject_SB.get_model_stopc                 C   s   t j| jdd}|S )z*Return the mean of first order statistics.r   axis)r   meanr   )r   mur   r   r   get_mean_stat1   s   zStatObject_SB.get_mean_stat1c                 C   s0   | j | j jdd }t| || j jd  S )z^Compute and return the total covariance matrix of the first-order
        statistics.
        r   r*   )r   r,   r   dot	transposeshape)r   Cr   r   r   get_total_covariance_stat1   s   z(StatObject_SB.get_total_covariance_stat1c                 C   s   | j | j|kddf }|S )zReturn zero-order statistics of a given model

        Arguments
        ---------
        mod_id : str
            ID of the model which stat0 will be returned.

        Returns
        -------
        Zero-order statistics.
        N)r   r	   )r   r%   Sr   r   r   get_model_stat0   s   zStatObject_SB.get_model_stat0c                 C   s   | j | j|kddf S )zReturn first-order statistics of a given model.

        Arguments
        ---------
        mod_id : str
            ID of the model which stat1 will be returned.

        Returns
        -------
        First-order statistics.
        N)r   r	   r$   r   r   r   get_model_stat1   s   zStatObject_SB.get_model_stat1c                 C   s   t  }t| j|_t|j|_tj|jjd | j	jd ft
d|_	tj|jjd | jjd ft
d|_tt| jjd }t|jD ]2\}}| |jdd|j	|ddf< | |jdd|j|ddf< ||  | |jd 7  < qF||fS )a  Sum the zero- and first-order statistics per model and store them
        in a new StatObject_SB.

        Returns
        -------
        a StatObject_SB object with the statistics summed per model
        and a numpy array with session_per_model.
        r      r   r*   N)r   r   uniquer	   copydeepcopyr
   zerosr1   r   r   r   	enumerater5   sumr6   )r   sts_per_modelsession_per_modelidxmodelr   r   r   sum_stat_per_model   s.   	

z StatObject_SB.sum_stat_per_modelc                 C   sZ   | j jd | jjd  }tt| jjd |}| j | jdd|f |t  | _ dS )zCenter first order statistics.

        Arguments
        ---------
        mu : array
            Array to center on.
        r7   N)r   r1   r   r   repeatarangeastyper   )r   r-   dim	index_mapr   r   r   center_stat1   s
   
zStatObject_SB.center_stat1c                 C   s6   t t jj| jdddt j}| j |  | _dS )z:Divide all first-order statistics by their Euclidean norm.r7   r*   g:0yE>N)r   clipr   normr   infr0   )r   	vect_normr   r   r   
norm_stat1   s   zStatObject_SB.norm_stat1c                 C   s   t | j|| _dS )zRotate first-order statistics by a right-product.

        Arguments
        ---------
        R : ndarray
            Matrix to use for right product on the first order statistics.
        N)r   r/   r   )r   Rr   r   r   rotate_stat1   s   zStatObject_SB.rotate_stat1Fc                 C   s*  |j dkr| | | jt|t | _dS |j dkr_|}|sRt|\}}|j	
 ddd }|j	| }|j	dd|f }dt|j	 }t|t|}n	 | | | | dS |j dkr| jjd | jjd  }	| jjd }
| | td| jjd|	|
|d|
j| _dS td)	a2  Whiten first-order statistics
        If sigma.ndim == 1, case of a diagonal covariance.
        If sigma.ndim == 2, case of a single Gaussian with full covariance.
        If sigma.ndim == 3, case of a full covariance UBM.

        Arguments
        ---------
        mu : array
            Mean vector to be subtracted from the statistics.
        sigma : narray
            Co-variance matrix or covariance super-vector.
        isSqrInvSigma : bool
            True if the input Sigma matrix is the inverse of the square root of a covariance matrix.
        r7      N   r   zikj,ikl->iljz(Wrong dimension of Sigma, must be 1 or 2)ndimrH   r   r   sqrtrE   r   r   eighrealargsortr/   diagrO   r1   r   einsumTreshape	Exception)r   r-   sigmaisSqrInvSigmasqr_inv_sigmaeigen_valueseigen_vectorsindsqr_inv_eval_sigmansess_nbr   r   r   whiten_stat1  s8   







	zStatObject_SB.whiten_stat1c                    t   t  fdd|D } j|  _ j|  _ j|  _ j|  _ j|ddf  _ j|ddf  _dS )a?  Align models of the current StatServer to match a list of models
            provided as input parameter. The size of the StatServer might be
            reduced to match the input list of models.

        Arguments
        ---------
        model_list : ndarray of strings
            List of models to match.
        c                    $   g | ]}t  j|kd  d  qS r   )r   argwherer	   .0vr   r   r   
<listcomp>G     $ z.StatObject_SB.align_models.<locals>.<listcomp>Nr   r   r
   r	   r   r   r   r   )r   
model_listindxr   rn   r   align_models<     
zStatObject_SB.align_modelsc                    rg   )aF  Align segments of the current StatServer to match a list of segment
            provided as input parameter. The size of the StatServer might be
            reduced to match the input list of segments.

        Arguments
        ---------
        segment_list: ndarray of strings
            list of segments to match
        c                    rh   ri   )r   rj   r
   rk   rn   r   r   ro   [  rp   z0StatObject_SB.align_segments.<locals>.<listcomp>Nrq   )r   segment_listrs   r   rn   r   align_segmentsP  ru   zStatObject_SB.align_segmentsc                 C   s.  | j jd }t| j}|  }t|jd |f}t||f}d}|D ]4}| |tj| |dd }	|t	|	
 |	|	jd  7 }tj| |dd||ddf< |d7 }q%|| }t	|
 |}
t	|
t|
 }t|\}}|j}|j}|j | d ddd }|dd|f }|S )az  Compute and return the Linear Discriminant Analysis matrix
            on the first-order statistics. Columns of the LDA matrix are ordered
            according to the corresponding eigenvalues in descending order.

        Arguments
        ---------
        rank : int
            Rank of the LDA matrix to return.

        Returns
        -------
        L : matrix
        r7   r   r*   NrQ   )r   r1   r   r8   r	   r.   r;   r6   r,   r/   r0   r   invrU   rV   rW   )r   rank	vect_sizeunique_speakerr-   class_meansSwspk_idx
speaker_idspk_sessionsSbDiscriminationMatrixr`   ra   r@   Lr   r   r   get_lda_matrix_stat1d  s8   


z"StatObject_SB.get_lda_matrix_stat1)NNNNNN)F)__name__
__module____qualname____doc__r   r   r"   r&   r(   r)   r.   r3   r5   r6   rB   rH   rM   rO   rf   rt   rw   r   r   r   r   r   r       s4    
*

:r   c                    s    fdd| D }|   |S )zDifference between lists.c                    s   g | ]}| vr|qS r   r   rl   itemlist2r   r   ro     s    zdiff.<locals>.<listcomp>)sortlist1r   cr   r   r   diff  s   r   c                    s    fdd| D }|S )z7Checks if the elements if list1 are contained in list2.c                    s   g | ]}| v qS r   r   r   r   r   r   ro     s    zismember.<locals>.<listcomp>r   r   r   r   r   ismember  s   r   c                   @   sD   e Zd ZdZdeg eg fddZdd Zdd Zd	d
 Z	dS )Ndxa  A class that encodes trial index information.  It has a list of
    model names and a list of test segment names and a matrix
    indicating which combinations of model and test segment are
    trials of interest.

    Arguments
    ---------
    ndx_file_name : str
        Name of the file to load.
    models : list
        List of unique models in a ndarray.
    testsegs : list
        List of unique test segments in a ndarray.
     c                 C   st  t jddd| _t jddd| _t jg dd| _|dkr|jd |jd  }|dkr]|dkrDt|d }t |g| }t ||f}nt	|}t|d }t |g| }t ||f}t 
|}t 
|}t j|jd |jd fdd}	t|jd D ]}
|t t|||
  }t|||	|
f< q}|| _|| _|	| _|  sJ dd S t|}|j| _|j| _|j| _d S )Nr   r   r   boolr   rQ   Wrong Ndx format)r   r   r	   r
   r   	trialmaskr1   strhstackabsr8   r;   ranger   validater   read)r   ndx_file_namemodelstestsegsdlastpadr	   r
   r   msegsndxr   r   r   r     s<   


zNdx.__init__c                 C   r   )z!Saves the object in pickle formatr   Nr   )r   output_file_namer!   r   r   r   save_ndx_object  s   "zNdx.save_ndx_objectc           
      C   s  |r|}|}nt | j|}t | j|}tt| j|}tt| j|}t }| j| |_| j| |_| jt|ddf }	|	ddt|f |_|jsSJ d| jj	d |jj	d krnt
d| jj	d  |jj	d  | jj	d |jj	d krt
d| jj	d |jj	d  |S )a  Removes some of the information in an Ndx. Useful for creating a
        gender specific Ndx from a pooled gender Ndx.  Depending on the
        value of 'keep', the two input lists indicate the strings to
        retain or the strings to discard.

        Arguments
        ---------
        modlist : array
            A cell array of strings which will be compared with the modelset of 'inNdx'.
        seglist : array
            A cell array of strings which will be compared with the segset of 'inNdx'.
        keep : bool
            Indicating whether modlist and seglist are the models to keep or discard.

        Returns
        -------
        outNdx : Ndx
        Nr   r   z&Number of models reduced from %d to %dz-Number of test segments reduced from %d to %d)r   r	   r
   r   r   r   r   r   r   r1   print)
r   modlistseglistkeepkeepmodskeepsegs
keepmodidx
keepsegidxoutNdxtmpr   r   r   filter  s6   



z
Ndx.filterc                 C   s   t | jtj}|t | jtjM }|t | jtjM }|| jjdkM }|| jjdkM }|| jjdkM }|| jj| jjd | jjd fkM }|S )zChecks that an object of type Ndx obeys certain rules that
        must always be true. Returns a boolean value indicating whether the object is valid
        r7   rP   r   )
isinstancer	   r   ndarrayr
   r   rS   r1   )r   okr   r   r   r     s   

zNdx.validateN)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    
.3r   c                   @   s"   e Zd ZdZdddZdd ZdS )	Scoresa  A class for storing scores for trials.  The modelset and segset
    fields are lists of model and test segment names respectively.
    The element i,j of scoremat and scoremask corresponds to the
    trial involving model i and test segment j.

    Arguments
    ---------
    scores_file_name : str
        Name of a HDF5 file containing the following fields

        modelset : list
            list of unique models in a ndarray.
        segset : list
            list of unique test segments in a ndarray.
        scoremask : 2d ndarray of bool
            indicates the trials of interest, i.e.,
            the entry i,j in scoremat should be ignored if scoremask[i,j] is false.
        scoremat : 2d ndarray
            scores matrix.
    r   c                 C   sv   t jddd| _t jddd| _t jg dd| _t g | _|dkr$d S t|}|j| _|j| _|j| _|j| _d S )Nr   r   r   r   r   )	r   r   r	   r
   r   	scoremaskscorematr   r   )r   scores_file_namer   r   r   r   r   E  s   
zScores.__init__c                 C   s`   d}|| j d 7 }|d7 }|| jd 7 }|d7 }|| j d 7 }|d7 }|| j d 7 }d S )Nz
modelset:
r   zsegset:
zscoremask:
z
scoremat:
)r	   r
   r   r   r   r   r   r   r   r   T  s   zScores.__repr__N)r   )r   r   r   r   r   r   r   r   r   r   r   /  s    
r   c              	   C   sD  |j jd }|jjdkr6|j j|j }t }	t|dddf D ]}
t	
|
| t|jd  |	|
< q"tj|j jd |j jd ftjd}|D ]U}|jjdkrmt	
t||j j|||  ddf  |j  }n
|	|||  df  }|j j|||  ddf }tj|||| d |t|| || | ||< qJdS )a  A function for PLDA estimation.

    Arguments
    ---------
    batch_start : int
        Index to start at in the list.
    mini_batch_indices : list
        Indices of the elements in the list (should start at zero).
    factor_analyser : instance of PLDA class
        PLDA class object.
    stat0 : torch.Tensor
        Matrix of zero-order statistics.
    stat1: torch.Tensor
        Matrix of first-order statistics.
    e_h : torch.Tensor
        An accumulator matrix.
    e_hh: torch.Tensor
        An accumulator matrix.
    r7   rP   Nr   r   )out)Fr1   SigmarS   rZ   r/   dictr   r8   r   rx   eyer;   float64outer)batch_startmini_batch_indicesfactor_analyserr   r   e_he_hhry   Ainv_lambda_uniquesessr   r@   
inv_lambdaauxr   r   r   fa_model_loopb  s4   
 r   c                 C   s.   | | j|jd}| |j ||j |S )NT)r   r	   r
   rt   rw   )enrolltestr   	clean_ndxr   r   r   _check_missing_model  s   r                 ?Tc	           !   	   C   s  t | }	t |}
t|	jj|	jjks|	 }	|r"t|	|
|}n|}|	| |
| t|	jj|	jjks=|	 }	t	
|}tj|jd dd}|j|| |}t	
|| }t	
d| | }tj	|d }tj	|d }|d | }t||j}|| }t	
|}t	
|||| }|| }|||}dtd|	j||	jj }dtd|
j||
jj }t }|j|_|j|_|j|_|ddtjf | | |_| j|	j||
jj7  _| j|9  _|d	krE|jjd	 }t|jj}t|j}t|D ]-} |j| ddf t||t|| k  jd	d
 |d  d|   || ddf< q||_|S )a  Compute the PLDA scores between to sets of vectors. The list of
    trials to perform is given in an Ndx object. PLDA matrices have to be
    pre-computed. i-vectors/x-vectors are supposed to be whitened before.

    Arguments
    ---------
    enroll : speechbrain.utils.Xvector_PLDA_sp.StatObject_SB
        A StatServer in which stat1 are xvectors.
    test : speechbrain.utils.Xvector_PLDA_sp.StatObject_SB
        A StatServer in which stat1 are xvectors.
    ndx : speechbrain.utils.Xvector_PLDA_sp.Ndx
        An Ndx object defining the list of trials to perform.
    mu : double
        The mean vector of the PLDA gaussian.
    F : torch.Tensor
        The between-class co-variance matrix of the PLDA.
    Sigma : torch.Tensor
        The residual covariance matrix.
    p_known : float
        Probability of having a known speaker for open-set
        identification case (=1 for the verification task and =0 for the
        closed-set case).
    scaling_factor : float
        Factor to multiply statistics.
    check_missing : bool
        If True, check that all models and segments exist.

    Returns
    -------
    scores : Scores
    r7   floatr   rP   g       @g      ?z	ij, ji->iNr   r*   )r9   r:   r   r8   r	   r1   mean_stat_per_modelr   rH   r   rx   r   rZ   r/   slogdetrY   r   r   r
   r   r   newaxisr   r   expr   logrD   r=   )!r   r   r   r-   r   r   p_knownscaling_factorcheck_missing
enroll_ctrtest_ctrr   invSigmaI_spkKK1K2alpha1alpha2plda_cstSigma_ac	Sigma_totSigma_tot_invTmpPhiPsi
model_partseg_partscoreNopen_set_scoresr   iir   r   r   fast_PLDA_scoring  sd   
*




 
&r   c                   @   s"   e Zd ZdZdd ZdddZdS )	LDAztA class to perform Linear Discriminant Analysis.

    It returns the low dimensional representation as per LDA.
    c                 C   s
   d | _ d S N)transform_matrn   r   r   r   r   (  s   
zLDA.__init__NrP   c                 C   s6   |du r| || _n|| _t|}|| j |S )a  Performs LDA and projects the vectors onto lower dimension space.

        Arguments
        ---------
        stat_server : object of speechbrain.processing.PLDA_LDA.StatObject_SB.
            Contains vectors and meta-information to perform LDA.
        reduced_dim : int
            Dimension of the reduced space.
        transform_mat : matrix
            Transformation matrix.

        Returns
        -------
        new_train_obj : speechbrain.processing.PLDA_LDA.StatObject_SB
        N)r   r   r9   r:   rO   )r   stat_serverreduced_dimr   new_train_objr   r   r   do_lda+  s   
z
LDA.do_lda)NrP   N)r   r   r   r   r   r   r   r   r   r   r   "  s    r   c                   @   s8   e Zd ZdZ						dddZ				dd	d
ZdS )PLDAa	  A class to train PLDA model from embeddings.

    The input is in speechbrain.utils.StatObject_SB format.
    Trains a simplified PLDA model no within-class covariance matrix but full residual covariance matrix.

    Arguments
    ---------
    mean : torch.Tensor
        Mean of the vectors.
    F : torch.Tensor
        Eigenvoice matrix.
    Sigma : torch.Tensor
        Residual matrix.
    rank_f : int
        Rank (default 100).
    nb_iter : int
        Number of iterations (default 10).
    scaling_factor : int
        Factor to use for scaling statistics (default 1.0).

    Example
    -------
    >>> from speechbrain.processing.PLDA_LDA import *
    >>> import random, numpy
    >>> dim, N = 10, 100
    >>> n_spkrs = 10
    >>> train_xv = numpy.random.rand(N, dim)
    >>> md = ['md'+str(random.randrange(1,n_spkrs,1)) for i in range(N)]
    >>> modelset = numpy.array(md, dtype="|O")
    >>> sg = ['sg'+str(i) for i in range(N)]
    >>> segset = numpy.array(sg, dtype="|O")
    >>> s = numpy.array([None] * N)
    >>> stat0 = numpy.array([[1.0]]* N)
    >>> xvectors_stat = StatObject_SB(modelset=modelset, segset=segset, start=s, stop=s, stat0=stat0, stat1=train_xv)
    >>> # Training PLDA model: M ~ (mean, F, Sigma)
    >>> plda = PLDA(rank_f=5)
    >>> plda.plda(xvectors_stat)
    >>> print (plda.mean.shape)
    (10,)
    >>> print (plda.F.shape)
    (10, 5)
    >>> print (plda.Sigma.shape)
    (10, 10)
    >>> # Enrollment (20 utts), Test (30 utts)
    >>> en_N = 20
    >>> en_xv = numpy.random.rand(en_N, dim)
    >>> en_sgs = ['en'+str(i) for i in range(en_N)]
    >>> en_sets = numpy.array(en_sgs, dtype="|O")
    >>> en_s = numpy.array([None] * en_N)
    >>> en_stat0 = numpy.array([[1.0]]* en_N)
    >>> en_stat = StatObject_SB(modelset=en_sets, segset=en_sets, start=en_s, stop=en_s, stat0=en_stat0, stat1=en_xv)
    >>> te_N = 30
    >>> te_xv = numpy.random.rand(te_N, dim)
    >>> te_sgs = ['te'+str(i) for i in range(te_N)]
    >>> te_sets = numpy.array(te_sgs, dtype="|O")
    >>> te_s = numpy.array([None] * te_N)
    >>> te_stat0 = numpy.array([[1.0]]* te_N)
    >>> te_stat = StatObject_SB(modelset=te_sets, segset=te_sets, start=te_s, stop=te_s, stat0=te_stat0, stat1=te_xv)
    >>> ndx = Ndx(models=en_sets, testsegs=te_sets)
    >>> # PLDA Scoring
    >>> scores_plda = fast_PLDA_scoring(en_stat, te_stat, ndx, plda.mean, plda.F, plda.Sigma)
    >>> print (scores_plda.scoremat.shape)
    (20, 30)
    Nd   
   r   c                 C   sV   d | _ d | _d | _|| _|| _|| _|d ur|| _ |d ur || _|d ur)|| _d S d S r   )r,   r   r   rank_fnb_iterr   )r   r,   r   r   r   r   r   r   r   r   r     s   	
zPLDA.__init__Fc              
   C   sj  |j jd }|du r| }| }||| | | _| | _| \}}	|jjd }
| j	| j
9  _	| j | j
9  _ |	| j
9 }	| }t|\}}t|ddd }|jdd|d| j f }|ddd| jf | _t| jD ]}t|}|| j| j t| j\}}|j ddd }|j| }|jdd|f }dt|j }t|t|}|j| j| _tj|td}|j	dd|f }t|
| jf}t|
| j| jf}tdt|
| ||j ||d tj|dd|	jd  }|j|j t|}t d	||j	! }t"||j| _|| j||	   | _| jt#|| _qwdS )
a2  Trains PLDA model with no within class covariance matrix but full residual covariance matrix.

        Arguments
        ---------
        stat_server : speechbrain.processing.PLDA_LDA.StatObject_SB
            Contains vectors and meta-information to perform PLDA
        output_file_name : str
            Name of the output file where to store PLDA model.
        whiten : bool
            Whether to perform whitening.
        w_stat_server : speechbrain.processing.PLDA_LDA.StatObject_SB
            Contains whitening vectors and meta-information.
        r7   Tr   NrQ   r   )r   r   r   r   r   r   r   r*   z	ijk,i->jk)$r   r1   r.   r3   rf   r,   r   rB   r	   r   r   r   rU   r   rW   rV   r   r   r   r   r9   r:   rT   r/   rX   rZ   r;   intr   rD   r=   rx   rY   squeezesolvecholesky)r   r   r   whitenw_stat_serverrz   w_meanw_Sigmamodel_shifted_statr?   class_nb	sigma_obsevalsevecsr@   it
local_statr`   ra   rb   rc   r_   rG   _stat0r   r   _R_C_Ar   r   r   plda  sb   





z	PLDA.plda)NNNr   r   r   )NNFN)r   r   r   r   r   r  r   r   r   r   r   H  s    C
r   )r   r   T)r   r9   r   r   scipyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s,      { 
3:
{&