5
5
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
6
6
7
7
"""
8
- quantum_relative_entropy returns LinearAlgebra.tr(A*(log(A)-log(B))) where A and B
9
- are positive semidefinite matrices. Note this function uses logarithm
10
- base e, not base 2, so return value is in units of nats, not bits.
8
+ QuantumRelativeEntropy1Atom(
9
+ A::AbstractExpr,
10
+ B::AbstractExpr,
11
+ m::Integer,
12
+ k::Integer,
13
+ )
11
14
12
- Quantum relative entropy is convex (jointly) in (A,B). This function
13
- implements the semidefinite programming approximation given in the reference
14
- below. Parameters m and k control the accuracy of this approximation: m is
15
- the number of quadrature nodes to use and k the number of square-roots to
16
- take. See reference for more details.
15
+ quantum_relative_entropy returns LinearAlgebra.tr(A*(log(A)-log(B))) where A and
16
+ B are positive semidefinite matrices.
17
+
18
+ Note this function uses logarithm base e, not base 2, so return value is in
19
+ units of nats, not bits.
20
+
21
+ Quantum relative entropy is convex (jointly) in (A, B). This function implements
22
+ the semidefinite programming approximation given in the reference below.
23
+ Parameters m and k control the accuracy of this approximation: m is the number
24
+ of quadrature nodes to use and k the number of square-roots to take. See
25
+ reference for more details.
17
26
18
27
Implementation uses the expression
19
- D(A||B) = e'*D_{op} (A \\ otimes I || I \\ otimes B) )*e
28
+
29
+ D(A||B) = e'*D_{op} (A \\ otimes I || I \\ otimes B) )*e
30
+
20
31
where D_{op} is the operator relative entropy and e = vec(Matrix(I, n, n)).
21
32
22
- All expressions and atoms are subtypes of AbstractExpr.
23
- Please read expressions.jl first.
33
+ ## Reference
24
34
25
- REFERENCE
26
- Ported from CVXQUAD which is based on the paper: "Lieb's concavity
27
- theorem, matrix geometric means and semidefinite optimization" by Hamza
28
- Fawzi and James Saunderson (arXiv:1512.03401)
35
+ Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem,
36
+ matrix geometric means and semidefinite optimization" by Hamza Fawzi and James
37
+ Saunderson (arXiv:1512.03401)
29
38
"""
30
39
mutable struct QuantumRelativeEntropy1Atom <: AbstractExpr
31
40
children:: Tuple{AbstractExpr,AbstractExpr}
@@ -39,22 +48,60 @@ mutable struct QuantumRelativeEntropy1Atom <: AbstractExpr
39
48
m:: Integer ,
40
49
k:: Integer ,
41
50
)
42
- children = (A, B )
51
+ n = size (A, 1 )
43
52
if size (A) != size (B)
44
53
throw (DimensionMismatch (" A and B must be the same size" ))
45
- end
46
- n = size (A)[1 ]
47
- if size (A) != (n, n)
54
+ elseif size (A) != (n, n)
48
55
throw (DimensionMismatch (" A and B must be square" ))
49
56
end
50
- return new (children , (1 , 1 ), m, k)
57
+ return new ((A, B) , (1 , 1 ), m, k)
51
58
end
52
59
end
53
60
54
61
function head (io:: IO , :: QuantumRelativeEntropy1Atom )
55
62
return print (io, " quantum_relative_entropy" )
56
63
end
57
64
65
+ Base. sign (:: QuantumRelativeEntropy1Atom ) = Positive ()
66
+
67
+ function monotonicity (:: QuantumRelativeEntropy1Atom )
68
+ return (NoMonotonicity (), NoMonotonicity ())
69
+ end
70
+
71
+ curvature (:: QuantumRelativeEntropy1Atom ) = ConvexVexity ()
72
+
73
+ function evaluate (atom:: QuantumRelativeEntropy1Atom )
74
+ A = evaluate (atom. children[1 ])
75
+ B = evaluate (atom. children[2 ])
76
+ return quantum_relative_entropy (A, B)
77
+ end
78
+
79
+ function quantum_relative_entropy (
80
+ A:: AbstractExpr ,
81
+ B:: AbstractExpr ,
82
+ m:: Integer = 3 ,
83
+ k:: Integer = 3 ,
84
+ )
85
+ return QuantumRelativeEntropy1Atom (A, B, m, k)
86
+ end
87
+
88
+ function new_conic_form! (
89
+ context:: Context{T} ,
90
+ atom:: QuantumRelativeEntropy1Atom ,
91
+ ) where {T}
92
+ A, B = atom. children[1 ], atom. children[2 ]
93
+ add_constraint! (context, A ⪰ 0 )
94
+ add_constraint! (context, B ⪰ 0 )
95
+ I = Matrix (one (T) * LinearAlgebra. I (size (A, 1 )))
96
+ m, k, e = atom. m, atom. k, vec (I)
97
+ τ = Variable ()
98
+ add_constraint! (
99
+ context,
100
+ τ in RelativeEntropyEpiCone (kron (A, I), kron (I, conj (B)), m, k, e),
101
+ )
102
+ return conic_form! (context, τ)
103
+ end
104
+
58
105
mutable struct QuantumRelativeEntropy2Atom <: AbstractExpr
59
106
children:: Tuple{AbstractExpr}
60
107
size:: Tuple{Int,Int}
@@ -71,16 +118,12 @@ mutable struct QuantumRelativeEntropy2Atom <: AbstractExpr
71
118
k:: Integer ,
72
119
nullspace_tol:: Real ,
73
120
)
74
- children = (A,)
75
-
121
+ n = size (A, 1 )
76
122
if size (A) != size (B)
77
123
throw (DimensionMismatch (" A and B must be the same size" ))
78
- end
79
- n = size (A)[1 ]
80
- if size (A) != (n, n)
124
+ elseif size (A) != (n, n)
81
125
throw (DimensionMismatch (" A and B must be square" ))
82
- end
83
- if norm (B - B' ) > nullspace_tol
126
+ elseif norm (B - B' ) > nullspace_tol
84
127
throw (DomainError (B, " B must be Hermitian" ))
85
128
end
86
129
# nullspace of A must contain nullspace of B
@@ -90,52 +133,25 @@ mutable struct QuantumRelativeEntropy2Atom <: AbstractExpr
90
133
end
91
134
J = U' [v.> nullspace_tol, :]
92
135
K = U' [v.< nullspace_tol, :]
93
- return new (children , (1 , 1 ), m, k, B, J, K)
136
+ return new ((A,) , (1 , 1 ), m, k, B, J, K)
94
137
end
95
138
end
96
139
97
140
function head (io:: IO , :: QuantumRelativeEntropy2Atom )
98
141
return print (io, " quantum_relative_entropy" )
99
142
end
100
143
101
- function Base. sign (
102
- :: Union{QuantumRelativeEntropy1Atom,QuantumRelativeEntropy2Atom} ,
103
- )
104
- return Positive ()
105
- end
106
-
107
- function monotonicity (:: QuantumRelativeEntropy1Atom )
108
- return (NoMonotonicity (), NoMonotonicity ())
109
- end
144
+ Base. sign (:: QuantumRelativeEntropy2Atom ) = Positive ()
110
145
111
146
monotonicity (:: QuantumRelativeEntropy2Atom ) = (NoMonotonicity (),)
112
147
113
- function curvature (
114
- :: Union{QuantumRelativeEntropy1Atom,QuantumRelativeEntropy2Atom} ,
115
- )
116
- return ConvexVexity ()
117
- end
118
-
119
- function evaluate (atom:: QuantumRelativeEntropy1Atom )
120
- A = evaluate (atom. children[1 ])
121
- B = evaluate (atom. children[2 ])
122
- return quantum_relative_entropy (A, B)
123
- end
148
+ curvature (:: QuantumRelativeEntropy2Atom ) = ConvexVexity ()
124
149
125
150
function evaluate (atom:: QuantumRelativeEntropy2Atom )
126
151
A = evaluate (atom. children[1 ])
127
152
return quantum_relative_entropy (A, atom. B)
128
153
end
129
154
130
- function quantum_relative_entropy (
131
- A:: AbstractExpr ,
132
- B:: AbstractExpr ,
133
- m:: Integer = 3 ,
134
- k:: Integer = 3 ,
135
- )
136
- return QuantumRelativeEntropy1Atom (A, B, m, k)
137
- end
138
-
139
155
function quantum_relative_entropy (
140
156
A:: AbstractExpr ,
141
157
B:: Union{AbstractMatrix,Constant} ,
@@ -163,8 +179,7 @@ function quantum_relative_entropy(
163
179
k:: Integer = 0 ,
164
180
nullspace_tol:: Real = 1e-6 ,
165
181
)
166
- A = evaluate (A)
167
- B = evaluate (B)
182
+ A, B = evaluate (A), evaluate (B)
168
183
if size (A) != size (B)
169
184
throw (DimensionMismatch (" A and B must be the same size" ))
170
185
elseif size (A) != (size (A)[1 ], size (A)[1 ])
@@ -190,31 +205,9 @@ function quantum_relative_entropy(
190
205
return real (LinearAlgebra. tr (Ap * (log (Ap) - log (Bp))))
191
206
end
192
207
193
- function new_conic_form! (context:: Context , atom:: QuantumRelativeEntropy1Atom )
194
- A = atom. children[1 ]
195
- B = atom. children[2 ]
196
- m = atom. m
197
- k = atom. k
198
- n = size (A)[1 ]
199
- eye = Matrix (1.0 * LinearAlgebra. I, n, n)
200
- e = vec (eye)
201
- add_constraint! (context, A ⪰ 0 )
202
- add_constraint! (context, B ⪰ 0 )
203
- τ = Variable ()
204
- add_constraint! (
205
- context,
206
- τ in RelativeEntropyEpiCone (kron (A, eye), kron (eye, conj (B)), m, k, e),
207
- )
208
- return conic_form! (context, minimize (τ))
209
- end
210
-
211
208
function new_conic_form! (context:: Context , atom:: QuantumRelativeEntropy2Atom )
212
- A = atom. children[1 ]
213
- B = atom. B
214
- J = atom. J
215
- K = atom. K
216
- m = atom. m
217
- k = atom. k
209
+ A = only (atom. children)
210
+ B, J, K, m, k = atom. B, atom. J, atom. K, atom. m, atom. k
218
211
add_constraint! (context, A ⪰ 0 )
219
212
τ = if length (K) > 0
220
213
add_constraint! (context, K * A * K' == 0 )
@@ -224,5 +217,5 @@ function new_conic_form!(context::Context, atom::QuantumRelativeEntropy2Atom)
224
217
else
225
218
- quantum_entropy (A, m, k) - real (LinearAlgebra. tr (A * log (B)))
226
219
end
227
- return conic_form! (context, minimize (τ) )
220
+ return conic_form! (context, τ )
228
221
end
0 commit comments