class_docstr: Online clustering method for speaker diarization based on cosine similarity.
  
  Regular Clustering Attributes:
  
      max_num_speakers (int):
          The upper bound for the number of speakers in each session
      max_rp_threshold (float):
          Limits the range of parameter search.
          Clustering performance can vary depending on this range.
          Default is 0.15.
      enhanced_count_thres (int):
          For the short audio recordings, clustering algorithm cannot
          accumulate enough amount of speaker profile for each cluster.
          Thus, function `getEnhancedSpeakerCount` employs anchor embeddings
          (dummy representations) to mitigate the effect of cluster sparsity.
          enhanced_count_thres = 40 is recommended.
      sparse_search_volume (int):
          Number of p_values we search during NME analysis.
          Default is 30. The lower the value, the faster NME-analysis becomes.
          Lower than 20 might cause a poor parameter estimation.
      fixed_thres (float):
          A fixed threshold for finding p-closest neighbors in affinity matrix for clustering.
          If fixed_thres value is provided, NME-analysis process will be skipped.
          This value should be optimized on a development set to obtain a quality result.
          Default is None and performs NME-analysis to estimate the threshold.
      min_samples_for_nmesc (int):
          The minimum number of samples required for NME clustering. This avoids
          zero p_neighbour_lists. If the input has fewer segments than min_samples,
          it is directed to the enhanced speaker counting mode.
      sparse_search (bool):
          Toggle sparse search mode. If True, limit the size of p_value_list to sparse_search_volume.
      cuda (bool):
          Use cuda for Eigen decomposition if cuda=True.
  
  Additional Online Processing Attributes:
  
      history_buffer_size (int):
          - This is a buffer where diarization history is saved in the form of averaged speaker embedding vector.
          - The values in [50, 200] range is recommended while the system requires bigger buffer size for
            sessions with larger number of speakers.
      current_buffer_size (int):
          - This is a buffer which process the most recent speaker embedding vector inputs.
            current-buffer is first-in-first-out (FIFO) queue where the embeddings accepted earlier
            get to merged and saved to history buffer.
          - In general, [50, 200] range is recommended and the performance can be sensitive on this buffer size.
      min_spk_counting_buffer_size (int):
          Integer number for speaker counting buffer. Number of speakers are estimated through a small buffer
          and the number is obtained by taking majority vote.
      min_frame_per_spk (int):
          Below this number, the system considers the whole input segments as a single speaker.
      p_update_freq (int):
          Frequency (interval) of updating p_value for NMESC algorithm.
      p_value_skip_frame_thres (int):
          After `frame_index` passes this number, `p_value` estimation is skipped for inference speed
      p_value_queue_size (int):
          `p_value` buffer for major voting
      use_temporal_label_major_vote (bool):
          Boolean that determines whether to use temporal majorvoting for the final speaker labels
      temporal_label_major_vote_buffer_size (int):
          Buffer size for major-voting the
      num_spk_stat (list):
          List of number of speakers for major voting. Number of speakers are estimated through 
          majority voting of `self.num_spk_stat` list.
      p_value_hist (list):
          List of p_values for major voting.
          To save the computation time, p_value is estimated every `p_update_freq` frames and
          saved to `self.p_value_hist`.
  
  Attributes for counters and buffers in streaming system:
      
      is_online (bool):
          - If self.is_online is False:
              FIFO queue does not push out any speaker embedding vector
          - If self.is_online is True:
              FIFO queue starts push out speaker embedding vectors and saving them into
              history buffer.
      max_embed_count (int):
          The maximum number of segments the streaming system has ever seen.
          This value keeps increasing as the system processes more and more segments.
      memory_margin (int):
          The margin that is added to keep the segmentation data in the streaming system
      minimum_segments_per_buffer (int):
          Maximum number of embedding vectors kept in history buffer per speaker.
          Example:
              history_buffer_size (history_n) = 100
              max_num_speakers = 4
              minimum_segments_per_buffer = 25
      history_buffer_seg_end (int):
          Index that indicates the boundary between history embedding sets and current processing buffer
          when history embedding vectors and current input embedding vectors are concatenated into a
          single matrix.
  
  Attributes for history buffer:
  
      history_embedding_buffer_emb (Tensor)
          Tensor containing speaker embedding vectors for saving the history of the previous
          speaker profile in the given audio session
      history_embedding_buffer_label (Tensor)
          Speaker label (cluster label) for embedding vectors saved in the history buffer
      Y_fullhist (Tensor)
          Tensor containing the speaker label hypothesis from start to current frame
