sparse matrix constraints constrOptim - r

I everybody,
I have a function to optimize, subject to linear constraints.
I am actually using maxLik R-package, but this is a wrapper for various method, thus what I am actually running in constrOptim.
The problem is the following: I have a matrix of constraints which is n^2 x n, but n is ~ 10^3, so the matrix is huge and the routine stops for memory problems.
Cholmod error 'problem too large' at file ../Core/cholmod_dense.c, line 105
It seemed quite natural to me to shift to sparse matrices (indeed my matrix is very sparse) with the Matrix package, but I always get the following error
Error: Matrices must have same dimensions in ineqA * gi.old
even for small n.
Does it mean that sparseMatrix is not supported in constrOptim?
Do you know any way out?
reproducible example
you can find the dataset I am using to optimize here:
http://konect.uni-koblenz.de/downloads/extraction/opsahl.tar.bz2
and here you have the code
#read edgelist
edgelist <- read.table('out.opsahl-usairport',skip=2)
colnames(edgelist) = c('V1','V2','weight')
require(igraph)
g = graph_from_data_frame(edgelist)
s_in = strength(g,v=V(g), mode= 'in')
s_out = strength(g,v=V(g),mode='out')
n = length(s_in)
# optimization function
objective_fun = function(x){
theta_out = x[1:(length(x)/2)]; theta_in = x[(length(x)/2+1):length(x)];
llikelihood(s_out,s_in,theta_out,theta_in)
}
llikelihood = function(s_out,s_in,theta_out, theta_in){
theta_sum_mat = outer(theta_out,rep(1,length(theta_out))) + outer(rep(1,length(theta_in)),theta_in)
theta_sum_mat = log(1-exp(-theta_sum_mat))
diag(theta_sum_mat) = 0 # avoid self loops
f = -sum(s_out*theta_out+s_in*theta_in) + sum(theta_sum_mat)
f
}
#choose appropriate starting point
starting_point = function(s_out,s_in){
s_tot = sum(s_in) # =sum(s_out)
s_mean = mean(mean(s_in),mean(s_out))
z = log((s_tot + s_mean^2)/(s_mean^2))
list(theta_out = rep(1,length(s_out)), theta_in=rep(z-1,length(s_in))) # starting parameters
}
#gradient
grad = function(x){
theta_out = x[1:(length(x)/2)]; theta_in = x[(length(x)/2+1):length(x)];
ret = grad_fun(s_out,s_in,theta_out,theta_in)
ret
}
grad_fun = function(s_out,s_in, theta_out, theta_in){
theta_sum_mat = outer(theta_out,rep(1,length(theta_out))) + outer(rep(1,length(theta_in)),theta_in)
theta_sum_mat = exp(-theta_sum_mat)/(1-exp(-theta_sum_mat))
diag(theta_sum_mat) = 0 # avoid self loops
c(-s_out + rowSums(theta_sum_mat), -s_in + colSums(theta_sum_mat))
}
#constraints
constraints = function(n){
a1 = Diagonal(n); a2 = sparseMatrix(c(1:n),rep(1,n), x=1, dims=c(n,n)) # Diagonal is a sparse diagonal matrix
a12 = cBind(a1,a2)
a12[1,] = 0 # avoid self loops
dd = function(j){
sparseMatrix(c(1:n),rep(j,n), x=rep(1,n), dims=c(n,n))
}
b1 = sparseMatrix(i=1, j=1, x=1, dims=c(n^2,1)) # 1,0,0,... n^2 vector
for(j in c(2:n)) {
a = cBind(Diagonal(n),dd(j))
a[j,]=0 # avoid self loops
a12 = rBind(a12, a)
b1[(j-1)*n+j] = 1 # add 1 to ''self loops'' rows, in order to have the inequality satisfied
}
return(list(A=a12, B=b1))
}
# starting point
theta_0 = starting_point(s_out,s_in)
x_0 = c(theta_0$theta_out, theta_0$theta_in)
#constraints
constr = list(ineqA=constraints(n)$A, ineqB=constraints(n)$B)
# optimization
co = maxControl(printLevel = 1, iterlim=500, tol=1e-4) #tol=1e-8 (def) iterlim=150 (def)
res = maxLik(objective_fun, grad=grad, start=x_0, constraints=constr, control=co)

Related

