indu mann
indu mann

Reputation: 63

Optimisation reproduces initial values?

I am trying to maximize the following function with optimx in R

#Initial Parameter Values
beta1=0.5
beta2=0.5
lambda1=0.5
lambda2=0.5
delta=5

loglik=function(par) {sum(log(lambda1*PDF1+lambda2*PDF2))+delta*(lambda1+lambda2-1)}

G2=optimx(c(0.5,0.5,0.5,0.5,2),fn=loglik,gr=NULL, lower=-Inf, upper=Inf, hessian=FALSE)

But every time the optimization reproduces the initial values that I provide to the system, for e.g this is the response I get to the optimization using the above mentioned initial values.

             p1  p2  p3  p4 p5    value fevals gevals niter convcode  kkt1 kkt2
Nelder-Mead 0.5 0.5 0.5 0.5  2 5144.569      6     NA    NA        0 TRUE   NA
BFGS        0.5 0.5 0.5 0.5  2 5144.569      1      1    NA        0 TRUE   NA
            xtimes
Nelder-Mead      0
BFGS             0

Can anyone please tell whats going on?

Upvotes: 0

Views: 169

Answers (1)

Matthew Drury
Matthew Drury

Reputation: 1095

Note: I switched out optimx for the built in optim in my answer. This does not change the content. I also switched out your PDF1 and PDF2 in the function body for beta1 and beta2 on a hunch about your intent.

You're misunderstanding how optimx, and honestly, functions, work.

Here's your definition of loglik

loglik <- function(par) {
  sum(log(lambda1*beata1 + lambda2*beta2)) + delta*(lambda1 + lambda2 - 1)
}

Now watch

> loglik(1)
[1] -0.6931472
> loglik(2)
[1] -0.6931472
> loglik("I like cats.")
[1] -0.6931472

You haven't so much defined a function, but a constant. You can see this by observing that the function you defined makes no reference to its argument par. Instead, it ignores par and simply looks up the variables it contains in its enclosing environment.

You most likely meant to do this

loglik <- function(par) {
  sum(log(par[3]*par[1] + par[4]*par[2])) + par[5]*(par[3] + par[4] - 1)
}

After which the optimization works as intended

optim(c(0.5,0.5,0.5,0.5,2), fn=loglik, gr=NULL, lower=-Inf, upper=Inf, hessian=FALSE)
$par
[1]  0.6466066  0.8102440 -0.2802594  0.2236580  2.6381565

$value
[1] -40.91057

$counts
function gradient 
     501       NA 

$convergence
[1] 1

A convergence code of 1 does not indicate convergence

1 indicates that the iteration limit maxit had been reached.

Indeed, there are plenty of warnings

warnings()
1: In log(par[3] * par[1] + par[4] * par[2]) : NaNs produced
2: In log(par[3] * par[1] + par[4] * par[2]) : NaNs produced

You'll have to sort that out, I don't know what you are actually trying to accomplish with this call.

Thank you, But the problem is PDF1 and PDF2 are also functions defined by

PDF1=function(beta1) {BiCopPDF(u,v,par=abs(beta1),family=5)}

and

PDF2=function(beta2) {BiCopPDF(u,v,par=beta2,family=3)}

How do I manage that?

You will have to call into PDF1 and PDF2 within the function you are optimizing. If I understand correctly, this would result in something like:

loglik <- function(par) {
  sum(log( par[3]*PDF1(par[1]) + par[4]*PDF2(par[2]) )) + par[5]*(par[3] + par[4] - 1)
}

Upvotes: 3

Related Questions