// Transform the vector according to this instance's transform's state,
// which should normalize the vector as the original vectors were.
DoubleVector transformed = transform.transform(docVec);
// Represent the document as a 1-column matrix
Matrix queryAsMatrix = new ArrayMatrix(1, numDims);
for (int nz : docVec.getNonZeroIndices())
queryAsMatrix.set(0, nz, transformed.get(nz));
// Project the new document vector, d, by using
//
// d * U_k * Sigma_k^-1
//
// where k is the dimensionality of the LSA space
Matrix UtimesSigmaInv = null;
// We cache the reuslts of the U_k * Sigma_k^-1 multiplication since
// this will be the same for all projections.
while (UtimesSigmaInv == null) {
if (UtimesSigmaInvRef != null
&& ((UtimesSigmaInv = UtimesSigmaInvRef.get()) != null))
break;
int rows = sigma.rows();
double[] sigmaInv = new double[rows];
for (int i = 0; i < rows; ++i)
sigmaInv[i] = 1d / sigma.get(i, i);
DiagonalMatrix sigmaInvMatrix = new DiagonalMatrix(sigmaInv);
UtimesSigmaInv =
Matrices.multiply(U, sigmaInvMatrix);
// Update the field with the new reference to the precomputed matrix
UtimesSigmaInvRef = new WeakReference<Matrix>(UtimesSigmaInv);
}
// Compute the resulting projected vector as a matrix
Matrix result = Matrices.multiply(queryAsMatrix, UtimesSigmaInv);
// Copy out the vector itself so that we don't retain a reference to the
// matrix as a result of its getRowVector call, which isn't guaranteed
// to return a copy.
int cols = result.columns();
DoubleVector projected = new DenseVector(result.columns());
for (int i = 0; i < cols; ++i)
projected.set(i, result.get(0, i));
return projected;
}