def fit(self, X_train, y_train, reduced_dim):
        """Trains the model, i.e., it computes the weight matrix w_LDA.

        Parameters
        ----------
        X_train : array of floats of dimension N x D, where N is the number
            of data points and D the number of features.
            The training data points.
        y_train : array of ints of dimensions N.
            The classes of each data point.
        reduced_dim : float.
            The dimension of the subspace in which we want to project.

        """
        dim = np.size(X_train[0, :])
        K = y_train.max() + 1
        self.m_LDA = np.mean(X_train, axis=0)
        sums = np.zeros([dim, K])
        # We compute the class means iterating over dimension using this trick:
        for k in range(dim):
            sums[k, :] = np.bincount(y_train, X_train[:, k])
        N_class = np.bincount(y_train)
        class_means = sums/N_class

        S_B, S_W = np.zeros([dim, dim]), np.zeros([dim, dim])
        for k in range(K):
            dif = (self.m_LDA - class_means[:, k])[:, np.newaxis]
            S_B += N_class[k] * np.dot(dif, dif.T)
        X_train -= self.m_LDA
        # We compute S_T instead of S_W to improve performance
        S_T = np.dot(X_train.T, X_train)
        S_W = S_T - S_B

        _, eigenvectors = eigh(S_B, S_W, eigvals=(dim - reduced_dim, dim - 1),
                               overwrite_a=True, overwrite_b=True)
        self.W_LDA = eigenvectors[:, ::-1]
dataset/ETHPy150Open vicgalle/machine-learning/reduce_dim.py/LDA.fit/original