I have a function f(x)
, that is positive and decreasing for x<c
, and is zero for all x>=c
. How can I find c
, the threshold where the function hits zero (to within a tolerance)?
Here's an example:
zer = function(x){
ifelse(x>5, rep(0,length(x)), 5 - x)
}
> x=-5:15
> plot(x,zer(x))
You can use uniroot
to find where a function crosses zero, but that relies on the function being negative and positive on either side of the crossing, so I can't use that here. In the above case it evaluates zer
at the upper interval (15), finds a zero, and returns that.
I wrote a bisection algorithm that starts with the interval and moves left if f(midpoint) == 0
or right if f(midpoint) > 0
. This works, but I'm wondering if I've missed an implementation in a package or elsewhere that does this better, or if I've missed "one simple trick that lets you use uniroot to solve this".
The best I can find in the docs is the Numerical Task View's cryptic "There are implementations of the bisection algorithm in several contributed packages."
Note I don't have the gradient of f(x) so can't use Newton's method or anything that needs gradient evaluations at x values.