/
maximum.jl
54 lines (46 loc) · 1.5 KB
/
maximum.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
#############################################################################
# maximum.jl
# Compute the maximum value of an array.
# All expressions and atoms are subtpyes of AbstractExpr.
# Please read expressions.jl first.
#############################################################################
import Base.maximum
export maximum
### Maximum Atom
type MaximumAtom <: AbstractExpr
head::Symbol
id_hash::UInt64
children::Tuple{AbstractExpr}
size::Tuple{Int, Int}
function MaximumAtom(x::AbstractExpr)
children = (x,)
return new(:maximum, hash(children), children, (1, 1))
end
end
function sign(x::MaximumAtom)
return sign(x.children[1])
end
# The monotonicity
function monotonicity(x::MaximumAtom)
return (Nondecreasing(),)
end
# If we have h(x) = f o g(x), the chain rule says h''(x) = g'(x)^T f''(g(x))g'(x) + f'(g(x))g''(x);
# this represents the first term
function curvature(x::MaximumAtom)
return ConvexVexity()
end
function evaluate(x::MaximumAtom)
return Base.maximum(evaluate(x.children[1]))
end
# x <= this if maximum(x) = this
# so, this - x will be in the :NonNeg cone
function conic_form!(x::MaximumAtom, unique_conic_forms::UniqueConicForms)
if !has_conic_form(unique_conic_forms, x)
this = Variable()
objective = conic_form!(this, unique_conic_forms)
conic_form!(this >= x.children[1], unique_conic_forms)
cache_conic_form!(unique_conic_forms, x, objective)
end
return get_conic_form(unique_conic_forms, x)
end
maximum(x::AbstractExpr) = MaximumAtom(x)