def _test_betaincinv22(plt, allclose): scipy_special = pytest.importorskip("scipy.special") # call once to load table, so that doesn't effect timing _betaincinv22.lookup(5, [0.1]) dims = np.concatenate([ np.arange(1, 50), np.round(np.logspace(np.log10(51), 3.1)).astype(np.int64) ]) x = np.linspace(0, 1, 1000) results = [] for dim in dims: ref_timer = time.time() yref = scipy_special.betaincinv(dim / 2, 0.5, x) ref_timer = time.time() - ref_timer timer = time.time() y = _betaincinv22.lookup(dim, x) timer = time.time() - timer results.append((yref, y, ref_timer, timer)) n_show = 5 resultsT = list(zip(*results)) errors = np.abs(np.array(resultsT[0]) - np.array(resultsT[1])).max(axis=1) show_inds = np.argsort(errors)[-n_show:] subplots = plt.subplots(nrows=2, sharex=True) if isinstance(subplots, tuple): _, ax = subplots for i in show_inds: yref, y, ref_timer, timer = results[i] dim = dims[i] ax[0].plot(x, y, label=f"dims={dim}") ax[1].plot(x, y - yref) speedups = np.array(resultsT[2]) / np.array(resultsT[3]) ax[0].set_title(f"average speedup = {speedups.mean():0.1f} times") ax[0].set_ylabel("value") ax[1].set_xlabel("input") ax[1].set_ylabel("error") ax[0].legend() for i, (yref, y, ref_timer, timer) in enumerate(results): # allow error to increase for higher dimensions (to 5e-3 when dims=1000) atol = 1e-3 + (np.log10(dims[i]) / 3) * 4e-3 assert allclose(y, yref, atol=atol), f"dims={dims[i]}"
def test_betaincinv22_errors(): x = np.linspace(0.1, 0.9) _betaincinv22.lookup(3, x) with pytest.raises(ValidationError, match="must be an integer >= 1"): _betaincinv22.lookup(0, x) with pytest.raises(ValidationError, match="must be an integer >= 1"): _betaincinv22.lookup(2.2, x)