'Latent Semantic Analysis is a statistical machine learning method based on
singular value decomposition (SVD), and related to principal component analysis (PCA).
Closely related features (words) in the model are combined into "concepts".
Documents then get a concept vector that is an approximation of the original vector,
but with reduced dimensionality so that cosine similarity and clustering run faster.'

def __init__(self, model, k=NORM):

    import numpy
    matrix = [model.vector(d).values() for d in model.documents]
    matrix = numpy.array(matrix)
    (u, sigma, vt) = numpy.linalg.svd(matrix, full_matrices=False)
    if (k == L1):
        k = int(round(numpy.linalg.norm(sigma, 1)))
    if ((k == L2) or (k == NORM)):
        k = int(round(numpy.linalg.norm(sigma, 2)))
    if (k == TOP300):
        k = max(0, (len(sigma) - 300))
    if isinstance(k, int):
        k = max(0, (len(sigma) - k))
    if (type(k).__name__ == 'function'):
        k = max(0, int(k(sigma)))
    assert (k < len(model.documents)), "can't    create    more    dimensions    than    there    are    documents"
    tail = (lambda list, i: range((len(list) - i), len(list)))
    (u, sigma, vt) = (numpy.delete(u, tail(u[0], k), axis=1), numpy.delete(sigma, tail(sigma, k), axis=0), numpy.delete(vt, tail(vt, k), axis=0))
    self.model = model
    self._terms = dict(enumerate(model.vector().keys()))
    (self.u, self.sigma, self.vt) = (dict(((d.id, Vector(((i, float(x)) for (i, x) in enumerate(v)))) for (d, v) in zip(model, u))), list(sigma), [[float(x) for x in v] for v in vt])
