-
Notifications
You must be signed in to change notification settings - Fork 121
/
exp_constraints.jl
61 lines (57 loc) · 2.39 KB
/
exp_constraints.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
### (Primal) exponential cone constraint ExpConstraint(x,y,z) => y exp(x/y) <= z & y>=0
struct ExpConstraint <: Constraint
head::Symbol
id_hash::UInt64
children::Tuple{AbstractExpr, AbstractExpr, AbstractExpr} # (x, y, z)
size::Tuple{Int, Int}
dual::ValueOrNothing
function ExpConstraint(x::AbstractExpr, y::AbstractExpr, z::AbstractExpr)
@assert(x.size == y.size == z.size,
"Exponential constraint requires x, y, and z to be of same size")
# @assert(x.size == (1,1),
# "Exponential constraint requires x, y, and z to be scalar for now")
sz = x.size
id_hash = hash((x,y,z, :exp))
return new(:exp, id_hash, (x, y, z), sz, nothing)
end
end
ExpConstraint(x::AbstractExpr, y, z::AbstractExpr) = ExpConstraint(x, Constant(y), z)
ExpConstraint(x::AbstractExpr, y::AbstractExpr, z) = ExpConstraint(x, y, Constant(z))
ExpConstraint(x, y::AbstractExpr, z::AbstractExpr) = ExpConstraint(Constant(x), y, z)
function vexity(c::ExpConstraint)
# TODO: check these...
if vexity(c.x) == ConcaveVexity()
error("Exponential constraint requires x to be convex")
end
if vexity(c.y)!=ConstVexity()
error("Exponential constraint requires y to be constant")
end
if vexity(c.z) == ConvexVexity()
error("Exponential constraint requires z to be concave")
end
return ConvexVexity()
end
function conic_form!(c::ExpConstraint, unique_conic_forms::UniqueConicForms)
if !has_conic_form(unique_conic_forms, c)
conic_constrs = ConicConstr[]
if c.size == (1, 1)
objectives = Vector{ConicObj}(undef, 3)
@inbounds for iobj = 1:3
objectives[iobj] = conic_form!(c.children[iobj], unique_conic_forms)
end
push!(conic_constrs, ConicConstr(objectives, :ExpPrimal, [1, 1, 1]))
else
for i = 1:c.size[1]
for j = 1:c.size[2]
objectives = Vector{ConicObj}(undef, 3)
@inbounds for iobj = 1:3
objectives[iobj] = conic_form!(c.children[iobj][i,j], unique_conic_forms)
end
push!(conic_constrs, ConicConstr(objectives, :ExpPrimal, [1, 1, 1]))
end
end
end
cache_conic_form!(unique_conic_forms, c, conic_constrs)
end
return get_conic_form(unique_conic_forms, c)
end