code: def eig(ctx, A, left=False, right=True, overwrite_a=False):
      """
      This routine computes the eigenvalues and optionally the left and right
      eigenvectors of a square matrix A. Given A, a vector E and matrices ER
      and EL are calculated such that
  
                          A ER[:,i] =         E[i] ER[:,i]
                  EL[i,:] A         = EL[i,:] E[i]
  
      E contains the eigenvalues of A. The columns of ER contain the right eigenvectors
      of A whereas the rows of EL contain the left eigenvectors.
  
  
      input:
        A           : a real or complex square matrix of shape (n, n)
        left        : if true, the left eigenvectors are calculated.
        right       : if true, the right eigenvectors are calculated.
        overwrite_a : if true, allows modification of A which may improve
                      performance. if false, A is not modified.
  
      output:
        E    : a list of length n containing the eigenvalues of A.
        ER   : a matrix whose columns contain the right eigenvectors of A.
        EL   : a matrix whose rows contain the left eigenvectors of A.
  
      return values:
         E            if left and right are both false.
        (E, ER)       if right is true and left is false.
        (E, EL)       if left is true and right is false.
        (E, EL, ER)   if left and right are true.
  
  
      examples:
        >>> from mpmath import mp
        >>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
        >>> E, ER = mp.eig(A)
        >>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0]))
        [0.0]
        [0.0]
        [0.0]
  
        >>> E, EL, ER = mp.eig(A,left = True, right = True)
        >>> E, EL, ER = mp.eig_sort(E, EL, ER)
        >>> mp.nprint(E)
        [2.0, 4.0, 9.0]
        >>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0]))
        [0.0]
        [0.0]
        [0.0]
        >>> print(mp.chop( EL[0,:] * A - EL[0,:] * E[0]))
        [0.0  0.0  0.0]
  
      warning:
       - If there are multiple eigenvalues, the eigenvectors do not necessarily
         span the whole vectorspace, i.e. ER and EL may have not full rank.
         Furthermore in that case the eigenvectors are numerical ill-conditioned.
       - In the general case the eigenvalues have no natural order.
  
      see also:
        - eigh (or eigsy, eighe) for the symmetric eigenvalue problem.
        - eig_sort for sorting of eigenvalues and eigenvectors
      """
  
      n = A.rows
  
      if n == 1:
          if left and (not right):
              return ([A[0]], ctx.matrix([[1]]))
  
          if right and (not left):
              return ([A[0]], ctx.matrix([[1]]))
  
          return ([A[0]], ctx.matrix([[1]]), ctx.matrix([[1]]))
  
      if not overwrite_a:
          A = A.copy()
  
      T = ctx.zeros(n, 1)
  
      hessenberg_reduce_0(ctx, A, T)
  
      if left or right:
          Q = A.copy()
          hessenberg_reduce_1(ctx, Q, T)
      else:
          Q = False
  
      for x in xrange(n):
          for y in xrange(x + 2, n):
              A[y, x] = 0
  
      hessenberg_qr(ctx, A, Q)
  
      E = [0 for i in xrange(n)]
      for i in xrange(n):
          E[i] = A[i, i]
  
      if not (left or right):
          return E
  
      if left:
          EL = eig_tr_l(ctx, A)
          EL = EL * Q.transpose_conj()
  
      if right:
          ER = eig_tr_r(ctx, A)
          ER = Q * ER
  
      if left and (not right):
          return (E, EL)
  
      if right and (not left):
          return (E, ER)
  
      return (E, EL, ER)
  
file_path: catboost/contrib/python/mpmath/py3/mpmath/matrices/eigen.py
imports: from ..libmp.backend import xrange
label_desc: Use image node_id 10 for calling a global function with example usage: eig(ctx, A, left, right, overwrite_a) and returns: E,  EL,  ER, list,  ctx,  ctx, E, E,  EL, E,  ER, list,  ctx, list,  ctx