code: def fit(self, X, y):
      
      X, labels = self._prepare_inputs(X, y, ensure_min_samples=2)
      n, d = X.shape
      num_dims = self.num_dims
      if num_dims is None:
          num_dims = d
  
      # Measure the total training time
      train_time = time.time()
  
      # Initialize A to a scaling matrix
      A = np.zeros((num_dims, d))
      np.fill_diagonal(A, 1./(np.maximum(X.max(axis=0)-X.min(axis=0), EPS)))
  
      # Run NCA
      mask = labels[:, np.newaxis] == labels[np.newaxis, :]
      optimizer_params = {'method': 'L-BFGS-B',
                          'fun': self._loss_grad_lbfgs,
                          'args': (X, mask, -1.0),
                          'jac': True,
                          'x0': A.ravel(),
                          'options': dict(maxiter=self.max_iter),
                          'tol': self.tol
                          }
  
      # Call the optimizer
      self.n_iter_ = 0
      opt_result = minimize(**optimizer_params)
  
      self.transformer_ = opt_result.x.reshape(-1, X.shape[1])
      self.n_iter_ = opt_result.nit
  
      # Stop timer
      train_time = time.time() - train_time
      if self.verbose:
        cls_name = self.__class__.__name__
  
        # Warn the user if the algorithm did not converge
        if not opt_result.success:
          warnings.warn('[{}] NCA did not converge: {}'.format(
              cls_name, opt_result.message), ConvergenceWarning)
  
        print('[{}] Training took {:8.2f}s.'.format(cls_name, train_time))
  
      return self
docs: X: data matrix, (n x d)
      y: scalar labels, (n)