/**
   * Build the SVD model.
   *
   * @return A singular value decomposition recommender model.
   */
  @Override
  public SVDModel get() {
    // Create index mappings of user and item IDs.
    // You can use these to find row and columns in the matrix based on user/item IDs.
    IdIndexMapping userMapping = IdIndexMapping.create(userDAO.getUserIds());
    logger.debug("indexed {} users", userMapping.size());
    IdIndexMapping itemMapping = IdIndexMapping.create(itemDAO.getItemIds());
    logger.debug("indexed {} items", itemMapping.size());

    // We have to do 2 things:
    // First, prepare a matrix containing the rating data.
    RealMatrix matrix = createRatingMatrix(userMapping, itemMapping);

    // Second, compute its factorization
    // All the work is done in the constructor
    SingularValueDecomposition svd = new SingularValueDecomposition(matrix);

    // Third, truncate the decomposed matrix
    // TODO Truncate the matrices and construct the SVD model
    RealMatrix userMatrix = svd.getU();
    RealMatrix weights = svd.getS();
    RealMatrix itemMatrix = svd.getV();

    userMatrix = userMatrix.getSubMatrix(0, userMatrix.getRowDimension() - 1, 0, featureCount - 1);
    weights = weights.getSubMatrix(0, featureCount - 1, 0, featureCount - 1);
    itemMatrix = itemMatrix.getSubMatrix(0, itemMatrix.getRowDimension() - 1, 0, featureCount - 1);

    return new SVDModel(userMapping, itemMapping, userMatrix, itemMatrix, weights);
  }