Search code examples
roptimizationconstraintsminimization

function minimization in r with constraints on function of parameters


Many libraries are available in R to perform minimisation. However, all the ones I could find (e.g. rcgmin, or optimx) only allow lower and upper bounds on the input parameters:

opt_Params <- Rcgmin(par = Params_init,
                     fn = cost_func,
                     gr = params_grad,
                     lower = min_par,
                     upper = max_par
                     )

I'm looking for something different: boundaries not on the input parameters, but on the values of a function that takes them.

Concretely, my cost_func is a cost function that measures the sum of the squared residuals between my (fixed) observed data Y_obs and the prediction from my fitted parameters Y_calc:

cost_func <- function(Params) {
        X <- Params[1:(num_items*num_features)]
        dim(X) <- c(num_items,num_features)

        Theta <- Params[(num_items*num_features+1):length(Params)]
        dim(Theta) <- c(num_users,num_features)

        Y_calc <- X * t(Theta)
        J <- ((Y_calc - Y_obs) * (Y_calc - Y_obs))

        cost <- sum(rowSums(J)[])

        return(cost)
}

Minimising the cost function, I can ensure that my predicted Y_calc get ever closer to Y_obs.

This however allows for arbitrary values in Y_calc. What I would like to do is to impose the same boundaries as I know to be present in Y_obs (between 0 and 10 - this is a collaborative filtering algorithm). So I'm not trying to put constraints on my input parameters, but on a function of them (namely, on every element of Y_calc <- X * t(Theta)).

Is there an R minimisation library in which this is possible? Or do I need to change my approach?


Solution

  • I think you can try something like this :

    library(DEoptim)
    
    cost_func <- function(Params) 
    {
      X <- Params[1 : (num_items * num_features)]
      dim(X) <- c(num_items,num_features)
      Theta <- Params[(num_items * num_features + 1) : length(Params)]
      dim(Theta) <- c(num_users,num_features)
      Y_calc <- X * t(Theta)
      
      if((Y_calc < 0) | (Y_calc > 10))
      {
        return(10 ^ 30)
        
      }else
      {
        J <- ((Y_calc - Y_obs) * (Y_calc - Y_obs))
        cost <- sum(rowSums(J)[])
        return(cost)
      }
    }
    
    DEoptim(par = Params_init,
            fn = cost_func,
            lower = min_par,
            upper = max_par)
    

    If a parameter set generates a value of Y_calc that is between 0 and 10, the objective function will return a very high value. Hence, the DEoptim algorithm will not consider this set of parameters as a candidate solution.