I want to build an NLexpression
which is the sum of elements of an array containing both JuMP
variables and Float64
s, something like:
model = Model()
@variable(model, x[1:2])
xx = [x[1]; 3.0; 4.0; 5.0; x[2]]
@NLexpression(model, test, sin(xx[1]))
for i = 2:5
aux = @NLexpression(model, sin(xx[i]))
test += aux
end
Is it possible to “build up” a single nonlinear expression in steps like this? I’m hoping for a cleaner way to do it than to create three separate NLexpressions
: two to handle the variable and constant parts separately and one to combine them. I might be missing something obvious…
I can do this for expression
s as:
model = Model()
@variable(model, x[1:2])
xx = [x[1]; 3.0; 4.0; 5.0; x[2]]
@expression(model, test, (xx[1]))
for i = 2:5
aux = @expression(model, (xx[i]))
test += aux
end
This works: define an N
-dim array xx = Array{Union{Float64, JuMP.Variable},1}(N)
first and then fill.
Example:
using JuMP, Ipopt
N = 10
x0 = rand(N);
A = rand(N,N); A = A'*A
b = rand(N)
x_true = A\b
vlist = [1,3,5,7,9]; Nv = length(vlist)
plist = [2,4,6,8,10]; Np = length(plist)
x0[plist] = x_true[plist]
## -----------------------------------------------------------------------------
xp = x0[plist]
test = Model(solver=IpoptSolver())
@variable(test, xvar[vlist])
x_combined = Array{Union{Float64, JuMP.Variable}, 1}(10)
for i in vlist
x_combined[i] = xvar[i]
end
x_combined[plist] = xp
@NLexpression(test, xAx, sum(
sum(
0.5*x_combined[i]*x_combined[j]*A[i,j]
for i=1:N)
for j=1:N)
)
@NLobjective(test, Min, xAx - sum(b[i] * x_combined[i] for i=1:N))
## -----------------------------------------------------------------------------
solve(test)
xvar_star = getvalue(test[:xvar])
x_star = zeros(N)
x_star[plist] = xp
for i in vlist
x_star[i] = xvar_star[i]
end
A*x_star - b