class_docstr: Enables dimensionality reduction for multiple
  class distributions. It transforms the features space into a space where
  the between class scatter is maximized and the within class scatter is
  minimized.
  
  Parameters:
  -----------
  solver: str
      If 'svd' we use the pseudo-inverse to calculate the inverse of matrices
      when doing the transformation.
code: def _calculate_scatter_matrices(self, X, y):
      n_features = np.shape(X)[1]
      labels = np.unique(y)
  
      # Within class scatter matrix:
      # SW = sum{ (X_for_class - mean_of_X_for_class)^2 }
      #   <=> (n_samples_X_for_class - 1) * covar(X_for_class)
      SW = np.empty((n_features, n_features))
      for label in labels:
          _X = X[y == label]
          SW += (len(_X) - 1) * calculate_covariance_matrix(_X)
  
      # Between class scatter:
      # SB = sum{ n_samples_for_class * (mean_for_class - total_mean)^2 }
      total_mean = np.mean(X, axis=0)
      SB = np.empty((n_features, n_features))
      for label in labels:
          _X = X[y == label]
          _mean = np.mean(_X, axis=0)
          SB += len(_X) * (_mean - total_mean).dot(
              (_mean - total_mean).T
          )
  
      return SW, SB
  
file_path: ML-From-Scratch/mlfromscratch/supervised_learning/multi_class_lda.py
imports: from __future__ import print_function, division
  import matplotlib.pyplot
  import numpy
  from mlfromscratch.utils import calculate_covariance_matrix, normalize, standardize
label_desc: Use image node_id 2 for calling the MultiClassLDA obj's underlying member method code with example usage: obj._calculate_scatter_matrices(X, y) and returns: SW,  SB