Package: pba-waeber2013
This is an implementation of the probabilistic bisection algorithm (PBA)
described by Rolf Waeber in his 2013 PhD thesis.  PBA is a 1D stochastic
root-finding algorithm.  This means that it is meant to find the point where a
noisy function (i.e. a function that may return different values each time its
evaluated at the same point) crosses the x-axis.  More precisely, giveng(x) =
f(x) + ε(x), the goal is to findxsuch thatE[g(x)] = 0, wheref(x)is the function we are interested in,εis a normally
distributed noise function with median 0,g(x)is the only way we can
observef(x), andE[g(x)]is the expected value ofg(x).This algorithm works by repeatedly evaluating the noisy function at a singlexuntil the probability that we know the true sign off(x)exceeds a specified threshold.  This information is used to build a Bayesian
posterior distribution describing the location of the root.  The next point to
evaluate is then chosen from this distribution.  There are two features that
make this algorithm unique:It provides a true confidence interval in addition to the root itself.It places very little restraints on the form of the noise function.However, there are some caveats to be aware of:In my experience, the algorithm rarely converges.  This is due to the fact
that the confidence intervals only narrow as new x-coordinates are sampled,
but the closer the algorithm gets to the root, the more time it spends
sampling each x-coordinate.  That said, the algorithm seems to find the root
very accurately even when it doesn’t converge.The algorithm isn’t very numerically stable.  The posterior distribution is
represented using two arrays: one for the bin edges and one for the bin
heights.  As the algorithm progresses, the bins near the root get very thin
and very tall, which leads to loss-of-precision and overflow issues.  My
only advice on how to avoid these problems is to limit the number of
iterations.  It might also help to increase thep_cparameter.Note that I myself only have a rudimentary understanding of the math behind
this algorithm.  This implementation is based on scripts I received from the
authors, and I tried to test my code as well as possible to convince myself
that it’s doing the right thing, but I’m outside my comfort zone here.InstallationInstall from PyPI:$ pip install pba_waeber2013UsageThis module provides a single public function:>>> from pba_waeber2013 import pba_waeber2013
>>> pba_waeber2013(
...         f, a, b, *
...         tol=None,
...         rtol=None,
...         alpha=0.05,
...         p_c=0.65,
...         maxiter=1000,
...         check_bounds=False,
...         slope=None,
...         args=None,
...         kwargs=None,
... )Below are brief descriptions of the parameters:fThe stochastic function of interest.  This function can take any number of
arguments (seeargsandkwargs), but the first should be thexcoordinate to evaluate the function at.a bThe lower and upper bounds, respectively, on where the root can occur.  There
must be exactly one root in this interval.tolHow narrow the confidence interval needs to be in order for the algorithm to
be converged.  Note that if neithertolnorrtolare specified, the
algorithm will just run for the maximum number of iterations.rtolSimilar totol, but multiplied by the estimated root.alphaA parameter controlling the width of the confidence intervals.  Specifically,
the confidence level is given by1 − alpha.  In other words, for 95%
confidence intervals, setalphato 0.05.p_cRepeatedly evaluate the function at eachxcoordinate until we can reject
the null hypothesis thatf(x) = 0with probabilityp_c.  At that point,
the sign off(x)will be taken as whichever sign we observed most often.maxiterThe maximum number of function calls to make.check_boundsEvaluate the function at the boundsaandbbefore starting the
bisection.  This achieves two things.  First, it checks that the bounds have
different signs.  If this is not the case, then there are either 0 or >1
roots in the interval, and so this algorithm is not applicable.  Second, it
determines the slope of the function.  If the bounds are not checked, theslopeparameter must be manually specified.slope+1 if the function is increasing (i.e. negative before the root and positive
after) or -1 if the function is decreasing.  A slope must be given unlesscheck_boundsis True (in which case it will be calculated internally).argsAny extra arguments to pass to the function on each evaluation.kwargsAny extra keyword arguments to pass to the function on each evaluation.The return value is an object with the following attributes:xThe location of the root.x_obsAll of thexcoordinates where the function was evaluated.f_obsThe result of evaluating the function at each of the abovexcoordinates.x_postThe bin edges of the posterior distribution.log_p_postThe natural logarithms of the bin heights of the posterior distribution.
Logarithms are used to avoid multiplication overflows.ciThe confidence interval evaluated independently after a sign is determined
for each coordinate.  Note that these intervals can grow and shrink over
time.  See [Waeber2013] §3.3 for more information.ci_seqThe sequential confidence interval.  Unlike theciintervals, these are
guaranteed to never expand.  For that reason, these are the intervals used to
check for convergence.convergedTrue if the algorithm terminated because the confidence interval grew
narrower than the given tolerance, False if the algorithm terminated because
it reached the maximum number of iterations.ReferencesWaeber R. (2013) “Probabilistic bisection search for stochastic
root-finding.”Frazier PI, Henderson SG, Waeber R (2016) “Probabilistic bisection converges
almost as quickly as stochastic approximation”, arXiv:1612.03964Robbins H and Siegmund D. (1974) “The expected sample size of some tests of
power one”, The Annals of Statistics, 2(3), pp. 415–436.
doi:10.1214/aos/1176342704.