docstr: Makes use of the quadratic programming solver `solve_qp` to fit the
  model. The initialization for the model is done using the warm-start by
  default in `CVXPY`.
  
  Parameters
  ----------
  X : ndarray
      Matrix to be fit by the QP solver calculated in
      `MultiShellDeconvModel`
  reg : ndarray
      the regularization B matrix calculated in `MultiShellDeconvModel`
code: def __init__(self, X, reg):
      r"""
      Makes use of the quadratic programming solver `solve_qp` to fit the
      model. The initialization for the model is done using the warm-start by
      default in `CVXPY`.
  
      Parameters
      ----------
      X : ndarray
          Matrix to be fit by the QP solver calculated in
          `MultiShellDeconvModel`
      reg : ndarray
          the regularization B matrix calculated in `MultiShellDeconvModel`
      """
      self._P = P = np.dot(X.T, X)
      self._X = X
  
      self._reg = reg
      self._P_mat = np.array(P)
      self._reg_mat = np.array(-reg)
      self._h_mat = np.array([0])
  
imports: from packaging.version import Version
  import numbers
  import warnings
  import numpy
  from dipy.core import geometry
  from dipy.core.gradients import GradientTable, gradient_table, unique_bvals_tolerance, get_bval_indices
  from dipy.data import default_sphere
  from dipy.reconst import shm
  from dipy.reconst.csdeconv import response_from_mask_ssst
  from dipy.reconst.dti import TensorModel, fractional_anisotropy, mean_diffusivity
  from dipy.reconst.multi_voxel import multi_voxel_fit
  from dipy.reconst.utils import _roi_in_volume, _mask_from_roi
  from dipy.sims.voxel import single_tensor
  from dipy.utils.optpkg import optional_package
label_desc: Use image node_id 1 to create a new QpFitter object  with example: obj = QpFitter(X, reg)