0
votes

I have the following problem: I have to solve an optimization problem in multiple dimensions. However, the problem is somehow nice in the sense: I can split the problem in an outer and an inner optimization reducing the dimension. The inner optimization can be solved very efficiently (linear algebra). The code is somewhat lengthy. For this reason I created a toy model.

out.obj <- function(x,storage){
  inner.sol <- inner.obj(param = x)
  storage <- append(storage,inner.sol)
  return((x-inner.sol)^2)
}

inner.obj <- function(x = NULL,param){
  return(log(param)^2-param)
}
storage <- c()
sol <- optim(par = c(3),fn = out.obj,storage = storage)

This example doesnt make much sense from a mathematical point of view. However, it shows my problem regarding extracting the inner solution. In the above code we have a 2dim problem, x1,x2. As you can see I call optim for the outer objective function. Given a value for the x1 we can "solve" for x2.

At the end I would like to have the two optimal values for x1 and x2. For this I used the parameter storage. But the storage gets a local version and I cant retrieve the optimal value for x2. I also tried the following:

    storage <- c()
    out.obj <- function(x){
      inner.sol <- inner.obj(param = x)
      storage <- append(storage,inner.sol)
      return((x-inner.sol)^2)
    }

    inner.obj <- function(x = NULL,param){
      return(log(param)^2-param)
    }

    sol <- optim(par = c(3),fn = out.obj)

In this case storage should be globally defined. Still the values for x2 are not getting populated. How can I get this value?


**EDIT**

f2 <- function(y=NULL){
  storage <- c()
sol <- optim(par = c(3),fn = out.obj)
return(list("sol" = sol,"storage"=storage))
}

f1 <- function(p=NULL){
  temp <- f2(NULL)
  return(temp)
}

out.obj <- function(x){
  inner.sol <- inner.obj(param = x)
  storage <<- append(storage,inner.sol)
  return((x-inner.sol)^2)
}

inner.obj <- function(x = NULL,param){
  return(log(param)^2-param)
}
1

1 Answers

2
votes

Use <<-

storage <<- append(storage,inner.sol)

or assign :

assign("storage", append(storage, inner.sol), .GlobalEnv))

Regarding modified problem where storage is not in the global environment pass the environment that storage is in to out.obj as shown:

f2 <- function(y=NULL){
  storage <- c()
  sol <- optim(par = c(3),fn = out.obj, e = environment())
  return(list("sol" = sol,"storage"=storage))
}

out.obj <- function(x, e){
  inner.sol <- inner.obj(param = x)
  assign("storage", append(e$storage, inner.sol), e)
  return((x-inner.sol)^2)
}

The assign line could alternatively be written as:

 e$storage <- append(e$storage, inner.sol)