def inverse_deriv2(self, z): """ Second derivative of the inverse link function g^(-1)(z). Parameters ---------- z : array_like `z` is usually the linear predictor for a GLM or GEE model. Returns ------- g^(-1)''(z) : ndarray The value of the second derivative of the inverse of the link function Notes ----- This method should be overwritten by subclasses. The inherited method is implemented through numerical differentiation. """ from statsmodels.tools.numdiff import _approx_fprime_scalar z = np.atleast_1d(z) # Note: special function for norm.ppf does not support complex return _approx_fprime_scalar(z, self.inverse_deriv, centered=True)
def _deriv_score_obs_dendog(self, params): """derivative of score_obs w.r.t. endog Parameters ---------- params : ndarray parameter at which score is evaluated Returns ------- derivative : ndarray_2d The derivative of the score_obs with respect to endog. """ raise NotImplementedError # The below currently does not work, discontinuity at zero # see https://github.com/statsmodels/statsmodels/pull/7951#issuecomment-996355875 # noqa from statsmodels.tools.numdiff import _approx_fprime_scalar endog_original = self.endog def f(y): if y.ndim == 2 and y.shape[1] == 1: y = y[:, 0] self.endog = y self.model_main.endog = y sf = self.score_obs(params) self.endog = endog_original self.model_main.endog = endog_original return sf ds = _approx_fprime_scalar(self.endog[:, None], f, epsilon=1e-2) return ds
def deriv2_numdiff(self, p): """ Second derivative of the link function g''(p) implemented through numerical differentiation """ from statsmodels.tools.numdiff import _approx_fprime_scalar p = np.atleast_1d(p) # Note: special function for norm.ppf does not support complex return _approx_fprime_scalar(p, self.deriv, centered=True)
def test_vectorized(): def f(x): return 2 * x desired = np.array([2, 2]) # vectorized parameter, column vector p = np.array([[1, 2]]).T assert_allclose(_approx_fprime_scalar(p, f), desired[:, None], rtol=1e-8) assert_allclose(_approx_fprime_scalar(p.squeeze(), f), desired, rtol=1e-8) assert_allclose(_approx_fprime_cs_scalar(p, f), desired[:, None], rtol=1e-8) assert_allclose(_approx_fprime_cs_scalar(p.squeeze(), f), desired, rtol=1e-8) # check 2-d row, see #7680 # not allowed/implemented for approx_fprime, raises broadcast ValueError # assert_allclose(approx_fprime(p.T, f), desired, rtol=1e-8) # similar as used in MarkovSwitching unit test assert_allclose(approx_fprime_cs(p.T, f).squeeze(), desired, rtol=1e-8)