code: def compute_py_inv_noise_matrix(
      ps, noise_matrix
  ) -> Tuple[np.ndarray, np.ndarray]:
      """Compute py := P(true_label=k), and the inverse noise matrix.
  
      Parameters
      ----------
      ps : np.ndarray
          Array of shape ``(K, )`` or ``(1, K)``.
          The fraction (prior probability) of each observed, NOISY class ``P(labels = k)``.
  
      noise_matrix : np.ndarray
          A conditional probability matrix (of shape ``(K, K)``) of the form ``P(label=k_s|true_label=k_y)`` containing
          the fraction of examples in every class, labeled as every other class.
          Assumes columns of noise_matrix sum to 1."""
  
      # 'py' is p(true_labels=k) = noise_matrix^(-1) * p(labels=k)
      # because in *vector computation*: P(label=k|true_label=k) * p(true_label=k) = P(label=k)
      # The pseudo-inverse is used when noise_matrix is not invertible.
      py = np.linalg.inv(noise_matrix).dot(ps)
  
      # No class should have probability 0, so we use .000001
      # Make sure valid probabilities that sum to 1.0
      py = clip_values(
          py, low=CLIPPING_LOWER_BOUND, high=1.0, new_sum=1.0
      )
  
      # All the work is done in this function (below)
      return py, compute_inv_noise_matrix(
          py=py, noise_matrix=noise_matrix, ps=ps
      )
  
file_path: cleanlab/cleanlab/internal/latent_algebra.py
imports: import warnings
  import numpy
  from typing import Tuple
  from cleanlab.internal.util import value_counts, clip_values, clip_noise_rates
  from cleanlab.internal.constants import TINY_VALUE, CLIPPING_LOWER_BOUND
label_desc: Use image node_id 2 for calling a global function with example usage: compute_py_inv_noise_matrix(ps, noise_matrix) and returns: py,  compute_inv_noise_matrix