class_docstr_tok: ["Online","clustering","method","for","speaker","diarization","based","on","cosine","similarity",".","Regular","Clustering","Attributes",":","max_num_speakers","(","int",")",":","The","upper","bound","for","the","number","of","speakers","in","each","session","max_rp_threshold","(","float",")",":","Limits","the","range","of","parameter","search",".","Clustering","performance","can","vary","depending","on","this","range",".","Default","is","0.15.","enhanced_count_thres","(","int",")",":","For","the","short","audio","recordings",",","clustering","algorithm","can","not","accumulate","enough","amount","of","speaker","profile","for","each","cluster",".","Thus",",","function","`","getEnhancedSpeakerCount","`","employs","anchor","embeddings","(","dummy","representations",")","to","mitigate","the","effect","of","cluster","sparsity",".","enhanced_count_thres","=","40","is","recommended",".","sparse_search_volume","(","int",")",":","Number","of","p_values","we","search","during","NME","analysis",".","Default","is","30",".","The","lower","the","value",",","the","faster","NME-analysis","becomes",".","Lower","than","20","might","cause","a","poor","parameter","estimation",".","fixed_thres","(","float",")",":","A","fixed","threshold","for","finding","p-closest","neighbors","in","affinity","matrix","for","clustering",".","If","fixed_thres","value","is","provided",",","NME-analysis","process","will","be","skipped",".","This","value","should","be","optimized","on","a","development","set","to","obtain","a","quality","result",".","Default","is","None","and","performs","NME-analysis","to","estimate","the","threshold",".","min_samples_for_nmesc","(","int",")",":","The","minimum","number","of","samples","required","for","NME","clustering",".","This","avoids","zero","p_neighbour_lists",".","If","the","input","has","fewer","segments","than","min_samples",",","it","is","directed","to","the","enhanced","speaker","counting","mode",".","sparse_search","(","bool",")",":","Toggle","sparse","search","mode",".","If","True",",","limit","the","size","of","p_value_list","to","sparse_search_volume",".","cuda","(","bool",")",":","Use","cuda","for","Eigen","decomposition","if","cuda=True",".","Additional","Online","Processing","Attributes",":","history_buffer_size","(","int",")",":","-","This","is","a","buffer","where","diarization","history","is","saved","in","the","form","of","averaged","speaker","embedding","vector",".","-","The","values","in","[","50",",","200","]","range","is","recommended","while","the","system","requires","bigger","buffer","size","for","sessions","with","larger","number","of","speakers",".","current_buffer_size","(","int",")",":","-","This","is","a","buffer","which","process","the","most","recent","speaker","embedding","vector","inputs",".","current-buffer","is","first-in-first-out","(","FIFO",")","queue","where","the","embeddings","accepted","earlier","get","to","merged","and","saved","to","history","buffer",".","-","In","general",",","[","50",",","200","]","range","is","recommended","and","the","performance","can","be","sensitive","on","this","buffer","size",".","min_spk_counting_buffer_size","(","int",")",":","Integer","number","for","speaker","counting","buffer",".","Number","of","speakers","are","estimated","through","a","small","buffer","and","the","number","is","obtained","by","taking","majority","vote",".","min_frame_per_spk","(","int",")",":","Below","this","number",",","the","system","considers","the","whole","input","segments","as","a","single","speaker",".","p_update_freq","(","int",")",":","Frequency","(","interval",")","of","updating","p_value","for","NMESC","algorithm",".","p_value_skip_frame_thres","(","int",")",":","After","`","frame_index","`","passes","this","number",",","`","p_value","`","estimation","is","skipped","for","inference","speed","p_value_queue_size","(","int",")",":","`","p_value","`","buffer","for","major","voting","use_temporal_label_major_vote","(","bool",")",":","Boolean","that","determines","whether","to","use","temporal","majorvoting","for","the","final","speaker","labels","temporal_label_major_vote_buffer_size","(","int",")",":","Buffer","size","for","major-voting","the","num_spk_stat","(","list",")",":","List","of","number","of","speakers","for","major","voting",".","Number","of","speakers","are","estimated","through","majority","voting","of","`","self.num_spk_stat","`","list",".","p_value_hist","(","list",")",":","List","of","p_values","for","major","voting",".","To","save","the","computation","time",",","p_value","is","estimated","every","`","p_update_freq","`","frames","and","saved","to","`","self.p_value_hist","`",".","Attributes","for","counters","and","buffers","in","streaming","system",":","is_online","(","bool",")",":","-","If","self.is_online","is","False",":","FIFO","queue","does","not","push","out","any","speaker","embedding","vector","-","If","self.is_online","is","True",":","FIFO","queue","starts","push","out","speaker","embedding","vectors","and","saving","them","into","history","buffer",".","max_embed_count","(","int",")",":","The","maximum","number","of","segments","the","streaming","system","has","ever","seen",".","This","value","keeps","increasing","as","the","system","processes","more","and","more","segments",".","memory_margin","(","int",")",":","The","margin","that","is","added","to","keep","the","segmentation","data","in","the","streaming","system","minimum_segments_per_buffer","(","int",")",":","Maximum","number","of","embedding","vectors","kept","in","history","buffer","per","speaker",".","Example",":","history_buffer_size","(","history_n",")","=","100","max_num_speakers","=","4","minimum_segments_per_buffer","=","25","history_buffer_seg_end","(","int",")",":","Index","that","indicates","the","boundary","between","history","embedding","sets","and","current","processing","buffer","when","history","embedding","vectors","and","current","input","embedding","vectors","are","concatenated","into","a","single","matrix",".","Attributes","for","history","buffer",":","history_embedding_buffer_emb","(","Tensor",")","Tensor","containing","speaker","embedding","vectors","for","saving","the","history","of","the","previous","speaker","profile","in","the","given","audio","session","history_embedding_buffer_label","(","Tensor",")","Speaker","label","(","cluster","label",")","for","embedding","vectors","saved","in","the","history","buffer","Y_fullhist","(","Tensor",")","Tensor","containing","the","speaker","label","hypothesis","from","start","to","current","frame"]
docstr: Choose whether we want to add embeddings to the memory or not.
  The processing buffer has size of (self.current_n + self.history_n).
  
  Case-1: If margin_seg_n > 0, this means we have more embedding vectors than we can hold in the processing buffer.
      - `is_online` should be `True`
      - reduce the number of embedding vectors by merging the closest ones.
          call `update_speaker_history_buffer` function
  
  Case-2: If margin_seg_n <= 0, this means that we can accept more embedding vectors and yet to fill the processing buffer.
      - `is_online` should be `False`
      - Replace `merged_emb` variable with the raw input `emb_in`.
      - `add_new` is `True`, since we are adding more embedding vectors to `merged_emb` variable.
  
  Args:
      emb_in (Tensor):
          If self.is_online is False:
              `emb` contains only current speaker embedding inputs
      base_segment_indexes (Tensor):
          Tensor containing unique segment (embedding vector) index
  
  Returns:
      merged_emb (Tensor):
          Matrix containing merged embedding vectors of the previous frames.
          This matrix is referred to as "history buffer" in this class.
          If self.is_online is False:
              `merged_emb` contains only current speaker embedding inputs
          If self.is_online is True:
              `merged_emb` is a concatenated matrix with history embedding and current embedding inputs
      add_new (bool):
          Boolean that indicates whether there is a new set of segments. Depending on the VAD timestamps,
          the number of subsegments can be ocassionally decreased. If `add_new=True`, then it adds the newly
          acquired cluster labels.
