@Override
  public boolean setA(DenseMatrix64F A) {
    pinv.reshape(A.numCols, A.numRows, false);

    if (!svd.decompose(A)) return false;

    DenseMatrix64F U_t = svd.getU(null, true);
    DenseMatrix64F V = svd.getV(null, false);
    double[] S = svd.getSingularValues();
    int N = Math.min(A.numRows, A.numCols);

    // compute the threshold for singular values which are to be zeroed
    double maxSingular = 0;
    for (int i = 0; i < N; i++) {
      if (S[i] > maxSingular) maxSingular = S[i];
    }

    double tau = threshold * Math.max(A.numCols, A.numRows) * maxSingular;

    // computer the pseudo inverse of A
    for (int i = 0; i < N; i++) {
      double s = S[i];
      if (s < tau) S[i] = 0;
      else S[i] = 1.0 / S[i];
    }

    // V*W
    for (int i = 0; i < V.numRows; i++) {
      int index = i * V.numCols;
      for (int j = 0; j < V.numCols; j++) {
        V.data[index++] *= S[j];
      }
    }

    // V*W*U^T
    CommonOps.mult(V, U_t, pinv);

    return true;
  }