private String lsaSummary() {
    StringBuffer result = new StringBuffer();
    
    // print number of latent variables used
    result.append("Number of latent variables utilized: " + m_actualRank);
    
    // print singular values
    result.append("\n\nSingularValue\tLatentVariable#\n");
    // create single array of singular values rather than diagonal matrix
    for (int i = 0; i < m_actualRank; i++) {
      result.append(Utils.doubleToString(m_s.get(i, i), 9, 5) + "\t" + (i + 1) + "\n");
    }
    
    // print attribute vectors
    result.append("\nAttribute vectors (left singular vectors) -- row vectors show\n" +
                  "the relation between the original attributes and the latent \n" +
                  "variables computed by the singular value decomposition:\n");
    for (int i = 0; i < m_actualRank; i++) {
      result.append("LatentVariable#" + (i + 1) + "\t");
    }
    result.append("AttributeName\n");
    for (int i = 0; i < m_u.getRowDimension(); i++) { // for each attribute
      for (int j = 0; j < m_u.getColumnDimension(); j++) { // for each latent variable
        result.append(Utils.doubleToString(m_u.get(i, j), 9, 5) + "\t\t");
      }
      result.append(m_trainInstances.attribute(i).name() + "\n");
    }
    
    // print instance vectors
    result.append("\n\nInstance vectors (right singular vectors) -- column\n" +
                  "vectors show the relation between the original instances and the\n" +
                  "latent variables computed by the singular value decomposition:\n");
    for (int i = 0; i < m_numInstances; i++) {
      result.append("Instance#" + (i + 1) + "\t");
    }
    result.append("LatentVariable#\n");
    for (int i = 0; i < m_v.getColumnDimension(); i++) { // for each instance
      for (int j = 0; j < m_v.getRowDimension(); j++) { // for each latent variable
        // going down columns instead of across rows because we're
        // printing v' but have v stored
        result.append(Utils.doubleToString(m_v.get(j, i), 9, 5) + "\t");
      }
      result.append((i + 1) + "\n");
    }
    
    return result.toString();
  }