* singular values) have been found.
*/
public TrainingState solve(Matrix corpus,
int desiredRank) {
int cols = corpus.numCols();
Matrix eigens = new DenseMatrix(desiredRank, cols);
List<Double> eigenValues = new ArrayList<Double>();
log.info("Finding " + desiredRank + " singular vectors of matrix with " + corpus.numRows() + " rows, via Hebbian");
/**
* The corpusProjections matrix is a running cache of the residual projection of each corpus vector against all
* of the previously found singular vectors. Without this, if multiple passes over the data is made (per
* singular vector), recalculating these projections eventually dominates the computational complexity of the
* solver.
*/
Matrix corpusProjections = new DenseMatrix(corpus.numRows(), desiredRank);
TrainingState state = new TrainingState(eigens, corpusProjections);
for (int i = 0; i < desiredRank; i++) {
Vector currentEigen = new DenseVector(cols);
Vector previousEigen = null;
while (hasNotConverged(currentEigen, corpus, state)) {