'Fit the model by computing truncated SVD (by ARPACK or randomized)
on X'

def _fit_truncated(self, X, n_components, svd_solver):

    (n_samples, n_features) = X.shape
    if isinstance(n_components, six.string_types):
        raise ValueError(("n_components=%r    cannot    be    a    string    with    svd_solver='%s'" % (n_components, svd_solver)))
    elif (not (1 <= n_components <= n_features)):
        raise ValueError(("n_components=%r    must    be    between    1    and    n_features=%r    with    svd_solver='%s'" % (n_components, n_features, svd_solver)))
    elif ((svd_solver == 'arpack') and (n_components == n_features)):
        raise ValueError(("n_components=%r    must    be    stricly    less    than    n_features=%r    with    svd_solver='%s'" % (n_components, n_features, svd_solver)))
    random_state = check_random_state(self.random_state)
    self.mean_ = np.mean(X, axis=0)
    X -= self.mean_
    if (svd_solver == 'arpack'):
        v0 = random_state.uniform((-1), 1, size=min(X.shape))
        (U, S, V) = svds(X, k=n_components, tol=self.tol, v0=v0)
        S = S[::(-1)]
        (U, V) = svd_flip(U[:, ::(-1)], V[::(-1)])
    elif (svd_solver == 'randomized'):
        (U, S, V) = randomized_svd(X, n_components=n_components, n_iter=self.iterated_power, flip_sign=True, random_state=random_state)
    (self.n_samples_, self.n_features_) = (n_samples, n_features)
    self.components_ = V
    self.n_components_ = n_components
    self.explained_variance_ = ((S ** 2) / (n_samples - 1))
    total_var = np.var(X, ddof=1, axis=0)
    self.explained_variance_ratio_ = (self.explained_variance_ / total_var.sum())
    self.singular_values_ = S.copy()
    if (self.n_components_ < min(n_features, n_samples)):
        self.noise_variance_ = (total_var.sum() - self.explained_variance_.sum())
        self.noise_variance_ /= (min(n_features, n_samples) - n_components)
    else:
        self.noise_variance_ = 0.0
    return (U, S, V)
