Reputation: 13
I am trying to maximize the number N_ent through a 1x42 weighting vector (weight).
N_ent
is calculated with the following function:
N_ent <- exp(-sum((((solve(pca$rotation[])) %*% t(weight))^2)*
(pca$sdev^2)/(sum((((solve(pca$rotation[])) %*% t(weight))^2)*
(pca$sdev^2)))*log((((solve(pca$rotation[])) %*% t(weight))^2)*
(pca$sdev^2)/(sum((((solve(pca$rotation[])) %*% t(weight))^2)*(pca$sdev^2))))))
Though it looks quite complicated, the equation works fine and supplies me with N_ent = 1.0967
when equal weights of 0.0238 (1/42 = 0.0238) are used.
Further, none of the weights may be below -0.1 or above 1.
I am new to R have struggled to use both the optim()
(ignoring my constraints) and constrOptim()
functions, encountering the error
Error in match.arg(method) : 'arg' must be of length 1
when optim()
was used and
Error in ui %*% theta : non-conformable arguments
when constrOptim()
was used.
Any help on how to set up the code for such an optimization problem would be greatly appreciated.
Upvotes: 1
Views: 902
Reputation: 4643
Here is the solution using library nloptr
.
library(nloptr)
pca <- dget('pca.csv')
#random starting point
w0 <- runif(42, -0.1, 1)
#things that do not depend on weight
rotinv <- solve(pca$rotation)
m2 <- pca$sdev^2
#function to maximize
N_ent <- function(w) {
m1 <- (rotinv %*% w)^2
-exp(-sum(m1 * m2 / sum(m1 * m2) * log(m1 * m2 / sum(m1 * m2))))
}
#call optimization function
optres <- nloptr(w0, N_ent, lb = rep(-0.1, 42), ub = rep(1, 42),
opts = list('algorithm' = 'NLOPT_LN_NEWUOA_BOUND', 'print_level' = 2, 'maxeval' = 1000, 'xtol_rel' = 0))
You can view result by optres$solution
. For your particular problem I find NLOPT_LN_NEWUOA_BOUND
algorithm giving best result of 42. You can view all available algorithms by nloptr.print.options()
. Note that _XN_
in the names of the algorithms indicate these that do not require derivatives. In your case derivative computation is not that difficult. You can provide it and use algorithms with _XD_
in the names.
Upvotes: 1