[R] vectorized uni-root?

ivo welch ivo.welch at gmail.com
Fri Nov 9 06:17:13 CET 2012


hi michael---this can be done better than with outer().  A vectorized
bisection search that works with an arbitrary number of arguments is

bisection <- function(f, lower, upper, ..., numiter =100, tolerance =
.Machine$double.eps^0.25 ) {
  stopifnot(length(lower) == length(upper))

  flower <- f(lower, ...); fupper <- f(upper, ...)
  for (n in 1:numiter) {
    mid <- (lower+upper)/2
    fmid <- f(mid, ...)
    if (all(abs(fmid) < tolerance)) break
    samesign <- ((fmid<0)&(flower<0))|((fmid>=0)&(flower>=0))
    lower <- ifelse(samesign, mid, lower )
    flower <- ifelse(samesign, fmid, flower )
    upper <- ifelse(!samesign, mid, upper )
    fupper <- ifelse(!samesign, fmid, fupper )
  }
  return(list( mid=mid, fmid=fmid, lower=lower, upper=upper,
flower=flower, fupper=fupper, n=n ))
}

test.function <- function(x, a) (x-a)*(x**2-a)
K <- 5
print( bisection( test.function, lower=rep(-100,K), upper=rep(100,K), a=1:K ))

this is almost a direct generalization of the simpler uniroot()
function that is currently in R.  if any of the R developers is
reading this, maybe they can add a version of this function and
deprecate the non-vectorized version.

/iaw



On Thu, Nov 8, 2012 at 9:53 AM, R. Michael Weylandt
<michael.weylandt at gmail.com> wrote:
> On Thu, Nov 8, 2012 at 3:05 PM, ivo welch <ivo.welch at gmail.com> wrote:
>> dear R experts--- I have (many) unidimensional root problems.  think
>>
>>   loc.of.root <- uniroot( f= function(x,a) log( exp(a) + a) + a,
>> c(.,9e10), a=rnorm(1) ) $root
>>
>> (for some coefficients a, there won't be a solution; for others, it
>> may exceed the domain.  implied volatilities in various Black-Scholes
>> formulas and variant formulas are like this, too.)
>>
>> except I don't need 1 root, but a few million.  to get so many roots,
>> I can use a for loop, or an lapply or mclapply.  alternatively,
>> because f is a vectorized function in both x and a, evaluations for a
>> few million values will be cheap.  so, one could probably write a
>> clever bisection search here.
>>
>> does a "vectorized" uniroot exist already?
>
> Not to my knowledge, but I think you're on track for a nice
> quick-and-dirty if your function is cheap like the above. Make a 2D
> grid of results with outer() and interpolate to find roots as needed.
> For smooth objective functions, it will likely be cheaper to increase
> precision than to loop over optimization routines written in R.
>
> Cheers,
> Michael




More information about the R-help mailing list