Tom.K
Tom.K

Reputation: 13

Maximize a target number by optimizing a weighting vector

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

Answers (1)

danas.zuokas
danas.zuokas

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

Related Questions