def fit(self, maxiter=60, ctol=1e-6, start_params=None,
            params_niter=1, first_dep_update=0,
            cov_type='robust', ddof_scale=None, scaling_factor=1.):

        # Subtract this number from the total sample size when
        # normalizing the scale parameter estimate.
        if ddof_scale is None:
            self.ddof_scale = self.exog.shape[1]
        else:
            if not ddof_scale >= 0:
                raise ValueError("ddof_scale must be a non-negative number or None")
            self.ddof_scale = ddof_scale

        self.scaling_factor = scaling_factor

        self._fit_history = {'params': [],
                             'score': [],
                             'dep_params': [],
                             'cov_adjust': []}

        if self.weights is not None and cov_type == 'naive':
            raise ValueError("when using weights, cov_type may not be naive")

        if start_params is None:
            mean_params = self._starting_params()
        else:
            start_params = np.asarray(start_params)
            mean_params = start_params.copy()

        self.update_cached_means(mean_params)

        del_params = -1.
        num_assoc_updates = 0
        for itr in range(maxiter):

            update, score = self._update_mean_params()
            if update is None:
                warnings.warn("Singular matrix encountered in GEE update",
                              ConvergenceWarning)
                break
            mean_params += update
            self.update_cached_means(mean_params)

            # L2 norm of the change in mean structure parameters at
            # this iteration.
            del_params = np.sqrt(np.sum(score**2))

            self._fit_history['params'].append(mean_params.copy())
            self._fit_history['score'].append(score)
            self._fit_history['dep_params'].append(
                self.cov_struct.dep_params)

            # Don't exit until the association parameters have been
            # updated at least once.
            if (del_params < ctol and
                (num_assoc_updates > 0 or self.update_dep == False)):
                break

            # Update the dependence structure
            if (self.update_dep and (itr % params_niter) == 0
                and (itr >= first_dep_update)):
                self._update_assoc(mean_params)
                num_assoc_updates += 1

        if del_params >= ctol:
            warnings.warn("Iteration limit reached prior to convergence",
                          IterationLimitWarning)

        if mean_params is None:
            warnings.warn("Unable to estimate GEE parameters.",
                          ConvergenceWarning)
            return None

        bcov, ncov, bc_cov, _ = self._covmat()
        if bcov is None:
            warnings.warn("Estimated covariance structure for GEE "
                          "estimates is singular", ConvergenceWarning)
            return None

        if self.constraint is not None:
            mean_params, bcov = self._handle_constraint(mean_params, bcov)
            if mean_params is None:
                warnings.warn("Unable to estimate constrained GEE "
                              "parameters.", ConvergenceWarning)
                return None

        scale = self.estimate_scale()

        #kwargs to add to results instance, need to be available in __init__
        res_kwds = dict(cov_type = cov_type,
                        cov_robust = bcov,
                        cov_naive = ncov,
                        cov_robust_bc = bc_cov)

        # The superclass constructor will multiply the covariance
        # matrix argument bcov by scale, which we don't want, so we
        # divide bcov by the scale parameter here
        results = GEEResults(self, mean_params, bcov / scale, scale,
                             cov_type=cov_type, use_t=False,
                             attr_kwds=res_kwds)

        # attributes not needed during results__init__
        results.fit_history = self._fit_history
        delattr(self, "_fit_history")
        results.score_norm = del_params
        results.converged = (del_params < ctol)
        results.cov_struct = self.cov_struct
        results.params_niter = params_niter
        results.first_dep_update = first_dep_update
        results.ctol = ctol
        results.maxiter = maxiter

        # These will be copied over to subclasses when upgrading.
        results._props = ["cov_type", "use_t",
                          "cov_params_default", "cov_robust",
                          "cov_naive", "cov_robust_bc",
                           "fit_history",
                          "score_norm", "converged", "cov_struct",
                          "params_niter", "first_dep_update", "ctol",
                          "maxiter"]

        return GEEResultsWrapper(results)
dataset/ETHPy150Open statsmodels/statsmodels/statsmodels/genmod/generalized_estimating_equations.py/GEE.fit/original