Skip to content

Commit a9d86d4

Browse files
committed
fix mixed-monotonic bug
1 parent 0d5a4f1 commit a9d86d4

File tree

6 files changed

+31
-8
lines changed

6 files changed

+31
-8
lines changed

binomial_cis/volume.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ def max_expected_shortage(alpha, n, tol=1e-3, verbose=True, randomized=True):
163163
"""
164164
I = Interval(0,1)
165165
if randomized:
166-
def F(p1, p2): expected_shortage_mixed_monotonic(llc_accept_prob, alpha, n, p1, p2)
166+
def F(p1, p2): return expected_shortage_mixed_monotonic(llc_accept_prob, alpha, n, p1, p2)
167167
else:
168-
def F(p1, p2): expected_shortage_mixed_monotonic_cp(alpha, n, p1, p2)
168+
def F(p1, p2): return expected_shortage_mixed_monotonic_cp(alpha, n, p1, p2)
169169

170170
ub, lb, p_lb, num_iters = mmp_solve(F, I, tol=tol, max_iters=1000, verbose=verbose)
171171
return ub, lb, p_lb, num_iters
@@ -224,7 +224,7 @@ def max_expected_width(alpha, n, tol=1e-3, verbose=True):
224224
I = Interval(0,1)
225225
# expected width is increasing in p2 and decreasing in p1
226226
# mmp_solve expects increasing in first arg and decreasing in second arg
227-
def F(p2, p1): expected_width_mixed_monotonic(llc_accept_prob_2_sided, alpha, n, p1, p2)
227+
def F(p2, p1): return expected_width_mixed_monotonic(llc_accept_prob_2_sided, alpha, n, p1, p2)
228228
ub, lb, p_lb, num_iters = mmp_solve(F, I, tol=tol, max_iters=1000, verbose=verbose)
229229
return ub, lb, p_lb, num_iters
230230

docs/_include/tests.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ Then, create a virtual environment and load the dependencies (these commands are
2020
2121
binom_ci_test.py
2222
******************
23-
This file contains functions to test the correctness of the lower, upper, and 2-sided bounds.
23+
This file contains functions to test the correctness of the lower, upper, 2-sided bounds, and the mixed monotonic solver.
2424
The lower/upper bound tests ensure the bounds we compute are better than Clopper-Pearson bounds (without being too optimistic).
2525
The 2-sided test ensures that our 2-sided bounds agree with those computed by Blyth and Hutchinson in their 1960 paper titled "Table of Neyman-Shortest Unbiased Confidence Intervals for the Binomial Parameter".
26+
The mixed monotonic test ensures that the computed maximum of expected shortage/excess/width is greater than the sample-based maximum of these quantities.
2627
We use a Github Action to automatically run the tests in this file via ``pytest``.
2728
To run the tests yourself simply navigate to the ``tests/`` directory and run
2829

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
project = 'binomial_cis'
1414
copyright = '2024, Joe Vincent'
1515
author = 'Joe Vincent'
16-
release = '0.0.12'
16+
release = '0.0.11'
1717

1818
# -- General configuration ---------------------------------------------------
1919
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name="binomial_cis",
5-
version='0.0.12',
5+
version='0.0.11',
66
author="Joe Vincent",
77
description="Confidence intervals for binomial distributions.",
88
packages=find_packages(),

tests/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The tests are written in the form of interactive notebooks.
22

33
- `2_side_validation.ipynb`: This notebook can be used to more easily inspect any differences between our 2-sided bounds and those from the Blyth paper.
4-
- `binom_ci_test.py`: This file can be used to test the correctness of the lower, upper, and 2-sided bounds.
4+
- `binom_ci_test.py`: This file can be used to test the correctness of the lower, upper, and 2-sided bounds, and the correctness of the mixed-monotonic solver.
55
- `binom_helper_validation.ipynb`: This notebook can be used to validate the binomial helper functions from `binomial_cis/binomial_helper.py`. Accuracy and speed of our implementation is tested against the SciPy implementation.
66
- `conf_set_validation.ipynb`: This notebook can be used to validate the probabilistic guarantees of the confidence intervals using Monte Carlo simulation.

tests/binom_ci_test.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
from math import isclose
66
import pandas as pd
77

8+
from binomial_cis.conf_intervals import llc_accept_prob, llc_accept_prob_2_sided
9+
from binomial_cis.volume import expected_excess, max_expected_excess
10+
from binomial_cis.volume import expected_shortage, max_expected_shortage
11+
from binomial_cis.volume import expected_width, max_expected_width
12+
813

914
# define range of test conditions
1015
ns = np.array(range(1,50+1))
@@ -208,5 +213,22 @@ def test_2_sided():
208213

209214

210215

211-
216+
def test_mixed_monotonicity():
217+
"""
218+
Test that our values for MES, MEE, and MEW actually upper bound the
219+
sample-based maximum of these quantities
220+
"""
221+
n = 10
222+
alpha = 0.05
223+
mes_ub, _, _, _ = max_expected_shortage(alpha, n, verbose=False)
224+
mee_ub, _, _, _ = max_expected_excess(alpha, n, verbose=False)
225+
mew_ub, _, _, _ = max_expected_width(alpha, n, verbose=False)
226+
227+
sample_mes = max([expected_shortage(llc_accept_prob, alpha, n, p) for p in np.linspace(0.01, 0.99, num=50)])
228+
sample_mee = max([expected_excess(llc_accept_prob, alpha, n, p) for p in np.linspace(0.01, 0.99, num=50)])
229+
sample_mew = max([expected_width(llc_accept_prob_2_sided, alpha, n, p) for p in np.linspace(0.01, 0.99, num=50)])
230+
231+
assert mes_ub >= sample_mes
232+
assert mee_ub >= sample_mee
233+
assert mew_ub >= sample_mew
212234

0 commit comments

Comments
 (0)