Getting started¶
In this guide, we will use the following quantum relative entropy program
where
as a running example to see how we can solve problems in QICS. This is a simple example of the a nearest correlation matrix problem. Further examples showing how QICS can be used to solve semidefinite and quantum relative entropy programs can be found in Examples.
Modelling¶
First, we need to reformulate the above problem as a standard form conic program. We can do this by rewriting the problem as
where
In QICS, we represent our variables \((t, X, Y)\in\mathbb{R}\times \mathbb{S}^2\times\mathbb{S}^2\) as a vector \(x\in\mathbb{R}^9\), with lements represented by
See here for additional details about how QICS vectorizes matrices. We can now represent our linear objective function as \(c^\top x\), where
In Python, we represent this using a numpy.ndarray
array.
>>> import numpy
>>> c = numpy.array([[1., 0., 0., 0., 0., 0., 0., 0., 0.]]).T
Additionaly, we represent our linear equality constraints using \(Ax=b\), where
and
Again, in Python we represent this using numpy.ndarray
arrays.
>>> A = numpy.array([ \
... [0., 1., 0., 0., 0., 0., 0., 0., 0.], \
... [0., 0., 1., 1., 0., 0., 0., 0., 0.], \
... [0., 0., 0., 0., 1., 0., 0., 0., 0.], \
... [0., 0., 0., 0., 0., 1., 0., 0., 0.], \
... [0., 0., 0., 0., 0., 0., 0., 0., 1.] \
... ])
>>> b = numpy.array([[2., 2., 2., 1., 1.]]).T
Finally, we want to tell QICS that \(x\) must be constrained in the
quantum relative entropy cone \(\mathcal{QRE}_2\). We do this by using the
qics.cones.QuantRelEntr
class.
>>> import qics
>>> cones = [qics.cones.QuantRelEntr(2)]
Note
We define cones
as a list of cones, as often we solve conic programs
involving a Cartesian product of cones.
Finally, we initialize a qics.Model
class to represent our conic
program using the matrices and cones we have defined.
>>> model = qics.Model(c=c, A=A, b=b, cones=cones)
Solving¶
Now that we have built our model, solving the conic program is fairly
straightforward. First, we initialize a qics.Solver
class with the
model we have defined.
>>> solver = qics.Solver(model)
Optionally, there are also many solver settings we can specify when initializing
the qics.Solver
. A list of these options can be found
here. Once we have initialized our
qics.Solver
, we then solve the conic program by calling
>>> info = solver.solve()
====================================================================
QICS v1.0.0 - Quantum Information Conic Solver
by K. He, J. Saunderson, H. Fawzi (2024)
====================================================================
Problem summary:
no. vars: 9 barr. par: 6
no. constr: 5 symmetric: False
cone dim: 9 complex: False
no. cones: 1 sparse: False
...
Solution summary
sol. status: optimal num. iter: 7
exit status: solved solve time: ...
primal obj: 2.772588704718e+00 primal feas: 6.28e-09
dual obj: 2.772588709215e+00 dual feas: 3.14e-09
The solver returns a dictionary info
containing additional information about
the solution. A list of all keys contained in this dictionary can be found
here. For example, we can access the
optimal variable \(Y\) by using
>>> print(info["s_opt"][0][2])
[[1. 0.5]
[0.5 1. ]]
Note
The info["s_opt"]
object is a qics.point.VecProduct
, which
represents a Cartesian product of real vectors, symmetric matrices, and
Hermitian matrices. To access arrays corresponding to these vectors, we use
info["s_opt"][i][j]
to access the \(j\)-th variable corresponding to
the \(i\)-th cone.