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: Merge the given embedding vectors based on the calculate affinity matrix.
  if `is_update` is True, update the history buffer .
  
  Args:
      emb_in (Tensor):
          If self.is_online is False:
              `emb` contains only current speaker embedding inputs, which is FIFO queue
          If self.is_online is True:
              `emb` contains history buffer and FIFO queue
      base_segment_indexes (Tensor):
          Tensor containing unique segment (embedding vector) index
  
  Returns:
      history_embedding_buffer_emb (Tensor):
          Matrix containing merged embedding vectors of the previous frames.
          This matrix is referred to as "history buffer" in this class.
      is_update (bool):
          Boolean indicates whether to update speaker
  
  Example:
  
      at the frame index where `is_online` turns to True:
  
      |------hist-buffer------|-----FIFO-queue-----|
  
      self.history_n = 20
      self.current_n = 10
  
      Step (1)
      |-----------------------|ABCDEF--------------|
  
      If we get two more segments, "NN" as in the description:
      history buffer = 20
      current buffer = 12
  
      Step (2)
      |-----------------------|ABCDEF--------------XY|
                              |---------emb_in-------| 
  
      The newly accepted embeddings go through a FIFO queue (first come, first merge)
      history buffer = 22
      current buffer = 10
  
      Step (3)
      |-----------------------AB|CDEF--------------XY|
      |---------pre_embs--------|
  
      After merging (reducing) the embedding set gets back to the original size:
      history buffer = 20
      current buffer = 10
  
      Step (4)
      |======================|CDEF--------------XY|
      |-----hist_emb_buff----|
      
      After clustering, `self.Y_fullhist` is updated as:
  
      |0000000000011111111111|11110000110010010011|
  
      The dimension of `self.Y_fullhist` is (`history_n + current_n`) x 1
  
  self.history_buffer_seg_end (int):
      The total number of segments that have been merged from the beginning of the session.
      (=`hist_curr_boundary`)
