docs: public void computeBasis( int numComponents ) {
          if( numComponents > A.getNumCols() )
              throw new IllegalArgumentException("More components requested that the data's length.");
          if( sampleIndex != A.getNumRows() )
              throw new IllegalArgumentException("Not all the data has been added");
          if( numComponents > sampleIndex )
              throw new IllegalArgumentException("More data needed to compute the desired number of components");
  
          this.numComponents = numComponents;
  
          // compute the mean of all the samples
          for( int i = 0; i < A.getNumRows(); i++ ) {
              for( int j = 0; j < mean.length; j++ ) {
                  mean[j] += A.get(i,j);
              }
          }
          for( int j = 0; j < mean.length; j++ ) {
              mean[j] /= A.getNumRows();
          }
  
          // subtract the mean from the original data
          for( int i = 0; i < A.getNumRows(); i++ ) {
              for( int j = 0; j < mean.length; j++ ) {
                  A.set(i,j,A.get(i,j)-mean[j]);
              }
          }
  
          // Compute SVD and save time by not computing U
          SingularValueDecomposition<DMatrixRMaj> svd =
                  DecompositionFactory_DDRM.svd(A.numRows, A.numCols, false, true, false);
          if( !svd.decompose(A) )
              throw new RuntimeException("SVD failed");
  
          V_t = svd.getV(null,true);
          DMatrixRMaj W = svd.getW(null);
  
          // Singular values are in an arbitrary order initially
          SingularOps_DDRM.descendingOrder(null,false,W,V_t,true);
  
          // strip off unneeded components and find the basis
          V_t.reshape(numComponents,mean.length,true);
      }