Оптимизация значений в матрице

Обычно я использую Rsolnp для оптимизации, но мне сложно понять, как попросить R найти значения для заполнения матрицы (вместо вектора). Это возможно с Rsolnp или любым другим оптимизатором?

Вот упрощенный пример, который не работает:

library(Rsolnp)

a<-matrix(rnorm(9), ncol=3)
b<-matrix(rnorm(9), ncol=3)

f1<-function(H) {
    return(sum(H*a))
}

f2<-function(H) {
    return(sum(H*b))
}

lH<-matrix(rep(0, 9), ncol=3)
uH<-matrix(rep(1, 9), ncol=3)
pars<-uH
target<-1.2

sol <- gosolnp(pars, fixed=NULL, fun=f1, eqfun=f2, eqB=target, LB=lH, UB=uH, distr=uH, n.restarts=10, n.sim=20000, cluster= NULL)

Как видно из вывода, Rsolnp, похоже, смущен запросом:

> sol
$values
[1] 1e+10

$convergence
[1] 0

$pars
[1] NA NA NA NA NA NA NA NA NA

$start.pars
[1] 0.90042133 0.33262541 0.94586530 0.02083822 0.99953060 0.10720068 0.14302770 0.67162637 0.25463806

$rseed
[1] 1487866229

1 ответ

Решение

Кажется, что gosolnp() не работает с матрицами. Я прошел через функцию в режиме отладки, и есть вызов solnp() что не так с сообщением:

Ошибка в pb/cbind(vscale[(neq + 2):(neq + mm + 1)], vscale[(neq + 2):(neq +: несовместимые массивы

Но поскольку матрица - это просто вектор с установленным атрибутом измерения, вы всегда можете переформулировать свою проблему в терминах векторов. В вашем случае это очень просто, потому что вы никогда не делаете то, что действительно требует матрицы (например, матричный продукт). Просто опуская matrix() везде отлично работает.

Но я предполагаю, что это всего лишь свойство вашей упрощенной проблемы, и ваша настоящая проблема действительно должна быть выражена в виде матриц. Вы можете обойти эту проблему, преобразовав свои векторы в матрицы только внутри функций f1() а также f2() следующее:

f1 <- function(H) {
    return(sum(matrix(H, ncol = 3) * a))
}

f2 <- function(H) {
    return(sum(matrix(H, ncol = 3) * b))
}

Вы можете определить a а также b как матрицы, как и раньше, но lH а также uH должны быть векторы:

a <- matrix(rnorm(9), ncol=3)
b <- matrix(rnorm(9), ncol=3)

lH <- rep(0, 9)
uH <- rep(1, 9)
pars <- uH
target <- 1.2

И теперь вы можете позвонить gosolnp():

sol <- gosolnp(pars, fixed = NULL, fun = f1, eqfun = f2,
               eqB = target, LB = lH, UB = uH, distr = uH,
               n.restarts = 10, n.sim = 20000, cluster = NULL)
sol$pars
## [1] 3.917819e-08 9.999997e-01 4.748336e-07 1.000000e+00 5.255060e-09 5.114680e-10
## [7] 4.899963e-01 1.000000e+00 9.260947e-08
Другие вопросы по тегам