@@ -30,158 +30,91 @@ REFERENCE
30
30
theorem, matrix geometric means and semidefinite optimization" by Hamza
31
31
Fawzi and James Saunderson (arXiv:1512.03401)
32
32
"""
33
- mutable struct GeometricMeanHypoCone
34
- A:: AbstractExpr
35
- B:: AbstractExpr
33
+ struct GeometricMeanHypoConeSquare <: MOI.AbstractVectorSet
36
34
t:: Rational
37
- size :: Tuple{ Int,Int}
35
+ side_dimension :: Int
38
36
fullhyp:: Bool
39
37
40
- function GeometricMeanHypoCone (
41
- A:: AbstractExpr ,
42
- B:: AbstractExpr ,
38
+ function GeometricMeanHypoConeSquare (
43
39
t:: Rational ,
40
+ side_dimension:: Int ,
44
41
fullhyp:: Bool = true ,
45
42
)
46
- if size (A) != size (B)
47
- throw (DimensionMismatch (" A and B must be the same size" ))
48
- end
49
- n = size (A)[1 ]
50
- if size (A) != (n, n)
51
- throw (DimensionMismatch (" A and B must be square" ))
52
- end
53
43
if t < 0 || t > 1
54
44
throw (DomainError (t, " t must be in the range [0, 1]" ))
55
45
end
56
- return new (A, B, t, (n, n), fullhyp)
57
- end
58
-
59
- function GeometricMeanHypoCone (
60
- A:: Value ,
61
- B:: AbstractExpr ,
62
- t:: Rational ,
63
- fullhyp:: Bool = true ,
64
- )
65
- return GeometricMeanHypoCone (constant (A), B, t, fullhyp)
66
- end
67
-
68
- function GeometricMeanHypoCone (
69
- A:: AbstractExpr ,
70
- B:: Value ,
71
- t:: Rational ,
72
- fullhyp:: Bool = true ,
73
- )
74
- return GeometricMeanHypoCone (A, constant (B), t, fullhyp)
46
+ return new (t, side_dimension, fullhyp)
75
47
end
48
+ end
76
49
77
- function GeometricMeanHypoCone (
78
- A:: Value ,
79
- B:: Value ,
80
- t:: Rational ,
81
- fullhyp:: Bool = true ,
82
- )
83
- return GeometricMeanHypoCone (constant (A), constant (B), t, fullhyp)
84
- end
50
+ MOI. dimension (set:: GeometricMeanHypoConeSquare ) = 3 * set. side_dimension^ 2
85
51
86
- function GeometricMeanHypoCone (
87
- A:: Union{AbstractExpr,Value} ,
88
- B:: Union{AbstractExpr,Value} ,
89
- t:: Integer ,
90
- fullhyp:: Bool = true ,
91
- )
92
- return GeometricMeanHypoCone (A, B, t // 1 , fullhyp)
93
- end
52
+ function head (io:: IO , :: GeometricMeanHypoConeSquare )
53
+ return print (io, " GeometricMeanHypoConeSquare" )
94
54
end
95
55
96
- mutable struct GeometricMeanHypoConeConstraint <: Constraint
97
- T:: AbstractExpr
98
- cone:: GeometricMeanHypoCone
99
-
100
- function GeometricMeanHypoConeConstraint (
101
- T:: AbstractExpr ,
102
- cone:: GeometricMeanHypoCone ,
103
- )
104
- if size (T) != cone. size
105
- throw (DimensionMismatch (" T must be size $(cone. size) " ))
56
+ function GenericConstraint (func:: Tuple , set:: GeometricMeanHypoConeSquare )
57
+ for f in func
58
+ n = LinearAlgebra. checksquare (f)
59
+ if n != set. side_dimension
60
+ throw (
61
+ DimensionMismatch (
62
+ " Matrix of side dimension `$n ` does not match set of side dimension `$(set. side_dimension) `" ,
63
+ ),
64
+ )
106
65
end
107
- return new (T, cone)
108
- end
109
-
110
- function GeometricMeanHypoConeConstraint (
111
- T:: Value ,
112
- cone:: GeometricMeanHypoCone ,
113
- )
114
- return GeometricMeanHypoConeConstraint (constant (T), cone)
115
66
end
67
+ return GenericConstraint (vcat (vec .(func)... ), set)
116
68
end
117
69
118
- function iscomplex (c:: GeometricMeanHypoConeConstraint )
119
- return iscomplex (c. T) || iscomplex (c. cone)
120
- end
121
-
122
- iscomplex (c:: GeometricMeanHypoCone ) = iscomplex (c. A) || iscomplex (c. B)
123
-
124
- function head (io:: IO , :: GeometricMeanHypoConeConstraint )
125
- return print (io, " ∈(GeometricMeanHypoCone)" )
126
- end
127
-
128
- function Base. in (T, cone:: GeometricMeanHypoCone )
129
- return GeometricMeanHypoConeConstraint (T, cone)
130
- end
131
-
132
- function AbstractTrees. children (constraint:: GeometricMeanHypoConeConstraint )
133
- return (
134
- constraint. T,
135
- constraint. cone. A,
136
- constraint. cone. B,
137
- constraint. cone. t,
138
- )
70
+ function _get_matrices (c:: GenericConstraint{GeometricMeanHypoConeSquare} )
71
+ n = c. set. side_dimension
72
+ d = n^ 2
73
+ T = reshape (c. child[1 : d], n, n)
74
+ A = reshape (c. child[d.+ (1 : d)], n, n)
75
+ B = reshape (c. child[2 d.+ (1 : d)], n, n)
76
+ return T, A, B
139
77
end
140
78
141
79
# For t ∈ [0,1] the t-weighted matrix geometric mean is matrix concave (arxiv:1512.03401).
142
80
# So if A and B are convex sets, then T ⪯ A #_t B will be a convex set.
143
- function vexity (constraint:: GeometricMeanHypoConeConstraint )
144
- A = vexity (constraint. cone. A)
145
- B = vexity (constraint. cone. B)
146
- T = vexity (constraint. T)
147
-
148
- # NOTE: can't say A == NotDcp() because the NotDcp constructor prints a
149
- # warning message.
150
- if typeof (A) == ConvexVexity || typeof (A) == NotDcp
151
- return NotDcp ()
152
- elseif typeof (B) == ConvexVexity || typeof (B) == NotDcp
153
- return NotDcp ()
154
- end
155
- vex = - ConcaveVexity () + T
156
- if vex == ConcaveVexity ()
81
+ function vexity (constraint:: GenericConstraint{GeometricMeanHypoConeSquare} )
82
+ T, A, B = _get_matrices (constraint)
83
+ if vexity (A) in (ConvexVexity (), NotDcp ()) ||
84
+ vexity (B) in (ConvexVexity (), NotDcp ())
157
85
return NotDcp ()
158
86
end
159
- return vex
87
+ return - ConcaveVexity () + vexity (T)
160
88
end
161
89
162
90
function _add_constraint! (
163
91
context:: Context ,
164
- constraint:: GeometricMeanHypoConeConstraint ,
92
+ constraint:: GenericConstraint{GeometricMeanHypoConeSquare} ,
165
93
)
166
- A = constraint. cone. A
167
- B = constraint. cone. B
168
- t = constraint. cone. t
169
- T = constraint. T
170
- fullhyp = constraint. cone. fullhyp
94
+ T, A, B = _get_matrices (constraint)
95
+ t = constraint. set. t
96
+ fullhyp = constraint. set. fullhyp
171
97
172
98
is_complex =
173
99
sign (A) == ComplexSign () ||
174
100
sign (B) == ComplexSign () ||
175
101
sign (T) == ComplexSign ()
102
+ n = size (A, 1 )
176
103
if is_complex
177
- make_temporary = () -> HermitianSemidefinite (size (A)[ 1 ] )
104
+ make_temporary = () -> HermitianSemidefinite (n )
178
105
else
179
- make_temporary = () -> Semidefinite (size (A)[ 1 ] )
106
+ make_temporary = () -> Semidefinite (n )
180
107
end
181
108
182
109
if fullhyp && t != 0 && t != 1
183
110
W = make_temporary ()
184
- add_constraint! (context, W in GeometricMeanHypoCone (A, B, t, false ))
111
+ add_constraint! (
112
+ context,
113
+ GenericConstraint (
114
+ (W, A, B),
115
+ GeometricMeanHypoConeSquare (t, n, false ),
116
+ ),
117
+ )
185
118
add_constraint! (context, W ⪰ T)
186
119
else
187
120
p = t. num
@@ -206,13 +139,19 @@ function _add_constraint!(
206
139
if t < 1 / 2
207
140
add_constraint! (
208
141
context,
209
- Z in GeometricMeanHypoCone (A, B, 2 * t, false ),
142
+ GenericConstraint (
143
+ (Z, A, B),
144
+ GeometricMeanHypoConeSquare (2 * t, n, false ),
145
+ ),
210
146
)
211
147
add_constraint! (context, [A T; T' Z] ⪰ 0 )
212
148
else
213
149
add_constraint! (
214
150
context,
215
- Z in GeometricMeanHypoCone (A, B, 2 * t - 1 , false ),
151
+ GenericConstraint (
152
+ (Z, A, B),
153
+ GeometricMeanHypoConeSquare (2 * t - 1 , n, false ),
154
+ ),
216
155
)
217
156
add_constraint! (context, [B T; T' Z] ⪰ 0 )
218
157
end
@@ -221,7 +160,10 @@ function _add_constraint!(
221
160
Z = make_temporary ()
222
161
add_constraint! (
223
162
context,
224
- Z in GeometricMeanHypoCone (A, T, (2 * p - q) // p, false ),
163
+ GenericConstraint (
164
+ (Z, A, T),
165
+ GeometricMeanHypoConeSquare ((2 * p - q) // p, n, false ),
166
+ ),
225
167
)
226
168
add_constraint! (context, [Z T; T B] ⪰ 0 )
227
169
elseif t < 1 / 2
@@ -231,18 +173,28 @@ function _add_constraint!(
231
173
l = floor (Int, log2 (q))
232
174
add_constraint! (
233
175
context,
234
- X in GeometricMeanHypoCone (A, B, p // (2 ^ l), false ),
176
+ GenericConstraint (
177
+ (X, A, B),
178
+ GeometricMeanHypoConeSquare (p // (2 ^ l), n, false ),
179
+ ),
235
180
)
236
181
add_constraint! (
237
182
context,
238
- T in GeometricMeanHypoCone (A, X, (2 ^ l) // q, false ),
183
+ GenericConstraint (
184
+ (T, A, X),
185
+ GeometricMeanHypoConeSquare ((2 ^ l) // q, n, false ),
186
+ ),
239
187
)
240
188
else
241
189
# println("geom_mean_hypocone p=$p q=$q else")
242
190
add_constraint! (
243
191
context,
244
- T in GeometricMeanHypoCone (B, A, 1 - t, false ),
192
+ GenericConstraint (
193
+ (T, B, A),
194
+ GeometricMeanHypoConeSquare (1 - t, n, false ),
195
+ ),
245
196
)
246
197
end
247
198
end
199
+ return
248
200
end
0 commit comments