How to predict Brown's Exponential Double Smoothing in a rolling window approach of 60 observations from a dataset

I have a task to predict Brown's Exponential Double Smoothing in a rolling window frame of 60 observations from a dataset of 228 observatoins and 17 variables. I will only predict one variable of those 17.
Also need to plot the original data and the predicted data.
How can this be done?
First, I create this function to calculate the prediction:
estwo_brown = function(x ,m, lambda) {
# Number of observations
TT = length(x)
# Looking at the lecture - we need M1,t
so = c();
# We need M2,t
st = c();
# We need the level component, Lt
at = c();
# We need the trend component, Tt
bt = c();
# We need the predicted values, Y_t+h
fs = c();
# We set up initial values
so\[1\] = x\[1\]
st\[1\] = x\[1\]
# Now as before, we loop from the second to the last observation
# and use equations from the lecture (2:TT)
for (i in 2:TT) {
so\[i\] = lambda \* x\[i-1\] + (1-lambda) \* so\[i-1\]
st\[i\] = lambda \* so\[i\] + (1-lambda) \* st\[i-1\]
at\[i\] = 2\*so\[i\] - st\[i\]
bt\[i\] = lambda / (1 - lambda) \* (so\[i\] - st\[i\])
fs\[i+m\] = at\[i\] + bt\[i\] \* m
}
# Combining results
res = matrix(NA, nrow = TT, ncol = 6)
colnames(res) = c('Y', 'Mt1', 'Mt2', 'at', 'bt', 'Ft')
res\[,'Y'\] = x
res\[,'Mt1'\] = so
res\[,'Mt2'\] = st
res\[,'at'\] = at
res\[,'bt'\] = bt
res\[,'Ft'\] = fs\[1:TT\]
results = list()
results\[\['results'\]\] = as.data.frame(res)
results\[\['outpred'\]\] = fs\[length(fs)\]
return(results)
}
and then calculating the model using this:
b_double_exp = estwo_brown(x = dataset$column7, m = 1, lambda = 0.5)
But, this is will predict the whole dataset. How can I predict this in a rolling window of 60 observations? The rolling window should slide one observation ahead.

How do get this function to run on multiple cores/processors in R?

How would I go about running this function across multiple cores on my machine to speed it up. The function implements a backfitting algorithm to fit a nonparametric bivariate linear model using functional data.
The ffunopare.knn.gcv() function implements the functional Nadaraya-Watson estimator to estimate the regression function.
library(bbefkr)
backfit = function(X1, X2, Y, eps){
# fix r(x1) and r(x2)
rx1_storage = list()
rx2_storage = list()
rx1_init = matrix(1, nrow=1000, ncol=100)
rx2_init = rx1_init
rx1_storage[[1]] = rx1_init
rx2_storage[[1]] = rx2_init
i=2
repeat{
a = Y_RESPONSE3 - rx1_storage[[i-1]]
# a~r(x2)
a_func_of_x2 = ffunopare.knn.gcv(RESPONSES=a, CURVES=X2,
PRED=X2,q=4,semimetric="pca") # Y - r(X1)
rx2 = a_func_of_x2$Estimated.values
# we get r(x2)
b = Y_RESPONSE3 - rx2
# b~r(x1)
b_func_of_x1 = ffunopare.knn.gcv(RESPONSES=b, CURVES=X1,
PRED=X1, q=4,semimetric="pca")
# we get r(x1)
rx1 = b_func_of_x1$Estimated.values
rx1_storage[[i]] = rx1
rx2_storage[[i]] = rx2
dmax_rx1 = max(abs(rx1_storage[[i]] - rx1_storage[[i-1]]))
dmax_rx2 = max(abs(rx2_storage[[i]] - rx2_storage[[i-1]]))
max_dist = max(c(dmax_rx1, dmax_rx2)) # want the maximum of this vector to be <= epsilon
print(max_dist)
if(max_dist <= eps)
break # if it converges, break the loop
#print(max_dist)
i = i+1 # update i
}
return(list(rx1=rx1_storage[[i]], rx2=rx2_storage[[i]],
iterations=i-1))
}

R Error: object length is not a multiple of shorter object length

