class_docstr: Implements top-p (nucleus) sampling for document filtering based on cumulative probability scores.
  
  This class provides functionality to filter a list of documents by selecting those whose scores fall
  within the top 'p' percent of the cumulative distribution. The method is useful for focusing on high-probability
  documents while filtering out less relevant ones based on their assigned scores.
  
  Usage example:
  
  ```python
  from haystack import Document
  from haystack.components.samplers import TopPSampler
  
  sampler = TopPSampler(top_p=0.95, score_field="similarity_score")
  docs = [
      Document(text="Berlin", meta={"similarity_score": -10.6}),
      Document(text="Belgrade", meta={"similarity_score": -8.9}),
      Document(text="Sarajevo", meta={"similarity_score": -4.6}),
  ]
  output = sampler.run(documents=docs)
  docs = output["documents"]
  assert len(docs) == 1
  assert docs[0].content == "Sarajevo"
  ```
docstr: Filters documents using top-p sampling based on their scores.
  
  :param documents: List of Document objects to be filtered.
  :param top_p: Optional. A float to override the cumulative probability threshold set during initialization.
           If None, the class's top_p value is used.
  :return: A dictionary with a key 'documents' containing the list of filtered Document objects.
  
  This method applies top-p sampling to filter out documents. It selects those documents whose similarity scores
  are within the top 'p' percent of the cumulative distribution, based on the specified or default top_p value.
  
  If the specified top_p results in no documents being selected (especially in cases of a low top_p value), the
  method defaults to returning the document with the highest similarity score.
  
  :raises ValueError: If the top_p value is not within the range [0, 1].
docstr_tok: ["Filters","documents","using","top-p","sampling","based","on","their","scores",".",":","param","documents",":","List","of","Document","objects","to","be","filtered",".",":","param","top_p",":","Optional",".","A","float","to","override","the","cumulative","probability","threshold","set","during","initialization",".","If","None",",","the","class","'s","top_p","value","is","used",".",":","return",":","A","dictionary","with","a","key","'documents","'","containing","the","list","of","filtered","Document","objects",".","This","method","applies","top-p","sampling","to","filter","out","documents",".","It","selects","those","documents","whose","similarity","scores","are","within","the","top","'","p","'","percent","of","the","cumulative","distribution",",","based","on","the","specified","or","default","top_p","value",".","If","the","specified","top_p","results","in","no","documents","being","selected","(","especially","in","cases","of","a","low","top_p","value",")",",","the","method","defaults","to","returning","the","document","with","the","highest","similarity","score",".",":","raises","ValueError",":","If","the","top_p","value","is","not","within","the","range","[","0",",","1","]","."]
code: def run(
      self, documents: List[Document], top_p: Optional[float] = None
  ):
      """
      Filters documents using top-p sampling based on their scores.
  
      :param documents: List of Document objects to be filtered.
      :param top_p: Optional. A float to override the cumulative probability threshold set during initialization.
               If None, the class's top_p value is used.
      :return: A dictionary with a key 'documents' containing the list of filtered Document objects.
  
      This method applies top-p sampling to filter out documents. It selects those documents whose similarity scores
      are within the top 'p' percent of the cumulative distribution, based on the specified or default top_p value.
  
      If the specified top_p results in no documents being selected (especially in cases of a low top_p value), the
      method defaults to returning the document with the highest similarity score.
  
      :raises ValueError: If the top_p value is not within the range [0, 1].
      """
      if not documents:
          return {"documents": []}
  
      top_p = (
          top_p or self.top_p or 1.0
      )  # default to 1.0 if both are None
  
      if not 0 <= top_p <= 1:
          raise ValueError(
              f"top_p must be between 0 and 1. Got {top_p}."
          )
  
      similarity_scores = torch.tensor(
          self._collect_scores(documents), dtype=torch.float32
      )
  
      # Apply softmax normalization to the similarity scores
      probs = torch.nn.functional.softmax(similarity_scores, dim=-1)
  
      # Sort the probabilities and calculate their cumulative sum
      sorted_probs, sorted_indices = torch.sort(probs, descending=True)
      cumulative_probs = torch.cumsum(sorted_probs, dim=-1)
  
      # Check if the cumulative probabilities are close to top_p with a 1e-6 tolerance
      close_to_top_p = torch.isclose(
          cumulative_probs,
          torch.tensor(top_p, device=cumulative_probs.device),
          atol=1e-6,
      )
  
      # Combine the close_to_top_p with original condition using logical OR
      condition = (cumulative_probs <= top_p) | close_to_top_p
  
      # Find the indices with cumulative probabilities that exceed top_p
      top_p_indices = torch.where(torch.BoolTensor(condition))[0]
  
      # Map the selected indices back to their original indices
      original_indices = sorted_indices[top_p_indices]
      selected_docs = [documents[i.item()] for i in original_indices]
  
      # If low p resulted in no documents being selected, then
      # return at least one document
      if not selected_docs:
          logger.warning(
              "Top-p sampling with p=%s resulted in no documents being selected. "
              "Returning the document with the highest similarity score.",
              top_p,
          )
          highest_prob_indices = torch.argsort(probs, descending=True)
          selected_docs = [
              documents[int(highest_prob_indices[0].item())]
          ]
  
      return {"documents": selected_docs}
  
imports: import logging
  from typing import List, Optional
  from haystack import ComponentError, Document, component
  from haystack.lazy_imports import LazyImport
label_desc: Use image node_id 2 for calling the TopPSampler obj's underlying member method code with example usage: obj.run(documents, top_p) and returns: dict, dict