code: def interp_decomp(A, eps_or_k, rand=True):
      """
      Compute ID of a matrix.
  
      An ID of a matrix `A` is a factorization defined by a rank `k`, a column
      index array `idx`, and interpolation coefficients `proj` such that::
  
          numpy.dot(A[:,idx[:k]], proj) = A[:,idx[k:]]
  
      The original matrix can then be reconstructed as::
  
          numpy.hstack([A[:,idx[:k]],
                                      numpy.dot(A[:,idx[:k]], proj)]
                                  )[:,numpy.argsort(idx)]
  
      or via the routine :func:`reconstruct_matrix_from_id`. This can
      equivalently be written as::
  
          numpy.dot(A[:,idx[:k]],
                              numpy.hstack([numpy.eye(k), proj])
                            )[:,np.argsort(idx)]
  
      in terms of the skeleton and interpolation matrices::
  
          B = A[:,idx[:k]]
  
      and::
  
          P = numpy.hstack([numpy.eye(k), proj])[:,np.argsort(idx)]
  
      respectively. See also :func:`reconstruct_interp_matrix` and
      :func:`reconstruct_skel_matrix`.
  
      The ID can be computed to any relative precision or rank (depending on the
      value of `eps_or_k`). If a precision is specified (`eps_or_k < 1`), then
      this function has the output signature::
  
          k, idx, proj = interp_decomp(A, eps_or_k)
  
      Otherwise, if a rank is specified (`eps_or_k >= 1`), then the output
      signature is::
  
          idx, proj = interp_decomp(A, eps_or_k)
  
      ..  This function automatically detects the form of the input parameters
          and passes them to the appropriate backend. For details, see
          :func:`backend.iddp_id`, :func:`backend.iddp_aid`,
          :func:`backend.iddp_rid`, :func:`backend.iddr_id`,
          :func:`backend.iddr_aid`, :func:`backend.iddr_rid`,
          :func:`backend.idzp_id`, :func:`backend.idzp_aid`,
          :func:`backend.idzp_rid`, :func:`backend.idzr_id`,
          :func:`backend.idzr_aid`, and :func:`backend.idzr_rid`.
  
      Parameters
      ----------
      A : :class:`numpy.ndarray` or :class:`scipy.sparse.linalg.LinearOperator` with `rmatvec`
          Matrix to be factored
      eps_or_k : float or int
          Relative error (if `eps_or_k < 1`) or rank (if `eps_or_k >= 1`) of
          approximation.
      rand : bool, optional
          Whether to use random sampling if `A` is of type :class:`numpy.ndarray`
          (randomized algorithms are always used if `A` is of type
          :class:`scipy.sparse.linalg.LinearOperator`).
  
      Returns
      -------
      k : int
          Rank required to achieve specified relative precision if
          `eps_or_k < 1`.
      idx : :class:`numpy.ndarray`
          Column index array.
      proj : :class:`numpy.ndarray`
          Interpolation coefficients.
      """
      from scipy.sparse.linalg import LinearOperator
  
      real = _is_real(A)
  
      if isinstance(A, np.ndarray):
          if eps_or_k < 1:
              eps = eps_or_k
              if rand:
                  if real:
                      k, idx, proj = backend.iddp_aid(eps, A)
                  else:
                      k, idx, proj = backend.idzp_aid(eps, A)
              else:
                  if real:
                      k, idx, proj = backend.iddp_id(eps, A)
                  else:
                      k, idx, proj = backend.idzp_id(eps, A)
              return k, idx - 1, proj
          else:
              k = int(eps_or_k)
              if rand:
                  if real:
                      idx, proj = backend.iddr_aid(A, k)
                  else:
                      idx, proj = backend.idzr_aid(A, k)
              else:
                  if real:
                      idx, proj = backend.iddr_id(A, k)
                  else:
                      idx, proj = backend.idzr_id(A, k)
              return idx - 1, proj
      elif isinstance(A, LinearOperator):
          m, n = A.shape
          matveca = A.rmatvec
          if eps_or_k < 1:
              eps = eps_or_k
              if real:
                  k, idx, proj = backend.iddp_rid(eps, m, n, matveca)
              else:
                  k, idx, proj = backend.idzp_rid(eps, m, n, matveca)
              return k, idx - 1, proj
          else:
              k = int(eps_or_k)
              if real:
                  idx, proj = backend.iddr_rid(m, n, matveca, k)
              else:
                  idx, proj = backend.idzr_rid(m, n, matveca, k)
              return idx - 1, proj
      else:
          raise _TYPE_ERROR
  
file_path: catboost/contrib/python/scipy/py2/scipy/linalg/interpolative.py
imports: import scipy.linalg._interpolative_backend
  import numpy
label_desc: Use image node_id 4 for calling a global function with example usage: interp_decomp(A, eps_or_k, rand) and returns: k,  unknown,  proj, unknown,  proj, k,  unknown,  proj, unknown,  proj