Question

I have a problem with optimize().

When I limit the search in a small interval around zero, e.g., (-1, 1), the optimize algorithm gives a finite minimum with a finite objective function value.

But when I make the interval wider to (-10, 10), then the minimum is on the boundary of the interval and the objective is Inf, which is really puzzling for me.

How can this happen and how to fix this? Thanks a lot in advance.

The following is my code.

set.seed(123)
n <- 120
c <- rnorm(n,mean=1,sd=.3); 
eps <- rnorm(n,mean=0,sd=5)                   
tet <- 32
r <-   eps * c^tet

x <- matrix(c(c,r), ncol=2)

g <- function(tet, x){   
  matrix((x[,1]^(-tet))*x[,2],ncol=1)
}

theta <- 37
g_t <- g(theta,x)

f.tau <- function(tau){
  exp.tau.g <- exp(g_t %*% tau)
  g.exp <- NULL; i <- 1:n
  g.exp <- matrix(exp.tau.g[i,] * g_t[i,], ncol=1)
  sum.g.exp <- apply(g.exp,2,sum)
  v <- t(sum.g.exp) %*% sum.g.exp
  return(v)
}

band.tau <- 1; 
f <- optimize(f.tau, c(-band.tau, band.tau), tol=1e-20)  
print("interval=(-1, 1)"); print(f);

band.tau <- 10;
f <- optimize(f.tau, c(-band.tau, band.tau), tol=1e-20)  
print("interval=(-10, 10)"); print(f);
Was it helpful?

Solution

The problem is that your function f.tau(x) is not well behaved. You can see that here:

vect.f <- Vectorize(f.tau)
z1     <- seq(-1,1,by=0.01)
z10    <- seq(-10,10,by=0.01)
par(mfrow=c(2,1), mar=c(2,2,1,1))
plot(z1, log(vect.f(z1)), type="l")
plot(z10,log(vect.f(z10)),type="l")

Note that these are plots of log(f.tau). So there are two problems: f.tau(...) has an extremely large slope on either side of the minimum, and f.tau = Inf for x<-0.6 and x>1.0, where Inf means that f.tau(...) is greater than the largest number that can be represented on this system. When you set the range to (-1,1) your starting point is close enough to the minimum that optimize(...) manages to converge. When you set the limits to (-10,10) the starting point is too far away. There are examples in the documentation which show a similar problem with functions that are not nearly as ill-behaved as f.tau.

EDIT (Response to OP's comment)

The main problem is that you are trying to optimize a function which has computational infinities in the interval of interest. Here's a way around that.

band.tau <- 10
z        <- seq(-band.tau,band.tau,length=1000)
vect.f   <- Vectorize(f.tau)
interval <- range(z[is.finite(vect.f(z))])
f        <- optimize(f.tau, interval, tol=1e-20)
f
# $minimum
# [1] 0.001615433
# 
# $objective
#              [,1]
# [1,] 7.157212e-12

This evaluates f.tau(x) at 1000 equally spaced points on (-band.tau,+band.tau), identifies all the values of x where f.tau is finite, and uses the range as the increment in optimize(...). This works in your case because f.tau(x) does not (appear to...) have asymptotes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top