'Compute data precision matrix with the generative model.
Equals the inverse of the covariance but computed with
the matrix inversion lemma for efficiency.
Returns
precision : array, shape=(n_features, n_features)
Estimated precision of data.'

def get_precision(self):

    n_features = self.components_.shape[1]
    if (self.n_components_ == 0):
        return (np.eye(n_features) / self.noise_variance_)
    if (self.n_components_ == n_features):
        return linalg.inv(self.get_covariance())
    components_ = self.components_
    exp_var = self.explained_variance_
    if self.whiten:
        components_ = (components_ * np.sqrt(exp_var[:, np.newaxis]))
    exp_var_diff = np.maximum((exp_var - self.noise_variance_), 0.0)
    precision = (np.dot(components_, components_.T) / self.noise_variance_)
    precision.flat[::(len(precision) + 1)] += (1.0 / exp_var_diff)
    precision = np.dot(components_.T, np.dot(linalg.inv(precision), components_))
    precision /= (- (self.noise_variance_ ** 2))
    precision.flat[::(len(precision) + 1)] += (1.0 / self.noise_variance_)
    return precision
