Optimization with nloptr using matrix

58 views Asked by At

I want to balance an unbalanced matrix. Unbalanced in the sense that the row and column sums do not match given values. I made a small example The matrix U is the start matrix and its row and column sums are used as the "new" values that the unbalanced matrix Uu should match. I have two constraints for the row and column sums and an objective function. (in reality I have a matrix of size 60x60 and the given row and col sums are given and not taken from the starting matrix). I have also defined some lower and upper bounds. When I try to run the following code, nloptr gives me following error:

Error in .checkfunargs(eval_f, arglist, "eval_f") : 
  u' passed to (...) in 'nloptr' but this is not required in the eval_f function.

Here is the code

library(nloptr)
U <- matrix(c(3,5,4,6),  ncol = 2, nrow = 2)
Uu <- matrix(c(3,5,4,5),  ncol = 2, nrow = 2)

eq_constr <- function(u, uu) {
  c(rowSums(uu) - rowSums(u),
  colSums(uu) - colSums(u))
}
  
obj_function <- function(u, uu) {
  sum(uu * log(uu/u))
}

opts <- list( "algorithm" = "NLOPT_GN_ISRES")

lb <- matrix(c(0,0,0,0), ncol = 2, nrow = 2)
ub <- matrix(c(1000, 1000, 1000, 1000), ncol = 2, nrow = 2)

res <- nloptr(
  x0 = u,
  lb          = lb,
  ub          = ub,
  eval_f      = obj_function,
  eval_g_eq   = eq_constr,
  opts        = opts,
  u           = U,
  uu          = Uu)
print(res)

As always: any help would be aprreciated.

Cheers

Renger

1

There are 1 answers

0
arnyeinstein On

This is scary: I got an answer from the chatbot from Bing and used it to get to the answer:

library(nloptr)
U <- matrix(c(3,5,4,6),  ncol = 2, nrow = 2)

eq_constr <- function(uu) {
  c(uu[1] + uu[2] - rowSums(U)[1],
    uu[3] + uu[4] - rowSums(U)[2],
    uu[1] + uu[3] - colSums(U)[1],
    uu[2] + uu[4] - colSums(U)[2]
    )
}

obj_function <- function(uu) {
  uu <- matrix(uu, nrow = 2)
  sum(uu * log(uu/U))
}

obj_function(uu)
uu <- x0
opts <- list( "algorithm" = "NLOPT_GN_ISRES")

lb <- matrix(c(0,0,0,0), ncol = 2, nrow = 2)
ub <- matrix(c(1000, 1000, 1000, 1000), ncol = 2, nrow = 2)

res <- nloptr(
  x0 = c(3,5,4,5),
  lb          = lb,
  ub          = ub,
  eval_f      = obj_function,
  eval_g_eq   = eq_constr,
  opts        = opts,

)
print(res)

Unfortunately, the problem now is that I have to write out all the constraints (for a 60x 60 matrix)