5

I am trying to solve an optimization problem using the package nloptr in R. I am not sure what is wrong with the following code, as I keep getting this error:

Error: nlopt_add_equality_mconstraint returned NLOPT_INVALID_ARGS.

Here is the problem (note that (A+)^T is the transpose of the Moore-Penrose inverse of matrix A)

enter image description here

and the code:

library( MASS ) ## for the Moore-Penrose inverse ginv()
library( zoo )
library( nloptr )

A = matrix(runif(27, -0.5, 0.5), nc = 3)
sigma = diag(runif(3,0.001,0.002))
M = ncol(A)
b = 1 / M
n = nrow(A)
init_y = rep(1/M, M)
c = -ncol(A)*log(ncol(A))



#### Objective function
eval_f <- function(y) 
{
return( sqrt( as.numeric( t(y) %*% sigma %*% y ) ) )
}

#### Gradient of objective function
eval_grad_f <- function(y) 
{
return( ( 2* sigma %*% y) / as.numeric(sqrt( t(y) %*% sigma %*% y )) )
}

#### Equality Constraint
eval_g_eq <- function(y)
{
return( ( t(ginv(A)) %*% y ) - 1 )## ginv(a) is the Moore-Penrose inverse of A
}


#### Inequality constraint
eval_g_ineq <- function(y)
{
return( c - sum( log(y) * b ) )
}

#### Jacobian of equality constraint
eval_jac_g_eq <- function(y)
{
return( ginv(A) )
} 

#### Jacobian of inequality constraint
eval_jac_g_ineq <- function(y)
{
return( (-1/y) * b )
}


 opts <- list( "algorithm" = "NLOPT_LD_SLSQP",
          "xtol_rel"  = 1.0e-14)

 res0 <- nloptr( x0=init_y,
 eval_f=eval_f,
 eval_grad_f=eval_grad_f,
 lb = rep(0,ncol(A)),
 ub = rep(Inf,ncol(A)),
 eval_g_eq = eval_g_eq,
 eval_jac_g_eq = eval_jac_g_eq,
 eval_g_ineq = eval_g_ineq,
 eval_jac_g_ineq = eval_jac_g_ineq,
 opts = opts
 )
Mayou
  • 7,628
  • 15
  • 51
  • 91

1 Answers1

2

I've seen this happen when people declare a lambda value with only 1 argument instead of two. The problem is probably to do with how you're setting the constraints. You can review this document on the topic.

In this case, the problem seems to be to do with the function that you're using for eval_g_eq. If I set this parameter to either NULL or the example function given on Page 4 of the documentation, then there are no errors.

Hack-R
  • 19,705
  • 11
  • 63
  • 110
  • Thank you very much for trying to help. I have actually never used `nloptr` before, so my knowledge is limited. I have tried to find what argument is missing, but I really can't spot anything wrong... I would really appreciate your help if you could devote a few minutes. Thanks! – Mayou Jun 25 '14 at 13:29
  • Actually, I realize that if I suppress the equality constraint, the problem gets solved! But I am not sure why I should suppress the constraint??? – Mayou Jun 25 '14 at 14:12
  • Also, I would like to add an additional inequality constraint that `t(ginv(A)) %*% y >= 0`. I am not sure how to set-up the `nloptr` with multiple inequality constraints... – Mayou Jun 25 '14 at 14:15
  • OK, sure. My first comment is that your code above is missing a ) in the #### Equality Constraint section. That's not what's causing your error, but it should be fixed in the post to make this more easily reproducible. With that out of the way, I'll try to hunt the bug in the code. – Hack-R Jun 26 '14 at 18:37
  • It seems like it doesn't like your eval_g_eq parameter. When I set that parameter to NULL it finishes without error (but not so with any other parameter). Moreover, if I see it to the function given on Page 4 of the documentation (http://r.adu.org.za/web/packages/nloptr/nloptr.pdf) then it works fine. – Hack-R Jun 26 '14 at 18:55
  • I can't work on the other question about multiple constraints right now; perhaps later. But nloptr is just an R wrapper of nlopt, so you might get started by Google-ing multiple constraints with nlopt, as it probably has more users and documentation than nloptr. – Hack-R Jun 26 '14 at 19:05