I am working with the R programming language. I am trying to learn about different optimization algorithms such as the "Genetic Algorithm" (e.g. https://cran.r-project.org/web/packages/GA/vignettes/GA.html, https://cran.r-project.org/web/packages/GA/index.html) vs. the "Evolutionary Grammar Algorithm" (e.g. https://cran.r-project.org/web/packages/gramEvol/gramEvol.pdf , https://www.jstatsoft.org/article/view/v071i01).
For instance, I can use the Genetic Algorithm to optimize the following function ("Rastrigin") :
#PART 1: Optimize Rastrigin Function with the Genetic Algorithm
library(GA)
#define function
Rastrigin <- function(x1, x2)
{
20 + x1^2 + x2^2 - 10*(cos(2*pi*x1) + cos(2*pi*x2))
}
#plot
x1 <- x2 <- seq(-5.12, 5.12, by = 0.1)
f <- outer(x1, x2, Rastrigin)
persp3D(x1, x2, f, theta = 50, phi = 20, col.palette = bl2gr.colors)
#run optimization algorithm and plot results
GA <- ga(type = "real-valued",
fitness = function(x) -Rastrigin(x[1], x[2]),
lower = c(-5.12, -5.12), upper = c(5.12, 5.12),
popSize = 50, maxiter = 1000, run = 100)
plot(GA)
summary(GA)
Fitness function value = -2.502466e-07
Solution =
x1 x2
[1,] 3.341508e-05 1.203355e-05
Problem: However, I am running into errors when I try to use the "Evolutionary Grammar Algorithm" to optimize the same function:
#PART 2: Optimize Rastrigin Function with the Evolutionary Grammar Algorithm:
library(gramEvol)
ruleDef <- list(expr = gsrule("<der.expr><op><der.expr>"),
der.expr = grule(func(var), var),
func = grule(log, exp, sin, cos),
op = gsrule("+", "-", "*"),
var = grule(x1, x2, n),
n = grule(1, 2, 3, 4))
# Creating the grammar object
grammarDef <- CreateGrammar(ruleDef)
#redine the same function in a format acceptable to the "gramEvol" library
Rastrigin <- function(expr) {
# expr: a string containing a symbolic expression
# returns: Symbolic regression Error
x1 <- c(5.12, 5.12)
x2 <- c(5.12, 5.12)
result <- eval(as.expression(expr))
err <- 20 + x1^2 + x2^2 - 10*(cos(2*pi*x1) + cos(2*pi*x2))
return(err)
}
#run optimization (problem)
ge <- GrammaticalEvolution(grammarDef, evalFunc, terminationCost = 0.001)
# print results (problem)
print(ge, sequence = TRUE)
The last two lines of code return the following errors:
Error in EvolutionStrategy.int(genomeLen = chromosomeLen, codonMin = 0, :
Invalid cost function return value (NA or NaN).
In addition: Warning messages:
1: In result - X :
longer object length is not a multiple of shorter object length
2: In result - X :
longer object length is not a multiple of shorter object length
#etc
Question: Can someone please show me how to fix this problem? What is result - X ? What exactly is longer object length is not a multiple of shorter object length referring to?
Thanks!
Source: https://rdrr.io/cran/gramEvol/man/GrammaticalEvolution.html

Optimization problem | Solve an equation with 4 parameters having two conditions

I have this equation :
f(x) = i * ln(j * x + k)
With these two conditions : f(0) = 6 & f(1) = 12
After several hours of research, I can not find how to optimize the parameters i, j & k which respect the conditions with RStudio.
I know how to do it with Excel, but I want to succeed in doing it with R.
Anyone have any idea to fix this problem with R?
i can help you with the monte carlo method
so :
after math calcul you find :
i=log(k)/6
k=exp(72*log(j+k))
so you apply the monte carlo method :
a=data.frame(k=round(runif(1000000,-2,2),4),j=round(runif(1000000,-2,2),4))
a$k2=round(exp(72*log(a$j+a$k)),4)
a=a[-which(is.na(a$k2)==TRUE),] # you delete the NA coz of negatif number in log
library(tidyverse) # to use "near" function
a[which(near(a$k,a$k2,0.001)==TRUE),]
Given the constraints you can solve for i and j in terms of k:
f(0) = 6
=> i*ln( j*0 + k) = 6
=> i*ln(k) = 6
=> i = 6/ln(k)
f(1) = 12
=> i*ln( j*1 + k) = 12
=> (6/ln(k))*ln(j+k) = 12
=> ln(j+k) = 2*ln(k)
=> j+k = k*k
=> j = k*k-k
So
f(x) = (6/ln(k))*ln( (k*(k-1)*x + k)
As a check
f(0) = (6/ln(k))*ln( (k*(k-1)*0 + k)
= (6/ln(k))*ln(k) = 6
f(1) = (6/ln(k))*ln( (k*(k-1)*1 + k)
= (6/ln(k))*ln( k*k)
= (6/ln(k))*2*ln(k)
= 12
However I do not understand what you want to optimize.
optim
Define f as the function in the question except we explicitly list all arguments and ss as the residual sum of squares. Then minimize ss using an arbitrary value for i (since we have two equations and 3 unknowns). Below we show the solution for j and k (in the par component of the output) using i = 10 as an input.
f <- function(x, i, j, k) i * log(j * x + k)
ss <- function(p, i) (f(x = 0, i = i, j = p[1], k = p[2]) - 6)^2 +
(f(x = 1, i = i, j= p[1], k = p[2]) - 12)^2
optim(1:2, ss, i = 10)
giving:
$par
[1] 1.497972 1.822113
$value
[1] 9.894421e-09
$counts
function gradient
59 NA
$convergence
[1] 0
$message
NULL
nlsLM
Alternately we can use nonlinear least squares. This is slightly easier to specify since we don't need to define ss but it does require a package. We use nlsLM instead of nls in the core of R since nls does not handle zero residual problems well.
library(minpack.lm)
nlsLM(y ~ f(x, i, j, k), data = list(y = c(6, 12), x = 0:1, i = 10),
start = c(j = 1, k = 2))
giving:
Nonlinear regression model
model: y ~ f(x, i, j, k)
data: list(y = c(6, 12), x = 0:1, i = 10)
j k
1.50 1.82
residual sum-of-squares: 0
Number of iterations to convergence: 4
Achieved convergence tolerance: 1.49e-08

Error in as.vector(data) : no method for coercing this S4 class to a vector

I am trying to run a O-garch model, the code seem to be right and on mac it works, but when it is run on windows it doesn not work giving me the following error message:
Error in as.vector(data) :
no method for coercing this S4 class to a vector
seems that there is a problem with the loop.
Thanks in advance.
graphics.off() # clean up graphic window
#install.packages("fGarch")
library(rmgarch)
library(tseries)
library(stats)
library(fGarch)
library(rugarch)
library(quantmod)
getSymbols(Symbols = c('PG','CVX','CSCO'),from="2005-01-01", to="2020-04-17",
env=parent.frame(),
reload.Symbols = FALSE,
verbose = FALSE,
warnings = TRUE,
src="yahoo",
symbol.lookup = TRUE,
auto.assign = getOption('getSymbols.auto.assign', TRUE))
Pt=cbind(PG$PG.Adjusted,CVX$CVX.Adjusted,CSCO$CSCO.Adjusted)
rt = 100 * diff(log(Pt))
rt=na.omit(rt)
rm(CSCO,CVX,PG)
rt_ts=ts(rt)
n=nrow(rt_ts)
N=ncol(rt_ts)
#O-GARCH:
Sigma = cov(rt_ts); # Covariance matrix
P = cor(rt_ts) # correlation matrix
# spectral decomposition
SpectralDec = eigen(Sigma, symmetric=TRUE)
V = SpectralDec$vectors # eigenvector matrix
V
lambda = SpectralDec$values # eigenvalues
lambda
Lambda = diag(lambda) # Eigenvalues on the diagonal
print(Sigma - V %*% Lambda %*% t(V), digits = 3) # Sigma - V Lambda V' = 0
print(V %*% t(V), digits = 3) # V'V = I
print(t(V) %*% V, digits = 3) # VV' = I
f = ts(as.matrix(rt_ts) %*% V);
cov(f) # diagonal matrix with lambda on the diagonal
ht.f = matrix(0, n, N)
for (i in 1:N)
{
fit = garchFit(~ garch(1,1), data =f[, i], trace = FALSE);
summary(fit);
ht = volatility(fit, type = "h");
ht.f[, i] = ht;
}
ht.f=ts(ht.f) ```
I had the exact same problem with the volatility line. Apparently the fGarch library doesn't get along with the quantmod library. Maybe try reseting RStidio and install all but quantmod library
That was the only way I got it to work

Resources