I am trying to solve a system of n equations in R. n-1 of the equations are non-linear and the last one is linear. If it helps, this is a constrained optimization problem, with the n-1 equation being first order conditions, and the last being a budget constraint. The n-1 non-linear equations can be characterized by:non-linear equations
In case the image doesn't show, it can be defined, element-by-element like:
v_i*epsilon_i*cos(2/pi * e_i/delta_i)-lambda=0
where epsilon,v, e, and delta are vectors of n-1 dimension, and lambda is a scalar common to all equations).
The last equation is a simple linear equation of the form |e|=c. That is, the sum of all elements in e is some known c, called below parms[1,4] or "budget".
I am interested in solving for the vector e and the constant lambda, treating everything else as given.
I tried using rootSolve's multiroot. To do this, I define a single vector X, which is supposed to be the vector e, with lambda appended to it, so that multiroot solves for x, and is given the n equations as a list. All the parameters are saved in a matrix called "parms"
I first define the n-1 non-linear equations
convex_focs <- function(x = numeric(),parms = numeric()){
deltas = parms[,1]
v = parms[,2]
lambda = x[1]
e = x[2:length(x)]
epsilon_2 = exp(parms[,3]) - parms[,1]
return(epsilon_2*cos((pi/2)*(e/deltas))-lambda)
}
This equation uses the matrix notation, and works fine by itself. I then define the last, linear, equation:
convex_budget <- function(x = numeric(),parms = numeric()){
e = x[2:length(x)]
return(sum(e)-parms[1,4])
}
I then tried convex_system <- function(x,parms) c(convex_focs,convex_budget )
and call:
multiroot(f = convex_system, maxiter = 500000, start = c(0,rep(budget/length(parms[,1]),length(parms[,1]))), parms = parms[,])
This of course doesn't work, as rootSolve recognizes convex_system
as two equations, but X as n-dimensions.
If I drop the last equation, and treat lambda as given (so only solving the non-linear equations) I can get a solution. But of course this isn't good, because I don't know lambda.
So my first question is:
1. How do I generate a list of functions from my vectors that rootSolve will recognize as a system?
I tried using lapply, or using vignettes, to create a list of the convex_focs
equations, one for every elememt in the vector, but couldn't think of a way to make it work.
2. Why would it recognize my original convex_focs
function as a system of equations, but when I add convex_budget
it stopped working?
I then (in desperation...) tried manually defining a set of functions, looking at only 3 non-linear, rather than n-1. This is so that my list of functions will look like the manual and other solutions I found online:
convex_system <- function(x,parms) c(F1 =
function(x =x,parms = parms){
deltas = parms[1,1]
v = parms[1,2]
lambda = x[1]
e = x[2]
epsilon_2 = exp(parms[1,3]) - parms[1,1]
return(v*epsilon_2*cos((pi/2)*(e/deltas))-lambda)
}
,
F2 =
function(x = x,parms = parms){
deltas = parms[2,1]
v = parms[2,2]
lambda = x[1]
e = x[3]
epsilon_2 = exp(parms[2,3]) - parms[2,1]
return(v*epsilon_2*cos((pi/2)*(e/deltas))-lambda)
}
,
F3 =
function(x = x,parms = parms){
deltas = parms[3,1]
v = parms[3,2]
lambda = x[1]
e = x[4]
epsilon_2 = exp(parms[3,3]) - parms[3,1]
return(v*epsilon_2*cos((pi/2)*(e/deltas))-lambda)
}
,
F_budget = function(x = x,parms = parms){
e = x[2:length(x)]
return(sum(e)-parms[1,4])}
)
And calling multiroot(f = convex_system, maxiter = 500000, start = c(0,rep(budget/length(parms[1:3,1]),length(parms[1:3,1]))), parms = parms[1:3,])
When I run this I get the error
Error in stode(y, times, func, parms = parms, ...) : REAL() can only be applied to a 'numeric', not a 'list'
Which I really don't understand - how could the list of functions not be of class 'list'? So my second question is:
- How does one generate a list of functions when they are not simple one-line-functions (as those in the links above)
Finally, I'd greatly appreciate any guidance on how to better solve these types of problems in R.
Thank you for any assistance!