Нелинейная оптимизация в R

#r #mathematical-optimization #nlopt

#r #математическая оптимизация #nlopt

Вопрос:

Я пытаюсь решить проблему оптимизации, используя пакет nloptr в R. Я не уверен, что не так со следующим кодом, поскольку я продолжаю получать эту ошибку:

Error: nlopt_add_equality_mconstraint returned NLOPT_INVALID_ARGS.

Вот проблема (обратите внимание, что (A ) ^ T — это транспонирование обратной матрицы Мура-Пенроуза матрицы A)

введите описание изображения здесь

и код:

 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
 )
  

Комментарии:

1. Вы решили эту проблему?

Ответ №1:

Я видел, как это происходит, когда люди объявляют лямбда-значение только с 1 аргументом вместо двух. Проблема, вероятно, связана с тем, как вы устанавливаете ограничения. Вы можете просмотреть этот документ по теме.

В этом случае проблема, по-видимому, связана с функцией, для которой вы используете eval_g_eq . Если я установлю для этого параметра значение NULL или функцию примера, приведенную на странице 4 документации, тогда ошибок не будет.

Комментарии:

1. Большое вам спасибо за попытку помочь. Я на самом деле никогда nloptr раньше не использовал, поэтому мои знания ограничены. Я попытался найти, какой аргумент отсутствует, но я действительно не могу обнаружить ничего плохого… Я был бы очень признателен за вашу помощь, если бы вы могли уделить несколько минут. Спасибо!

2. На самом деле, я понимаю, что если я подавлю ограничение равенства, проблема будет решена! Но я не уверен, почему я должен подавлять ограничение???

3. Кроме того, я хотел бы добавить дополнительное ограничение неравенства, которое t(ginv(A)) %*% y >= 0 . Я не уверен, как настроить nloptr с несколькими ограничениями неравенства…

4. Хорошо, конечно. Мой первый комментарий заключается в том, что в вашем приведенном выше коде отсутствует a ) в разделе #### Ограничение равенства. Это не то, что вызывает вашу ошибку, но это должно быть исправлено в сообщении, чтобы сделать это более легко воспроизводимым. С этим покончено, я попытаюсь найти ошибку в коде.

5. Похоже, ему не нравится ваш параметр eval_g_eq. Когда я устанавливаю для этого параметра значение NULL, он завершается без ошибок (но не так с любым другим параметром). Более того, если я увижу это в функции, указанной на странице 4 документации ( r.adu.org.za/web/packages/nloptr/nloptr.pdf ) тогда все работает нормально.