'Eigenvalue solver.
The eigenvalue solver computes the optimal solution of the Rayleigh
coefficient (basically the ratio of between class scatter to within
class scatter). This solver supports both classification and
dimensionality reduction (with optional shrinkage).
Parameters
X : array-like, shape (n_samples, n_features)
Training data.
y : array-like, shape (n_samples,) or (n_samples, n_targets)
Target values.
shrinkage : string or float, optional
Shrinkage parameter, possible values:
- None: no shrinkage (default).
- \'auto\': automatic shrinkage using the Ledoit-Wolf lemma.
- float between 0 and 1: fixed shrinkage constant.
Notes
This solver is based on [1]_, section 3.8.3, pp. 121-124.
References
.. [1] R. O. Duda, P. E. Hart, D. G. Stork. Pattern Classification
(Second Edition). John Wiley & Sons, Inc., New York, 2001. ISBN
0-471-05669-3.'

def _solve_eigen(self, X, y, shrinkage):

    self.means_ = _class_means(X, y)
    self.covariance_ = _class_cov(X, y, self.priors_, shrinkage)
    Sw = self.covariance_
    St = _cov(X, shrinkage)
    Sb = (St - Sw)
    (evals, evecs) = linalg.eigh(Sb, Sw)
    self.explained_variance_ratio_ = np.sort((evals / np.sum(evals)))[::(-1)][:self._max_components]
    evecs = evecs[:, np.argsort(evals)[::(-1)]]
    evecs /= np.linalg.norm(evecs, axis=0)
    self.scalings_ = evecs
    self.coef_ = np.dot(self.means_, evecs).dot(evecs.T)
    self.intercept_ = (((-0.5) * np.diag(np.dot(self.means_, self.coef_.T))) + np.log(self.priors_))
