code: def _svd_step(self, X, shrinkage_value, max_rank=None):
          
          if max_rank:
              # if we have a max rank then perform the faster randomized SVD
              (U, s, V) = randomized_svd(
                  X,
                  max_rank,
                  n_iter=self.n_power_iterations)
          else:
              # perform a full rank SVD using ARPACK
              (U, s, V) = np.linalg.svd(
                  X,
                  full_matrices=False,
                  compute_uv=True)
          s_thresh = np.maximum(s - shrinkage_value, 0)
          rank = (s_thresh > 0).sum()
          s_thresh = s_thresh[:rank]
          U_thresh = U[:, :rank]
          V_thresh = V[:rank, :]
          S_thresh = np.diag(s_thresh)
          X_reconstruction = np.dot(U_thresh, np.dot(S_thresh, V_thresh))
          return X_reconstruction, rank
docs: Returns reconstructed X from low-rank thresholded SVD and
          the rank achieved.