docstr_tok: ["Merge","the","given","embedding","vectors","based","on","the","calculate","affinity","matrix",".","if","`","is_update","`","is","True",",","update","the","history","buffer",".","Args",":","emb_in","(","Tensor",")",":","If","self.is_online","is","False",":","`","emb","`","contains","only","current","speaker","embedding","inputs",",","which","is","FIFO","queue","If","self.is_online","is","True",":","`","emb","`","contains","history","buffer","and","FIFO","queue","base_segment_indexes","(","Tensor",")",":","Tensor","containing","unique","segment","(","embedding","vector",")","index","Returns",":","history_embedding_buffer_emb","(","Tensor",")",":","Matrix","containing","merged","embedding","vectors","of","the","previous","frames",".","This","matrix","is","referred","to","as","``","history","buffer","''","in","this","class",".","is_update","(","bool",")",":","Boolean","indicates","whether","to","update","speaker","Example",":","at","the","frame","index","where","`","is_online","`","turns","to","True",":","|","--","--","--","hist-buffer","--","--","--","|","--","--","-FIFO-queue","--","--","-|","self.history_n","=","20","self.current_n","=","10","Step","(","1",")","|","--","--","--","--","--","--","--","--","--","--","--","-|ABCDEF","--","--","--","--","--","--","--","|","If","we","get","two","more","segments",",","``","NN","''","as","in","the","description",":","history","buffer","=","20","current","buffer","=","12","Step","(","2",")","|","--","--","--","--","--","--","--","--","--","--","--","-|ABCDEF","--","--","--","--","--","--","--","XY|","|","--","--","--","--","-emb_in","--","--","--","-|","The","newly","accepted","embeddings","go","through","a","FIFO","queue","(","first","come",",","first","merge",")","history","buffer","=","22","current","buffer","=","10","Step","(","3",")","|","--","--","--","--","--","--","--","--","--","--","--","-AB|CDEF","--","--","--","--","--","--","--","XY|","|","--","--","--","--","-pre_embs","--","--","--","--","|","After","merging","(","reducing",")","the","embedding","set","gets","back","to","the","original","size",":","history","buffer","=","20","current","buffer","=","10","Step","(","4",")","|======================|CDEF","--","--","--","--","--","--","--","XY|","|","--","--","-hist_emb_buff","--","--","|","After","clustering",",","`","self.Y_fullhist","`","is","updated","as",":","|0000000000011111111111|11110000110010010011|","The","dimension","of","`","self.Y_fullhist","`","is","(","`","history_n","+","current_n","`",")","x","1","self.history_buffer_seg_end","(","int",")",":","The","total","number","of","segments","that","have","been","merged","from","the","beginning","of","the","session",".","(","=","`","hist_curr_boundary","`",")"]
code: def update_speaker_history_buffer(
      self, emb_in: torch.Tensor, base_segment_indexes: torch.Tensor
  ) -> Tuple[torch.Tensor, bool]:
      """
      Merge the given embedding vectors based on the calculate affinity matrix.
      if `is_update` is True, update the history buffer .
  
      Args:
          emb_in (Tensor):
              If self.is_online is False:
                  `emb` contains only current speaker embedding inputs, which is FIFO queue
              If self.is_online is True:
                  `emb` contains history buffer and FIFO queue
          base_segment_indexes (Tensor):
              Tensor containing unique segment (embedding vector) index
  
      Returns:
          history_embedding_buffer_emb (Tensor):
              Matrix containing merged embedding vectors of the previous frames.
              This matrix is referred to as "history buffer" in this class.
          is_update (bool):
              Boolean indicates whether to update speaker
  
      Example:
  
          at the frame index where `is_online` turns to True:
  
          |------hist-buffer------|-----FIFO-queue-----|
  
          self.history_n = 20
          self.current_n = 10
  
          Step (1)
          |-----------------------|ABCDEF--------------|
  
          If we get two more segments, "NN" as in the description:
          history buffer = 20
          current buffer = 12
  
          Step (2)
          |-----------------------|ABCDEF--------------XY|
                                  |---------emb_in-------|
  
          The newly accepted embeddings go through a FIFO queue (first come, first merge)
          history buffer = 22
          current buffer = 10
  
          Step (3)
          |-----------------------AB|CDEF--------------XY|
          |---------pre_embs--------|
  
          After merging (reducing) the embedding set gets back to the original size:
          history buffer = 20
          current buffer = 10
  
          Step (4)
          |======================|CDEF--------------XY|
          |-----hist_emb_buff----|
  
          After clustering, `self.Y_fullhist` is updated as:
  
          |0000000000011111111111|11110000110010010011|
  
          The dimension of `self.Y_fullhist` is (`history_n + current_n`) x 1
  
      self.history_buffer_seg_end (int):
          The total number of segments that have been merged from the beginning of the session.
          (=`hist_curr_boundary`)
      """
      (
          is_update,
          new_emb_n,
          pre_embs,
          pre_clus_labels,
      ) = self.prepare_embedding_update(emb_in, base_segment_indexes)
  
      # Update the history/current_buffer boundary cursor
      total_emb, total_cluster_labels = [], []
  
      if is_update:
          # Calculate how many embedding vectors should be reduced per speaker
          class_target_vol = get_merge_quantity(
              num_to_be_removed=new_emb_n,
              pre_clus_labels=pre_clus_labels,
              min_count_per_cluster=self.minimum_segments_per_buffer,
          )
  
          # Merge the segments in the history buffer
          for spk_idx, sub_cluster_num in enumerate(
              list(class_target_vol)
          ):
              merged_embs, merged_clus_labels, _ = run_reducer(
                  pre_embs=pre_embs,
                  target_spk_idx=spk_idx,
                  merge_quantity=sub_cluster_num.item(),
                  pre_clus_labels=pre_clus_labels,
              )
              total_emb.append(merged_embs)
              total_cluster_labels.append(merged_clus_labels)
  
          # Update the speaker history buffer
          self.history_embedding_buffer_emb = torch.vstack(total_emb)
          self.history_embedding_buffer_label = torch.hstack(
              total_cluster_labels
          )
          if (
              self.history_embedding_buffer_emb.shape[0]
              != self.history_n
          ):
              raise ValueError(
                  "History embedding size is not maintained correctly."
              )
          if len(self.history_embedding_buffer_label) != self.history_n:
              raise ValueError(
                  "History label size is not maintained correctly."
              )
  
      else:
          total_emb.append(self.history_embedding_buffer_emb)
          total_cluster_labels.append(
              self.history_embedding_buffer_label
          )
  
      # `emb_curr` is the incumbent set of embeddings which is the the latest.
      emb_curr = self.make_constant_length_emb(
          emb_in, base_segment_indexes
      )
      total_emb.append(emb_curr)
  
      # Before perform clustering, we attach the current_n number of estimated speaker labels
      # from the previous clustering result.
      total_cluster_labels.append(self.Y_fullhist[-self.current_n :])
  
      history_and_current_emb = torch.vstack(total_emb)
      history_and_current_labels = torch.hstack(total_cluster_labels)
      if history_and_current_emb.shape[0] != len(
          history_and_current_labels
      ):
          raise ValueError(
              "`history_and_current_emb` has a mismatch in length with `history_and_current_labels`."
          )
      return history_and_current_emb, is_update
  
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 8 for calling the OnlineSpeakerClustering obj's underlying member method code with example usage: obj.update_speaker_history_buffer(emb_in, base_segment_indexes) and returns: history_and_current_emb,  is_update