/
real_imag.jl
110 lines (87 loc) · 2.68 KB
/
real_imag.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#############################################################################
# real_imag.jl
# Handles real and imaginary part of the variables, constants
# and expressions.
#############################################################################
import Base.real, Base.imag
### Real
struct RealAtom <: AbstractExpr
head::Symbol
id_hash::UInt64
children::Tuple{AbstractExpr}
size::Tuple{Int, Int}
function RealAtom(x::AbstractExpr)
children = (x,)
return new(:real, hash(children), children, x.size)
end
end
function sign(x::RealAtom)
if sign(x.children[1]) == ComplexSign()
return NoSign()
else
return sign(x.children[1])
end
end
function monotonicity(x::RealAtom)
return (Nondecreasing(),)
end
function curvature(x::RealAtom)
return ConstVexity()
end
function evaluate(x::RealAtom)
return real.(evaluate(x.children[1]))
end
function conic_form!(x::RealAtom, unique_conic_forms::UniqueConicForms)
if !has_conic_form(unique_conic_forms, x)
new_objective = ConicObj()
objective = conic_form!(x.children[1], unique_conic_forms)
for var in keys(objective)
re = real.(objective[var][1])
im = real.(objective[var][2])
new_objective[var] = (re,im)
end
cache_conic_form!(unique_conic_forms, x, new_objective)
end
return get_conic_form(unique_conic_forms, x)
end
real(x::AbstractExpr) = RealAtom(x)
real(x::Value) = RealAtom(Constant(x))
### Imaginary
struct ImaginaryAtom <: AbstractExpr
head::Symbol
id_hash::UInt64
children::Tuple{AbstractExpr}
size::Tuple{Int, Int}
function ImaginaryAtom(x::AbstractExpr)
children = (x,)
return new(:imag, hash(children), children, x.size)
end
end
function sign(x::ImaginaryAtom)
sign(x.children[1]) == ComplexSign()
return NoSign()
end
function monotonicity(x::ImaginaryAtom)
return (Nondecreasing(),)
end
function curvature(x::ImaginaryAtom)
return ConstVexity()
end
function evaluate(x::ImaginaryAtom)
return imag.(evaluate(x.children[1]))
end
function conic_form!(x::ImaginaryAtom, unique_conic_forms::UniqueConicForms)
if !has_conic_form(unique_conic_forms, x)
new_objective = ConicObj()
objective = conic_form!(x.children[1], unique_conic_forms)
for var in keys(objective)
re = imag.(objective[var][1])
im = imag.(objective[var][2])
new_objective[var] = (re,im)
end
cache_conic_form!(unique_conic_forms, x, new_objective)
end
return get_conic_form(unique_conic_forms, x)
end
imag(x::AbstractExpr) = ImaginaryAtom(x)
imag(x::Value) = ImaginaryAtom(Constant(x))