Search code examples
rmathematical-optimization

Passing multiple starting values to nlminb


I've tried do.call and apply, and there was a similar nlminb answer that used the plyr package but still no good. So I turn to you all for any suggestions.

I've created the following function:

calloptim <- function( under,strike, rf, ttoe,par) {(-(under*par[1]
  -strike*exp(-rf*ttoe)*par[2]))^2}

and then used nlminb to estimate par while holding the other arguments constant:

nlminb(c(2,2), calloptim, under= 90, strike = 100, rf =0.05, ttoe=3)

which yields:

$par
[1] 1.953851 2.043045

$objective
[1] 1.335531e-17

$convergence
[1] 0

$iterations
[1] 4

$evaluations
function gradient 
       6       10 

$message
[1] "X-convergence (3)"

when I put in another starting value, for example

nlminb(c(5,5), calloptim, under= 90, strike = 100, rf =0.05, ttoe=3)

I get different estimates:

$par
[1] 4.885987 5.109036

$objective
[1] 2.464145e-14

$convergence
[1] 1

$iterations
[1] 2

$evaluations
function gradient 
      33        4 

$message
[1] "false convergence (8)"

And thats ok! I understand mathematically what's happening. In fact I want to use different starting values.

My problem arises when I try to pass multiple starting values to nlminb.

I create a matrix:

f<- c(2,5,2,5)
dim(f) <- c(2,2)

> f
     [,1] [,2]
[1,]    2    2
[2,]    5    5

But when I pass f to nlminb's starting value

nlminb(f, calloptim, under= 90, strike = 100, rf =0.05, ttoe=3)

I get:

$par
[1] 3.452902 3.610530 2.000000 5.000000

$objective
[1] 3.010198e-19

$convergence
[1] 0

$iterations
[1] 4

$evaluations
function gradient 
      22       24 

$message
[1] "X-convergence (3)"

So my question is how can I pass multiple rows of starting values to nlminb?

Thanks for any suggestions!

Rye


Solution

  • Since ?nlminb says its first argument should be a numeric vector, you need apply it to each row of your matrix f.

    out <- apply(f, 1, nlminb, objective=calloptim, under=90, strike=100, rf=0.05, ttoe=3)
    
    str(out)
    
    List of 2
     $ :List of 6
      ..$ par        : num [1:2] 1.95 2.04
      ..$ objective  : num 1.34e-17
      ..$ convergence: int 0
      ..$ iterations : int 4
      ..$ evaluations: Named int [1:2] 6 10
      .. ..- attr(*, "names")= chr [1:2] "function" "gradient"
      ..$ message    : chr "X-convergence (3)"
     $ :List of 6
      ..$ par        : num [1:2] 4.89 5.11
      ..$ objective  : num 2.46e-14
      ..$ convergence: int 1
      ..$ iterations : int 2
      ..$ evaluations: Named int [1:2] 33 4
      .. ..- attr(*, "names")= chr [1:2] "function" "gradient"
      ..$ message    : chr "false convergence (8)"