Search code examples
roptimizationmathematical-optimization

apply an optimal function to a function using a for loop in r


I wrote a simple function for maximum likelihood and would like this function to give different result based on the different values of its parameters using for loop in R. That is my function include an expression based on for loop. My function works well and the result are saved in a list. Then, Since I have two different results, I would like to apply the optim function to my function based on each part of my function. For example,

ff <- function(x,mu=c(2,0.5),sd=c(0.2,0.3)){
  out <- vector("list",2)
  for (i in 1:2){
    out[[i]] <- -sum(log(dnorm(x,mu[[i]],sd[[i]]))) ## here I have two different part of my funcitons wrap as one using for loop.
  }
return(out)
}


 set.seed(123)
    x <- rnorm(10,2,0.5)
    x

Then the result of my function is:

> ff(x)
[[1]]
[1] 25.33975

[[2]]
[1] 101.4637

Then, since my function has two different parts wrap as one using for loop, I would like to apply the optim function to this function based on each part of it. I tried many own methods and they did not work. Here is one of my tries:

op <- vector("list",2)
for(i in 1:2){

op <- optim(c(0.5,0.5),fn=ff[[i]],i=i)
}

That is, I want the optim function to evaluate my function at the first value of my argument i=1 and then evaluate the function for the second one i=2.

So my funcitons without the wrap is as follows:

ff_1 <- function(x,mu=c(2,0.5),sd=c(0.2,0.3)){
      -sum(log(dnorm(x,mu[[1]],sd[[1]]))) 

    return(out)
    }

 ff_2 <- function(x,mu=c(2,0.5),sd=c(0.2,0.3)){
      -sum(log(dnorm(x,mu[[2]],sd[[2]]))) 

    return(out)
    }

and I then need to use two different optim functions for each functions.

I search many website and R help sites but I couldnot find a solution to this question.

Any help please?


Solution

  • Try this one, it's just the way of passing the arguments to optim, I suppose

    # given data
    set.seed(123)
    x <- rnorm(10,2,0.5)
    
    # use vector parOpt instead of specifying two; for convience
    # with optim
    ff <- function(x, parOpt){
      out  <- -sum(log(dnorm(x, parOpt[1], parOpt[2]))) 
      return(out)
    }
    
    
    # parameters in mu,sd vectors arranged in list
    params <- list(set1 = c(2, 0.2), set2 = c(0.5, 0.3))
    
    # output list
    out <- list()
    
    for(i in 1:2){
      # pass params (mu and sd) to optim, function ff and the data
      # note, since function ff has x argument, specify that in optim
      out[[i]] <- optim(par = params[[i]], fn=ff ,x=x)
    
    }
    

    Should give something like this:

    [[1]]
    [[1]]$par
    [1] 2.0372546 0.4523918
    
    [[1]]$value
    [1] 6.257931
    
    [[1]]$counts
    function gradient 
          55       NA 
    
    [[1]]$convergence
    [1] 0
    
    [[1]]$message
    NULL
    
    
    [[2]]
    [[2]]$par
    [1] 2.037165 0.452433
    
    [[2]]$value
    [1] 6.257932
    
    [[2]]$counts
    function gradient 
          73       NA 
    
    [[2]]$convergence
    [1] 0
    
    [[2]]$message
    NULL
    

    Hope this helps.