'Compute a Wald-test for a joint linear hypothesis.
Parameters
r_matrix : array-like, str, or tuple
- array : An r x k array where r is the number of restrictions to
test and k is the number of regressors. It is assumed that the
linear combination is equal to zero.
- str : The full hypotheses to test can be given as a string.
See the examples.
- tuple : A tuple of arrays in the form (R, q), ``q`` can be
either a scalar or a length p row vector.
cov_p : array-like, optional
An alternative estimate for the parameter covariance matrix.
If None is given, self.normalized_cov_params is used.
scale : float, optional
Default is 1.0 for no scaling.
invcov : array-like, optional
A q x q array to specify an inverse covariance matrix based on a
restrictions matrix.
use_f : bool
If True, then the F-distribution is used. If False, then the
asymptotic distribution, chisquare is used. If use_f is None, then
the F distribution is used if the model specifies that use_t is True.
The test statistic is proportionally adjusted for the distribution
by the number of constraints in the hypothesis.
Returns
res : ContrastResults instance
The results for the test are attributes of this results instance.
See also
statsmodels.stats.contrast.ContrastResults
f_test
t_test
patsy.DesignInfo.linear_constraint
Notes
The matrix `r_matrix` is assumed to be non-singular. More precisely,
r_matrix (pX pX.T) r_matrix.T
is assumed invertible. Here, pX is the generalized inverse of the
design matrix of the model. There can be problems in non-OLS models
where the rank of the covariance of the noise is not full.'

def wald_test(self, r_matrix, cov_p=None, scale=1.0, invcov=None, use_f=None):

    if (use_f is None):
        use_f = (hasattr(self, 'use_t') and self.use_t)
    from patsy import DesignInfo
    names = self.model.data.param_names
    LC = DesignInfo(names).linear_constraint(r_matrix)
    (r_matrix, q_matrix) = (LC.coefs, LC.constants)
    if ((self.normalized_cov_params is None) and (cov_p is None) and (invcov is None) and (not hasattr(self, 'cov_params_default'))):
        raise ValueError('need    covariance    of    parameters    for    computing    F    statistics')
    cparams = np.dot(r_matrix, self.params[:, None])
    J = float(r_matrix.shape[0])
    if (q_matrix is None):
        q_matrix = np.zeros(J)
    else:
        q_matrix = np.asarray(q_matrix)
    if (q_matrix.ndim == 1):
        q_matrix = q_matrix[:, None]
        if (q_matrix.shape[0] != J):
            raise ValueError('r_matrix    and    q_matrix    must    have    the    same    number    of    rows')
    Rbq = (cparams - q_matrix)
    if (invcov is None):
        cov_p = self.cov_params(r_matrix=r_matrix, cov_p=cov_p)
        if np.isnan(cov_p).max():
            raise ValueError('r_matrix    performs    f_test    for    using    dimensions    that    are    asymptotically    non-normal')
        invcov = np.linalg.inv(cov_p)
    if (hasattr(self, 'mle_settings') and (self.mle_settings['optimizer'] in ['l1', 'l1_cvxopt_cp'])):
        F = nan_dot(nan_dot(Rbq.T, invcov), Rbq)
    else:
        F = np.dot(np.dot(Rbq.T, invcov), Rbq)
    df_resid = getattr(self, 'df_resid_inference', self.df_resid)
    if use_f:
        F /= J
        return ContrastResults(F=F, df_denom=df_resid, df_num=invcov.shape[0])
    else:
        return ContrastResults(chi2=F, df_denom=J, statistic=F, distribution='chi2', distargs=(J,))
