def pinv_extended(X, rcond=1e-15):
 X = np.asarray(X)
 X = X.conjugate()
 (u, s, vt) = np.linalg.svd(X, 0)
 s_orig = np.copy(s)
 m = u.shape[0]
 n = vt.shape[1]
 cutoff = (rcond * np.maximum.reduce(s))
 for i in range(min(n, m)):
  if (s[i] > cutoff):
   s[i] = (1.0 / s[i])
  else:
   s[i] = 0.0
 res = np.dot(np.transpose(vt), np.multiply(s[:, np.core.newaxis], np.transpose(u)))
 return (res, s_orig)

def pinv_extended ( X , rcond = 1e-15 ) : X = np . asarray ( X ) X = X . conjugate ( ) ( u , s , vt ) = np . linalg . svd ( X , 0 ) s_orig = np . copy ( s ) m = u . shape [ 0 ] n = vt . shape [ 1 ] cutoff = ( rcond * np . maximum . reduce ( s ) ) for i in range ( min ( n , m ) ) : if ( s [ i ] > cutoff ) : s [ i ] = ( 1.0 / s [ i ] ) else : s [ i ] = 0.0 res = np . dot ( np . transpose ( vt ) , np . multiply ( s [ : , np . core . newaxis ] , np . transpose ( u ) ) ) return ( res , s_orig )
return the pinv of an array x as well as the singular values used in computation .