Skip to content

Commit 9656d62

Browse files
authored
ported cvxquad: matrix log, geometric mean, quantum entropy (#418)
* ported cvxquad: matrix log, geometric mean, quantum entropy * comments about vexity * throw DimensionMismatch for wrong size matrices * throw DomainError instead of `error` * added @test_throw * refactored range assert * added function overloads taking Integer, because that doesn't auto-convert to Rational * more tests * fix relative_entropy_epicone comment * document relative_entropy_epicone * made RelativeEntropyEpiCone a constraint rather than a function * minor changes and more coverage * fix diagm calls for old julia * fix for entropy with real matrices * RelativeEntropyEpiCone test * trace_logm tests * added cvxquad license * fix
1 parent 267bac0 commit 9656d62

File tree

13 files changed

+1972
-8
lines changed

13 files changed

+1972
-8
lines changed

LICENSE.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,31 @@ MIT "Expat" License:
9797
> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
9898
> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
9999
> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
100+
101+
The files geom_mean_epicone.jl, geom_mean_hypocone.jl, lieb_ando.jl,
102+
quantum_entropy.jl, quantum_relative_entropy.jl,
103+
relative_entropy_epicone.jl, trace_logm.jl, and trace_mpower.jl in
104+
src/atoms/sdp_cone are adapted from cvxquad
105+
(https://github.com/hfawzi/cvxquad) which is licensed under the MIT
106+
"Expat" license:
107+
108+
> Copyright (c) 2021 Hamza Fawzi
109+
>
110+
> Permission is hereby granted, free of charge, to any person obtaining
111+
> a copy of this software and associated documentation files (the
112+
> "Software"), to deal in the Software without restriction, including
113+
> without limitation the rights to use, copy, modify, merge, publish,
114+
> distribute, sublicense, and/or sell copies of the Software, and to
115+
> permit persons to whom the Software is furnished to do so, subject to
116+
> the following conditions:
117+
>
118+
> The above copyright notice and this permission notice shall be
119+
> included in all copies or substantial portions of the Software.
120+
>
121+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
122+
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
123+
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
124+
> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
125+
> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
126+
> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
127+
> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

docs/src/operations.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,22 @@ Semidefinite Program Representable Functions
108108
An optimization problem using these functions can be solved by any SDP
109109
solver (including SCS and Mosek).
110110

111-
| operation | description | vexity | slope | notes |
112-
|------------------|-------------------------------|--------|---------------|-------|
113-
| `nuclearnorm(x)` | sum of singular values of $x$ | convex | not monotonic | none |
114-
| `opnorm(x, 2)` (`operatornorm(x)`) | max of singular values of $x$ | convex | not monotonic | none | |
115-
| `eigmax(x)` | max eigenvalue of $x$ | convex | not monotonic | none |
116-
| `eigmin(x)` | min eigenvalue of $x$ | concave | not monotonic | none |
117-
| `matrixfrac(x, P)` | $x^TP^{-1}x$ | convex | not monotonic | IC: P is positive semidefinite |
118-
| `sumlargesteigs(x, k)` | sum of top $k$ eigenvalues of $x$ | convex | not monotonic | IC: P symmetric |
111+
| operation | description | vexity | slope | notes |
112+
|------------------------------------------------|----------------------------------------------------------------|------------------------------------------------------------------------|---------------|------------------------------------------------------------------|
113+
| `nuclearnorm(x)` | sum of singular values of $x$ | convex | not monotonic | none |
114+
| `opnorm(x, 2)` (`operatornorm(x)`) | max of singular values of $x$ | convex | not monotonic | none |
115+
| `eigmax(x)` | max eigenvalue of $x$ | convex | not monotonic | none |
116+
| `eigmin(x)` | min eigenvalue of $x$ | concave | not monotonic | none |
117+
| `matrixfrac(x, P)` | $x^TP^{-1}x$ | convex | not monotonic | IC: P is positive semidefinite |
118+
| `sumlargesteigs(x, k)` | sum of top $k$ eigenvalues of $x$ | convex | not monotonic | IC: P symmetric |
119+
| `T in GeomMeanHypoCone(A, B, t)` | $T \preceq A \#_t B = A^{1/2} (A^{-1/2} B A^{-1/2})^t A^{1/2}$ | concave | increasing | IC: $A \succeq 0$, $B \succeq 0$, $t \in [0,1]$ |
120+
| `T in GeomMeanEpiCone(A, B, t)` | $T \succeq A \#_t B = A^{1/2} (A^{-1/2} B A^{-1/2})^t A^{1/2}$ | convex | not monotonic | IC: $A \succeq 0$, $B \succeq 0$, $t \in [-1, 0] \cup [1, 2]$ |
121+
| `quantum_entropy(X)` | $-\textrm{Tr}(X \log X)$ | concave | not monotonic | IC: $X \succeq 0$; uses natural log |
122+
| `quantum_relative_entropy(A, B)` | $\textrm{Tr}(A \log A - A \log B)$ | convex | not monotonic | IC: $A \succeq 0$, $B \succeq 0$; uses natural log |
123+
| `trace_logm(X, C)` | $\textrm{Tr}(C \log X)$ | concave in X | not monotonic | IC: $X \succeq 0$, $C \succeq 0$, $C$ constant; uses natural log |
124+
| `trace_mpower(A, t, C)` | $\textrm{Tr}(C A^t)$ | concave in A for $t \in [0,1]$, convex for $t \in [-1,0] \cup [1,2]$ | not monotonic | IC: $X \succeq 0$, $C \succeq 0$, $C$ constant, $t \in [-1, 2]$ |
125+
| `lieb_ando(A, B, K, t)` | $\textrm{Tr}(K' A^{1-t} K B^t)$ | concave in A,B for $t \in [0,1]$, convex for $t \in [-1,0] \cup [1,2]$ | not monotonic | IC: $A \succeq 0$, $B \succeq 0$, $K$ constant, $t \in [-1, 2]$ |
126+
| `T in RelativeEntropyEpiCone(X, Y, m, k, e)` | $T \succeq e' X^{1/2} \log(X^{1/2} Y^{-1} X^{1/2}) X^{1/2} e$ | convex | not monotonic | IC: $e$ constant; uses natural log |
119127

120128
Exponential + SDP representable Functions
121129
-----------------------------------------

src/Convex.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export conv, dotsort, entropy, exp, geomean, hinge_loss, huber, inner_product, i
1616
export log_perspective, logisticloss, logsumexp, matrixfrac, neg, norm2, norm_1, norm_inf, nuclearnorm
1717
export partialtrace, partialtranspose, pos, qol_elementwise, quadform, quadoverlin, rationalnorm
1818
export relative_entropy, scaledgeomean, sigmamax, square, sumlargest, sumlargesteigs, sumsmallest, sumsquares
19+
export GeomMeanHypoCone, GeomMeanEpiCone, RelativeEntropyEpiCone, quantum_relative_entropy, quantum_entropy
20+
export trace_logm, trace_mpower, lieb_ando
1921

2022
# rexports from LinearAlgebra
2123
export diag, diagm, Diagonal, dot, eigmax, eigmin, kron, logdet, norm, tr
@@ -152,6 +154,14 @@ include("atoms/sdp_cone/operatornorm.jl")
152154
include("atoms/sdp_cone/eig_min_max.jl")
153155
include("atoms/sdp_cone/matrixfrac.jl")
154156
include("atoms/sdp_cone/sumlargesteigs.jl")
157+
include("atoms/sdp_cone/geom_mean_hypocone.jl")
158+
include("atoms/sdp_cone/geom_mean_epicone.jl")
159+
include("atoms/sdp_cone/relative_entropy_epicone.jl")
160+
include("atoms/sdp_cone/quantum_relative_entropy.jl")
161+
include("atoms/sdp_cone/quantum_entropy.jl")
162+
include("atoms/sdp_cone/trace_logm.jl")
163+
include("atoms/sdp_cone/trace_mpower.jl")
164+
include("atoms/sdp_cone/lieb_ando.jl")
155165

156166
### exponential atoms
157167
include("atoms/exp_cone/exp.jl")
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#############################################################################
2+
# geom_mean_epicone.jl
3+
# Constrains T to
4+
# A #_t B ⪯ T
5+
# where:
6+
# * A #_t B is the t-weighted geometric mean of A and B:
7+
# A^{1/2} (A^{-1/2} B A^{-1/2})^t A^{1/2}
8+
# Parameter t should be in [-1, 0] or [1, 2].
9+
# * Constraints A ⪰ 0, B ⪰ 0 are added.
10+
# All expressions and atoms are subtypes of AbstractExpr.
11+
# Please read expressions.jl first.
12+
#
13+
# Note on fullhyp: GeomMeanEpiCone will always return a full epigraph cone
14+
# (unlike GeomMeanHypoCone) and so this parameter is not really used. It is
15+
# here just for consistency with the GeomMeanHypoCone function.
16+
#
17+
#REFERENCE
18+
# Ported from CVXQUAD which is based on the paper: "Lieb's concavity
19+
# theorem, matrix geometric means and semidefinite optimization" by Hamza
20+
# Fawzi and James Saunderson (arXiv:1512.03401)
21+
#############################################################################
22+
23+
struct GeomMeanEpiCone
24+
A::AbstractExpr
25+
B::AbstractExpr
26+
t::Rational
27+
size::Tuple{Int, Int}
28+
29+
function GeomMeanEpiCone(A::AbstractExpr, B::AbstractExpr, t::Rational, fullhyp::Bool=true)
30+
if size(A) != size(B)
31+
throw(DimensionMismatch("A and B must be the same size"))
32+
end
33+
n = size(A)[1]
34+
if size(A) != (n, n)
35+
throw(DimensionMismatch("A and B must be square"))
36+
end
37+
if t < -1 || (t > 0 && t < 1) || t > 2
38+
throw(DomainError(t, "t must be in the range [-1, 0] or [1, 2]"))
39+
end
40+
return new(A, B, t, (n, n))
41+
end
42+
43+
GeomMeanEpiCone(A::Value, B::AbstractExpr, t::Rational, fullhyp::Bool=true) = GeomMeanEpiCone(Constant(A), B, t, fullhyp)
44+
GeomMeanEpiCone(A::AbstractExpr, B::Value, t::Rational, fullhyp::Bool=true) = GeomMeanEpiCone(A, Constant(B), t, fullhyp)
45+
GeomMeanEpiCone(A::Value, B::Value, t::Rational, fullhyp::Bool=true) = GeomMeanEpiCone(Constant(A), Constant(B), t, fullhyp)
46+
47+
GeomMeanEpiCone(A::AbstractExprOrValue, B::AbstractExprOrValue, t::Integer, fullhyp::Bool=true) = GeomMeanEpiCone(A, B, t//1, fullhyp)
48+
end
49+
50+
struct GeomMeanEpiConeConstraint <: Constraint
51+
head::Symbol
52+
id_hash::UInt64
53+
T::AbstractExpr
54+
cone::GeomMeanEpiCone
55+
56+
function GeomMeanEpiConeConstraint(T::AbstractExpr, cone::GeomMeanEpiCone)
57+
if size(T) != cone.size
58+
throw(DimensionMismatch("T must be size $(cone.size)"))
59+
end
60+
id_hash = hash((cone.A, cone.B, cone.t, :GeomMeanEpiCone))
61+
return new(:GeomMeanEpiCone, id_hash, T, cone)
62+
end
63+
64+
GeomMeanEpiConeConstraint(T::Value, cone::GeomMeanEpiCone) = GeomMeanEpiConeConstraint(Constant(T), cone)
65+
end
66+
67+
in(T, cone::GeomMeanEpiCone) = GeomMeanEpiConeConstraint(T, cone)
68+
69+
function AbstractTrees.children(constraint::GeomMeanEpiConeConstraint)
70+
return (constraint.T, constraint.cone.A, constraint.cone.B, "t=$(constraint.cone.t)")
71+
end
72+
73+
# For t ∈ [-1, 0] ∪ [1, 2] the t-weighted matrix geometric mean is matrix convex (arxiv:1512.03401).
74+
# So if A and B are convex sets, then T ⪰ A #_t B will be a convex set.
75+
function vexity(constraint::GeomMeanEpiConeConstraint)
76+
A = vexity(constraint.cone.A)
77+
B = vexity(constraint.cone.B)
78+
T = vexity(constraint.T)
79+
80+
# NOTE: can't say A == NotDcp() because the NotDcp constructor prints a warning message.
81+
if typeof(A) == ConcaveVexity || typeof(A) == NotDcp
82+
return NotDcp()
83+
end
84+
if typeof(B) == ConcaveVexity || typeof(B) == NotDcp
85+
return NotDcp()
86+
end
87+
# Copied from vexity(c::GtConstraint)
88+
vex = ConvexVexity() + (-T)
89+
if vex == ConcaveVexity()
90+
vex = NotDcp()
91+
end
92+
return vex
93+
end
94+
95+
function conic_form!(constraint::GeomMeanEpiConeConstraint, unique_conic_forms::UniqueConicForms)
96+
if !has_conic_form(unique_conic_forms, constraint)
97+
A = constraint.cone.A
98+
B = constraint.cone.B
99+
t = constraint.cone.t
100+
T = constraint.T
101+
is_complex = sign(A) == ComplexSign() || sign(B) == ComplexSign() || sign(T) == ComplexSign()
102+
if is_complex
103+
make_temporary = () -> HermitianSemidefinite(size(A)[1])
104+
else
105+
make_temporary = () -> Semidefinite(size(A)[1])
106+
end
107+
108+
Z = make_temporary()
109+
110+
if t <= 0
111+
conic_form!([T A; A Z] 0, unique_conic_forms)
112+
conic_form!(Z in GeomMeanHypoCone(A, B, -t, false), unique_conic_forms)
113+
else
114+
@assert t >= 1 # range of t checked in GeomMeanEpiCone constructor
115+
conic_form!([T B; B Z] 0, unique_conic_forms)
116+
conic_form!(Z in GeomMeanHypoCone(A, B, 2-t, false), unique_conic_forms)
117+
end
118+
119+
cache_conic_form!(unique_conic_forms, constraint, Array{Convex.ConicConstr,1}())
120+
end
121+
return get_conic_form(unique_conic_forms, constraint)
122+
end

0 commit comments

Comments
 (0)