-
Notifications
You must be signed in to change notification settings - Fork 121
/
scaledgeomean.jl
57 lines (48 loc) · 1.44 KB
/
scaledgeomean.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
import Base.sqrt
function power_of_2_gt(n::Int)
Int(2^ceil(log(2,n)))
end
struct ScaledGeoMeanAtom <: AbstractExpr
head::Symbol
id_hash::UInt64
children::Tuple{AbstractExpr, AbstractExpr}
size::Tuple{Int, Int}
function ScaledGeoMeanAtom(x::AbstractExpr)
children = (x)
return new(:scaledgeomean, hash(children), children, x.size)
end
end
function sign(q::ScaledGeoMeanAtom)
return Positive()
end
function monotonicity(q::ScaledGeoMeanAtom)
return (Nondecreasing(),)
end
function curvature(q::ScaledGeoMeanAtom)
return ConcaveVexity()
end
function evaluate(q::ScaledGeoMeanAtom)
nbar = power_of_2_gt(length(q.children))
return prod(evaluate(q.children[1]))^(1/nbar)
end
function conic_form!(q::ScaledGeoMeanAtom, unique_conic_forms::UniqueConicForms)
if !has_conic_form(unique_conic_forms, q)
t = Variable()
qol_objective = conic_form!(t, unique_conic_forms)
x, y = q.children
conic_form!(SOCElemConstraint(y + x, y - x, 2 * t), unique_conic_forms)
conic_form!(x >= 0, unique_conic_forms)
conic_form!(y >= 0, unique_conic_forms)
cache_conic_form!(unique_conic_forms, q, qol_objective)
end
return get_conic_form(unique_conic_forms, q)
end
function scaledgeomean(x::AbstractExpr)
if length(x) > 2
return ScaledGeoMeanAtom(x)
elseif length(x) == 2
return geomean(x[1],x[2])
else
return x
end
end