docstr: Fit method of the IvimModelVP model class
  
  MicroLearn framework (VarPro)[1]_.
  
  The VarPro computes the IVIM parameters using the MIX approach.
  This algorithm uses three different optimizers. It starts with a
  differential evolution algorithm and fits the parameters in the
  power of exponentials. Then the fitted parameters in the first step are
  utilized to make a linear convex problem. Using a convex optimization,
  the volume fractions are determined. Then the last step is non linear
  least square fitting on all the parameters. The results of the first
  and second step are utilized as the initial values for the last step
  of the algorithm. (see [1]_ and [2]_ for a comparison and a through
  discussion).
  
  References
  ----------
  .. [1] Fadnavis, Shreyas et.al. "MicroLearn: Framework for machine
         learning, reconstruction, optimization and microstructure
         modeling, Proceedings of: International Society of Magnetic
         Resonance in Medicine (ISMRM), Montreal, Canada, 2019.
  .. [2] Farooq, Hamza, et al. "Microstructure Imaging of Crossing (MIX)
         White Matter Fibers from diffusion MRI." Scientific reports 6
         (2016).
code: def fit(self, data, bounds_de=None):
      r"""Fit method of the IvimModelVP model class
  
      MicroLearn framework (VarPro)[1]_.
  
      The VarPro computes the IVIM parameters using the MIX approach.
      This algorithm uses three different optimizers. It starts with a
      differential evolution algorithm and fits the parameters in the
      power of exponentials. Then the fitted parameters in the first step are
      utilized to make a linear convex problem. Using a convex optimization,
      the volume fractions are determined. Then the last step is non linear
      least square fitting on all the parameters. The results of the first
      and second step are utilized as the initial values for the last step
      of the algorithm. (see [1]_ and [2]_ for a comparison and a through
      discussion).
  
      References
      ----------
      .. [1] Fadnavis, Shreyas et.al. "MicroLearn: Framework for machine
             learning, reconstruction, optimization and microstructure
             modeling, Proceedings of: International Society of Magnetic
             Resonance in Medicine (ISMRM), Montreal, Canada, 2019.
      .. [2] Farooq, Hamza, et al. "Microstructure Imaging of Crossing (MIX)
             White Matter Fibers from diffusion MRI." Scientific reports 6
             (2016).
  
      """
      data_max = data.max()
      data = data / data_max
      b = self.bvals
  
      # Setting up the bounds for differential_evolution
      bounds_de = np.array([(0.005, 0.01), (10**-4, 0.001)])
  
      # Optimizer #1: Differential Evolution
      res_one = differential_evolution(
          self.stoc_search_cost,
          bounds_de,
          maxiter=self.maxiter,
          args=(data,),
          disp=False,
          polish=True,
          popsize=28,
      )
      x = res_one.x
      phi = self.phi(x)
  
      # Optimizer #2: Convex Optimizer
      f = self.cvx_fit(data, phi)
      x_f = self.x_and_f_to_x_f(x, f)
  
      # Setting up the bounds for least_squares
      bounds = self.bounds
  
      # Optimizer #3: Nonlinear-Least Squares
      res = least_squares(
          self.nlls_cost,
          x_f,
          bounds=bounds,
          xtol=self.xtol,
          args=(data,),
      )
      result = res.x
      f_est = result[0]
      D_star_est = result[1]
      D_est = result[2]
  
      S0 = data / (
          f_est * np.exp(-b * D_star_est)
          + (1 - f_est) * np.exp(-b * D_est)
      )
      S0_est = S0 * data_max
  
      # final result containing the four fit parameters: S0, f, D* and D
      result = np.insert(result, 0, np.mean(S0_est), axis=0)
      return IvimFit(self, result)
  
imports: import warnings
  import numpy
  from scipy.optimize import least_squares, differential_evolution
  from dipy.reconst.base import ReconstModel
  from dipy.reconst.multi_voxel import multi_voxel_fit
  from dipy.utils.optpkg import optional_package
label_desc: Use image node_id 2 for calling the IvimModelVP obj's underlying member method code with example usage: obj.fit(data, bounds_de) and returns: IvimFit