code: def LDA(x, labels, n=False):
      
      # select n if not provided
      if not n:
          n = x.shape[1] - 1 
      # validate inputs
      try:    
          x = np.array(x)
      except:
          raise ValueError('Impossible to convert x to a numpy array.')
      assert type(n) == int, "Provided n is not an integer."
      assert x.shape[1] > n, "The requested n is bigger than \
          number of features in x."
      # make the LDA
      eigen_values, eigen_vectors = LDA_base(x, labels)
      # sort the eigen vectors according to eigen values
      eigen_order = eigen_vectors.T[(-eigen_values).argsort()]
      return eigen_order[:n].dot(x.T).T
docs: Linear Discriminant Analysis function.
  
      **Args:**
  
      * `x` : input matrix (2d array), every row represents new sample
  
      * `labels` : list of labels (iterable), every item should be label for \
        sample with corresponding index
  
      **Kwargs:**
  
      * `n` : number of features returned (integer) - how many columns 
        should the output keep
  
      **Returns:**
      
      * new_x : matrix with reduced size (number of columns are equal `n`)