docstr_tok: ["Choose","whether","we","want","to","add","embeddings","to","the","memory","or","not",".","The","processing","buffer","has","size","of","(","self.current_n","+","self.history_n",")",".","Case-1",":","If","margin_seg_n",">","0",",","this","means","we","have","more","embedding","vectors","than","we","can","hold","in","the","processing","buffer",".","-","`","is_online","`","should","be","`","True","`","-","reduce","the","number","of","embedding","vectors","by","merging","the","closest","ones",".","call","`","update_speaker_history_buffer","`","function","Case-2",":","If","margin_seg_n","<","=","0",",","this","means","that","we","can","accept","more","embedding","vectors","and","yet","to","fill","the","processing","buffer",".","-","`","is_online","`","should","be","`","False","`","-","Replace","`","merged_emb","`","variable","with","the","raw","input","`","emb_in","`",".","-","`","add_new","`","is","`","True","`",",","since","we","are","adding","more","embedding","vectors","to","`","merged_emb","`","variable",".","Args",":","emb_in","(","Tensor",")",":","If","self.is_online","is","False",":","`","emb","`","contains","only","current","speaker","embedding","inputs","base_segment_indexes","(","Tensor",")",":","Tensor","containing","unique","segment","(","embedding","vector",")","index","Returns",":","merged_emb","(","Tensor",")",":","Matrix","containing","merged","embedding","vectors","of","the","previous","frames",".","This","matrix","is","referred","to","as","``","history","buffer","''","in","this","class",".","If","self.is_online","is","False",":","`","merged_emb","`","contains","only","current","speaker","embedding","inputs","If","self.is_online","is","True",":","`","merged_emb","`","is","a","concatenated","matrix","with","history","embedding","and","current","embedding","inputs","add_new","(","bool",")",":","Boolean","that","indicates","whether","there","is","a","new","set","of","segments",".","Depending","on","the","VAD","timestamps",",","the","number","of","subsegments","can","be","ocassionally","decreased",".","If","`","add_new=True","`",",","then","it","adds","the","newly","acquired","cluster","labels","."]
code: def get_reduced_mat(
      self, emb_in: torch.Tensor, base_segment_indexes: torch.Tensor
  ) -> Tuple[torch.Tensor, bool]:
      """
      Choose whether we want to add embeddings to the memory or not.
      The processing buffer has size of (self.current_n + self.history_n).
  
      Case-1: If margin_seg_n > 0, this means we have more embedding vectors than we can hold in the processing buffer.
          - `is_online` should be `True`
          - reduce the number of embedding vectors by merging the closest ones.
              call `update_speaker_history_buffer` function
  
      Case-2: If margin_seg_n <= 0, this means that we can accept more embedding vectors and yet to fill the processing buffer.
          - `is_online` should be `False`
          - Replace `merged_emb` variable with the raw input `emb_in`.
          - `add_new` is `True`, since we are adding more embedding vectors to `merged_emb` variable.
  
      Args:
          emb_in (Tensor):
              If self.is_online is False:
                  `emb` contains only current speaker embedding inputs
          base_segment_indexes (Tensor):
              Tensor containing unique segment (embedding vector) index
  
      Returns:
          merged_emb (Tensor):
              Matrix containing merged embedding vectors of the previous frames.
              This matrix is referred to as "history buffer" in this class.
              If self.is_online is False:
                  `merged_emb` contains only current speaker embedding inputs
              If self.is_online is True:
                  `merged_emb` is a concatenated matrix with history embedding and current embedding inputs
          add_new (bool):
              Boolean that indicates whether there is a new set of segments. Depending on the VAD timestamps,
              the number of subsegments can be ocassionally decreased. If `add_new=True`, then it adds the newly
              acquired cluster labels.
      """
      margin_seg_n = emb_in.shape[0] - (self.current_n + self.history_n)
      if len(self.Y_fullhist) == 0 and margin_seg_n > 0:
          raise ValueError(
              "The number of incoming embedding vectors is larger than the total processing buffer size."
              "Please either (1) increase the history and current buffer size (2) or use longer segment lengths to reduce number of segments."
          )
      if margin_seg_n > 0:
          self.is_online = True
          merged_emb, add_new = self.update_speaker_history_buffer(
              emb_in=emb_in, base_segment_indexes=base_segment_indexes
          )
      else:
          self.is_online = False
          merged_emb = emb_in
          add_new = True
      return merged_emb, add_new
  
imports: from typing import List, Tuple
  import torch
  from nemo.collections.asr.parts.utils.offline_clustering import NMESC, SpeakerClustering, SpectralClustering, get_scale_interpolated_embs, getAffinityGraphMat, getCosAffinityMatrix, split_input_data
  from nemo.collections.asr.parts.utils.optimization_utils import linear_sum_assignment
label_desc: Use image node_id 9 for calling the OnlineSpeakerClustering obj's underlying member method code with example usage: obj.get_reduced_mat(emb_in, base_segment_indexes) and returns: merged_emb,  add_new