示例#1
0
 def grad_func(*args):
     inp = anp.array(anp.broadcast_arrays(*args))
     result = anp.atleast_2d(elementwise_grad(argwrapper)(inp))
     # Put 'gradient' axis at end
     axes = list(range(len(result.shape)))
     result = result.transpose(*chain(axes[1:], [axes[0]]))
     return result
示例#2
0
 def grad_func(*args):
     inp = anp.array(anp.broadcast_arrays(*args))
     result = anp.atleast_2d(elementwise_grad(argwrapper)(inp))
     # Put 'gradient' axis at end
     axes = list(range(len(result.shape)))
     result = result.transpose(*chain(axes[1:], [axes[0]]))
     return result
示例#3
0
 def hess_func(*args):
     result = anp.atleast_3d(
         elementwise_hess(argwrapper)(anp.array(
             anp.broadcast_arrays(*args))))
     # Put 'hessian' axes at end
     axes = list(range(len(result.shape)))
     result = result.transpose(*chain(axes[2:], axes[0:2]))
     return result
示例#4
0
 def hess_func(*args):
     result = anp.atleast_3d(elementwise_hess(argwrapper)(anp.array(anp.broadcast_arrays(*args))))
     # Put 'hessian' axes at end
     axes = list(range(len(result.shape)))
     result = result.transpose(*chain(axes[2:], axes[0:2]))
     return result
示例#5
0
    def test(self,
             null_point,
             sims=int(1e3),
             test_type="ratio",
             alt_point=None,
             null_cone=None,
             alt_cone=None,
             p_only=True):
        """
        Returns p-value for a single or several hypothesis tests.
        By default, does a simple hypothesis test with the log-likelihood ratio.

        Note that for tests on the boundary, the MLE for the null and alternative
        models are often the same (up to numerical precision), leading to a p-value of 1

        Parameters
        ----------
        null_point : array or list of arrays
              the MLE of the null model
              if a list of points, will do a hypothesis test for each point
        sims : the number of Gaussian simulations to use for computing null distribution
              ignored if test_type="wald"
        test_type : "ratio" for likelihood ratio, "wald" for Wald test
              only simple hypothesis tests are implemented for "wald"

              For "ratio" test:
              Note that we set the log likelihood ratio to 0 if the two
              likelihoods are within numerical precision (as defined by numpy.isclose)

              For tests on interior of parameter space, it generally shouldn't happen
              to get a log likelihood ratio of 0 (and hence p-value of 1).
              But this can happen on the interior of the parameter space.

        alt_point : the MLE for the alternative models
              if None, use self.point (the point estimate used for this ConfidenceRegion)
              dimensions should be compatible with null_point
        null_cone, alt_cone : the nested Null and Alternative models
              represented as a list, whose length is the number of parameters
              each entry of the list should be in (None,0,1,-1)
                     None: parameter is unconstrained around the "truth"
                     0: parameter is fixed at "truth"
                     1: parameter can be >= "truth"
                     -1: parameter can be <= "truth"

              if null_cone=None, it is set to (0,0,...,0), i.e. totally fixed
              if alt_cone=None, it is set to (None,None,...), i.e. totally unconstrained
        p_only : bool
              if True, only return the p-value (probability of observing a more extreme statistic)
              if False, return 3 values per test:
                   [0] the p-value: (probability of more extreme statistic)
                   [1] probability of equally extreme statistic (up to numerical precision)
                   [2] probability of less extreme statistic

              [1] should generally be 0 in the interior of the parameter space.
              But on the boundary, the log likelihood ratio will frequently be 0,
              leading to a point mass at the boundary of the null distribution.
        """
        in_shape = np.broadcast(np.array(null_point), np.array(alt_point),
                                np.array(null_cone), np.array(alt_cone)).shape

        null_point = np.array(null_point, ndmin=2)

        if null_cone is None:
            null_cone = [0] * null_point.shape[1]
        null_cone = np.array(null_cone, ndmin=2)

        if alt_point is None:
            alt_point = self.point
        alt_point = np.array(alt_point, ndmin=2)

        if alt_cone is None:
            alt_cone = [None] * null_point.shape[1]
        alt_cone = np.array(alt_cone, ndmin=2)

        b = np.broadcast_arrays(null_point, null_cone, alt_point, alt_cone)
        try:
            assert all(bb.shape[1:] == (len(self.point), ) for bb in b)
        except AssertionError:
            raise ValueError("points, cones have incompatible shapes")
        b = [list(map(tuple, x)) for x in b]
        null_point, null_cone, alt_point, alt_cone = b

        if test_type == "ratio":
            sims = np.random.multivariate_normal(self.score,
                                                 self.score_cov,
                                                 size=sims)

            liks = {}
            for p in list(null_point) + list(alt_point):
                if p not in liks:
                    liks[p] = self.lik_fun(np.array(p))

            sim_mls = {}
            for nc, ac in zip(null_cone, alt_cone):
                if (nc, ac) not in sim_mls:
                    nml, nmle = _project_scores(sims,
                                                self.fisher,
                                                nc,
                                                psd_rtol=self.psd_rtol)
                    aml, amle = _project_scores(sims,
                                                self.fisher,
                                                ac,
                                                psd_rtol=self.psd_rtol,
                                                init_vals=nmle)
                    sim_mls[(nc, ac)] = (nml, aml)

            ret = []
            for n_p, n_c, a_p, a_c in zip(null_point, null_cone, alt_point,
                                          alt_cone):
                lr = _trunc_lik_ratio(liks[n_p], liks[a_p])
                lr_distn = _trunc_lik_ratio(*sim_mls[(n_c, a_c)])
                ret += [
                    list(
                        map(np.mean,
                            [lr > lr_distn, lr == lr_distn, lr < lr_distn]))
                ]
            ret = np.array(ret)
        elif test_type == "wald":
            if np.any(np.array(null_cone) != 0) or any(
                    a_c != tuple([None] * len(self.point))
                    for a_c in alt_cone):
                raise NotImplementedError(
                    "Only simple tests implemented for wald")

            gdmb = self.godambe(inverse=False)

            resids = np.array(alt_point) - np.array(null_point)
            ret = np.einsum("ij,ij->i", resids, np.dot(resids, gdmb))
            ret = 1. - scipy.stats.chi2.cdf(ret, df=len(self.point))
            ret = np.array([ret, [0] * len(ret), 1. - ret]).T
        else:
            raise NotImplementedError("%s tests not implemented" % test_type)

        if p_only:
            ret = ret[:, 0]
        if len(in_shape) == 1:
            ret = np.squeeze(ret)
        return ret