Efficiently reusing/updating Julia's Convex constraints

question

#1

Not sure if this is the appropriate place to ask my question or if StackOverflow is better. Anyway, my question is related to reusing constraints in the Convex package.

I have something like the following simplified structure:

using Convex
x = Variable()
obj = square(x)
for sim_number = 1:100
    z = rand(7)
    p = minimize(obj)
    for j = 1:7
        p.constraints += [x >= z[j]]
    end
    solve!(p)
end

Is there a way to initialize the structure of the 7 constraints x >= random_val[j] outside of the sim_number loop so that I can reuse / update the RHS of the constraints only? For the real problem I have, setting up the constraints takes a long time, but solving is quick, so I’m seeking a way to reuse the constraint structure.


#2

Can’t you use minimize(objective, constraints) instead of iteratively adding constraints?

Compilation time in Convex.jl can definitely be an issue inside of loops. If you cannot find an alternative formulation that saves you from this bottleneck, try using JuMP.jl instead.


#3

Try setting the RHS as :

for j = 1:7
        p.constraints[j].rhs = z[j]
        solve!(p)
end

#4

Thank you! This works well (for posterity, I’ve included an example below at the bottom…)


Anyway, I have a quick follow up. The issue I’m working through deals with adding constraints that have Variable()s (or expressions) on both sides in a vectorized way. For example, I have

# variables
t = Variable(1)
v = Variable(7)
x = Variable(1)

# problem
p = minimize(x)
p.constraints += [t >= 0]         # initialize constraint 1

# initializing first simulation
z = rand(7)                       # randomness
c = Vector(7)                     # initialize holder for constraints
for j = 1:7
    cc = t + z[j]                 # constraint component
    c[j] = max(cc,0)
end
p.constraints += [c <= v]         # initialize constraint 2

# remaining simulations
for sim = 2:nsims
    z = rand(7)                   # randomness
    c = Vector(7)                 # initialize holder for constraints
    for j = 1:7
        cc = t + z[j]
        c[j] = max(cc,0)
    end
    p.constraints[2] = [c <= v]   # update constraint 2
end

and I am trying efficiently impose the 7 randomness constraints in a vectorized way (later I will have many more than 7). I also have

typeof(c) = Array{Any,1}
typeof(c[1]) = Convex.MaxAtom
typeof(v) = Convex.Variable
typeof(v[1]) = Convex.IndexAtom

but am unable to match operators (ERROR: LoadError: MethodError: no method matching isless(::Complex{Int64}, ::Int64). Is there a better way of enforcing these constraints in a vectorized way?

Example (based on @KrishnaKanhaiya’s post)


## example ##
using Convex

# setup
x = Variable()
obj = square(x)
sim_number = 1
z = rand(7)

# first simulation
p = minimize(obj)
for j = 1:7
    p.constraints += [x >= z[j]]
end
solve!(p)
print("==== $sim_number solved ===\n")

# remaining simulations
for sim_number = 2:100
    z = rand(7)
    for j = 1:7
        p.constraints[j].rhs = z[j]
    end
    solve!(p)
    print("==== $sim_number solved ===\n")
end