Creación de carteras aleatorias con ponderaciones xi puede considerarse como un muestreo de la superficie de un simplex dado por Ex=f y Ax≤b Dónde E y A son matrices de restricciones de igualdad y desigualdad, y f y b son soluciones para alguna cartera en la que quieras coincidir, x0 . Ajustando las ecuaciones anteriores para reflejar esto nos da: Ex=f=Ex0 y Ax≤b=Ax0.
Las restricciones de igualdad son relativamente fáciles de satisfacer, la solución es simplemente x=x0+Zr , donde Zr está en el espacio nulo de E y esto puede ser la base de un paseo aleatorio de Monte Carlo. Sin embargo, no hay una forma matemática directa de vincular las restricciones de desigualdad con las de igualdad. La solución parece ser comprobar si su paseo le lleva sobre el límite, y luego reflexionar sobre él, sin embargo, como el número de x es muy grande, el número de caras a reflejar crece con n y esto empieza a suponer un problema de tiempo de cálculo. ¿Hay alguna forma mejor de hacer este algoritmo, o simplemente es un problema difícil?
Editar: Aquí hay un ejemplo de código R con el paseo aleatorio y la reflexión sobre los límites, sólo manejando la restricción de desigualdad que todos x debe ser positivo:
require(MASS)
getWeights <- function(Emat, x0, n, verbose = FALSE) {
Z = Null(t(Emat))
ret = matrix(0, nrow = length(x0), ncol = n + 1)
## Would it be better to use apply here?
nc = ncol(Z)
mn = mean(x0)
ret[, 1] = x0 + Z %*% rnorm(nc, 0, mn)/sqrt(nc)
k = 0
if(verbose) cat("Created Vectors: ")
if(verbose) cat(paste(k))
for (i in 2:(n + 1)) {
ret[, i] = ret[, i - 1] + Z %*% rnorm(nc, 0, mn)/sqrt(nc)
m = k + 1;
while(any(ret[, i] < 0)) {
reflection = rep(0, ncol(Emat))
reflection[which(ret[, i] < 0)] = ret[, i][which(ret[, i] < 0)]
for (j in 1:ncol(Z)) {
ret[, i] = ret[, i] - 2* Z[, j] * (reflection %*% Z[, j])/sqrt(Z[,
j] %*% Z[, j])
}
##for(i in 1:nchar(paste(k))) cat("\b")
##if(verbose) cat(paste(m))
##k = m
##m = k + 1
}
if(verbose) for(i in 1:nchar(paste(k))) cat("\b")
if(verbose) cat(paste(m))
k = m
}
ret = ret[, 2:(n + 1)]
if(verbose) cat("\n")
return(ret)
}
Emat = matrix(1, ncol = 1000, nrow = 1)
x0 = rep(1/1000, 1000)
w = getWeights(Emat, x0, 1000, TRUE)
Como puedes ver este código simplemente va demasiado lento. (¿Crees que sería mejor intentar implementar este código más rápido, usando C y múltiples núcleos, o valdría más la pena cambiar el algoritmo?)