code: def fit_constrained(
      model,
      constraint_matrix,
      constraint_values,
      start_params=None,
      fit_kwds=None,
  ):
      # note: self is model instance
      """fit model subject to linear equality constraints
  
      The constraints are of the form   `R params = q`
      where R is the constraint_matrix and q is the vector of constraint_values.
  
      The estimation creates a new model with transformed design matrix,
      exog, and converts the results back to the original parameterization.
  
  
      Parameters
      ----------
      model: model instance
          An instance of a model, see limitations in Notes section
      constraint_matrix : array_like, 2D
          This is R in the linear equality constraint `R params = q`.
          The number of columns needs to be the same as the number of columns
          in exog.
      constraint_values :
          This is `q` in the linear equality constraint `R params = q`
          If it is a tuple, then the constraint needs to be given by two
          arrays (constraint_matrix, constraint_value), i.e. (R, q).
          Otherwise, the constraints can be given as strings or list of
          strings.
          see t_test for details
      start_params : None or array_like
          starting values for the optimization. `start_params` needs to be
          given in the original parameter space and are internally
          transformed.
      **fit_kwds : keyword arguments
          fit_kwds are used in the optimization of the transformed model.
  
      Returns
      -------
      params : ndarray ?
          estimated parameters (in the original parameterization
      cov_params : ndarray
          covariance matrix of the parameter estimates. This is a reverse
          transformation of the covariance matrix of the transformed model given
          by `cov_params()`
          Note: `fit_kwds` can affect the choice of covariance, e.g. by
          specifying `cov_type`, which will be reflected in the returned
          covariance.
      res_constr : results instance
          This is the results instance for the created transformed model.
  
  
      Notes
      -----
      Limitations:
  
      Models where the number of parameters is different from the number of
      columns of exog are not yet supported.
  
      Requires a model that implement an offset option.
      """
      self = model  # internal alias, used for methods
      if fit_kwds is None:
          fit_kwds = {}
  
      R, q = constraint_matrix, constraint_values
      endog, exog = self.endog, self.exog
  
      transf = TransformRestriction(R, q)
  
      exogp_st = transf.reduce(exog)
  
      offset = exog.dot(transf.constant.squeeze())
      if hasattr(self, "offset"):
          offset += self.offset
  
      if start_params is not None:
          start_params = transf.reduce(start_params)
  
      # need copy, because we do not want to change it, we do not need deepcopy
      import copy
  
      init_kwds = copy.copy(self._get_init_kwds())
  
      # TODO: refactor to combine with above or offset_all
      if "offset" in init_kwds:
          del init_kwds["offset"]
  
      # using offset as keywords is not supported in all modules
      mod_constr = self.__class__(
          endog, exogp_st, offset=offset, **init_kwds
      )
      res_constr = mod_constr.fit(start_params=start_params, **fit_kwds)
      params_orig = transf.expand(res_constr.params).squeeze()
      cov_params = transf.transf_mat.dot(res_constr.cov_params()).dot(
          transf.transf_mat.T
      )
  
      return params_orig, cov_params, res_constr
  
file_path: statsmodels/statsmodels/base/_constraints.py
imports: import numpy
label_desc: Use image node_id 2 for calling a global function with example usage: fit_constrained(model, constraint_matrix, constraint_values, start_params, fit_kwds) and returns: params_orig,  cov_params,  res_constr