'Fits a generalized linear model for a given family using
iteratively reweighted least squares (IRLS).'

def _fit_irls(self, start_params=None, maxiter=100, tol=1e-08, scale=None, cov_type='nonrobust', cov_kwds=None, use_t=None, **kwargs):

    atol = kwargs.get('atol')
    rtol = kwargs.get('rtol', 0.0)
    tol_criterion = kwargs.get('tol_criterion', 'deviance')
    atol = (tol if (atol is None) else atol)
    endog = self.endog
    wlsexog = self.exog
    if (start_params is None):
        start_params = np.zeros(self.exog.shape[1], np.float)
        mu = self.family.starting_mu(self.endog)
        lin_pred = self.family.predict(mu)
    else:
        lin_pred = (np.dot(wlsexog, start_params) + self._offset_exposure)
        mu = self.family.fitted(lin_pred)
    dev = self.family.deviance(self.endog, mu, self.iweights)
    if np.isnan(dev):
        raise ValueError('The    first    guess    on    the    deviance    function    returned    a    nan.        This    could    be    a    boundary        problem    and    should    be    reported.')
    history = dict(params=[np.inf, start_params], deviance=[np.inf, dev])
    converged = False
    criterion = history[tol_criterion]
    if (maxiter == 0):
        mu = self.family.fitted(lin_pred)
        self.scale = self.estimate_scale(mu)
        wls_results = lm.RegressionResults(self, start_params, None)
        iteration = 0
    for iteration in range(maxiter):
        self.weights = ((self.iweights * self.n_trials) * self.family.weights(mu))
        wlsendog = ((lin_pred + (self.family.link.deriv(mu) * (self.endog - mu))) - self._offset_exposure)
        wls_results = reg_tools._MinimalWLS(wlsendog, wlsexog, self.weights).fit(method='lstsq')
        lin_pred = (np.dot(self.exog, wls_results.params) + self._offset_exposure)
        mu = self.family.fitted(lin_pred)
        history = self._update_history(wls_results, mu, history)
        self.scale = self.estimate_scale(mu)
        if ((endog.squeeze().ndim == 1) and np.allclose((mu - endog), 0)):
            msg = 'Perfect    separation    detected,    results    not    available'
            raise PerfectSeparationError(msg)
        converged = _check_convergence(criterion, (iteration + 1), atol, rtol)
        if converged:
            break
    self.mu = mu
    if (maxiter > 0):
        wls_results = lm.WLS(wlsendog, wlsexog, self.weights).fit()
    glm_results = GLMResults(self, wls_results.params, wls_results.normalized_cov_params, self.scale, cov_type=cov_type, cov_kwds=cov_kwds, use_t=use_t)
    glm_results.method = 'IRLS'
    history['iteration'] = (iteration + 1)
    glm_results.fit_history = history
    glm_results.converged = converged
    return GLMResultsWrapper(glm_results)
