Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add complex psd cone #301

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions docs/src/api/cones.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ The cone :math:`\mathcal{K}` can be any Cartesian product of the following primi
- :math:`\{ s \in \mathbf{R}^{k(k+1)/2} \mid \text{mat}(s) \succeq 0 \}` (See :ref:`note <sdcone>`)
- :code:`s` array of PSD cone lengths with :code:`ssize` elements, each :math:`s_i = k_i` in description.
- :math:`\displaystyle \sum_{i=1}^{\text{ssize}} \frac{s_i(s_i+1)}{2}`
* - Complex positive semidefinite cone
- :math:`\{ s \in \mathbf{R}^{k^2} \mid \text{mat}(s) \succeq 0 \}` (See :ref:`note <sdcone>`)
- :code:`cs` array of PSD cone lengths with :code:`cssize` elements, each :math:`cs_i = k_i` in description.
- :math:`\displaystyle \sum_{i=1}^{\text{cssize}} cs_i^2`
* - Exponential cone
- :math:`\{ (x,y,z) \in \mathbf{R}^3 \mid y e^{x/y} \leq z, y>0 \}`
- :code:`ep` number of cone triples.
Expand Down Expand Up @@ -70,45 +74,52 @@ and therefore the variable vector is stacked as :code:`[x, y, z]`, etc.
Semidefinite cones
------------------

The symmetric positive semidefinite cone of matrices is the set
The real positive semidefinite cone of matrices is the set

.. math::
\{S \in \mathbf{R}^{k \times k} \mid S = S^\top, x^\top S x \geq 0 \ \forall x \in \mathbf{R}^k \}
\{S \in \mathbf{R}^{k \times k} \mid S = S^\top,\ x^\top S x \geq 0 \ \forall x \in \mathbf{R}^k \},

and the complex positive semidefinite cone is the set

.. math::
\{S \in \mathbf{C}^{k \times k} \mid S = S^\dagger,\ x^\dagger S x \geq 0 \ \forall x \in \mathbf{C}^k \},

and for short we use :math:`S \succeq 0` to denote membership. SCS
vectorizes this cone in a special way which we detail here.
vectorizes these cones in a special way which we detail here.

SCS assumes that the input data corresponding to
semidefinite cones have been vectorized by scaling the off-diagonal entries by
:math:`\sqrt{2}` and stacking the lower triangular elements column-wise. For a :math:`k \times k`
matrix variable (or data matrix) this operation would create a vector of length
:math:`k(k+1)/2`. Scaling by :math:`\sqrt{2}` is required to preserve the inner-product.
SCS assumes that the input data corresponding to positive semidefinite cones have been vectorized by scaling the off-diagonal entries by
:math:`\sqrt{2}` and stacking the real parameters of the lower triangle column-wise. For a :math:`k \times k`
real matrix variable (or data matrix) this operation creates a vector of length
:math:`k(k+1)/2`, whereas for a :math:`k \times k` complex matrix it creates a vector of length :math:`k^2`. Scaling by :math:`\sqrt{2}` is required to preserve the inner-product.

**This must be done for the rows of both** :math:`A` **and** :math:`b` **that correspond to semidefinite cones and must be done independently for each semidefinite cone.**

More explicitly, we want to express :math:`\text{Trace}(Y S)` as :math:`\text{vec}(Y)^\top \text{vec}(S)`,
where the :math:`\text{vec}` operation takes the (assumed to be symmetric) :math:`k \times k` matrix
More explicitly, we want to express :math:`\text{Trace}(Y^\dagger S)` as :math:`\text{vec}(Y)^\dagger \text{vec}(S)`,
where the :math:`\text{vec}` operation takes the :math:`k \times k` matrix

.. math::

S = \begin{bmatrix}
S_{11} & S_{12} & \ldots & S_{1k} \\
S_{21} & S_{22} & \ldots & S_{2k} \\
\vdots & \vdots & \ddots & \vdots \\
S_{k1} & S_{k2} & \ldots & S_{kk} \\
\end{bmatrix}

and produces a vector consisting of the lower triangular elements scaled and arranged as
and produces a vector consisting of the lower triangular real parameters scaled and re-arranged. In the real case, the result is

.. math::
\text{vec}(S) = (S_{11}, \sqrt{2} S_{21}, \ldots, \sqrt{2} S_{k1}, S_{22}, \sqrt{2}S_{32}, \dots, S_{k-1,k-1}, \sqrt{2}S_{k,k-1}, S_{kk}) \in \mathbf{R}^{k(k+1)/2},

whereas in the complex case the result is

\text{vec}(S) = (S_{11}, \sqrt{2} S_{21}, \ldots, \sqrt{2} S_{k1}, S_{22}, \sqrt{2}S_{32}, \dots, S_{k-1,k-1}, \sqrt{2}S_{k,k-1}, S_{kk}) \in \mathbf{R}^{k(k+1)/2}.
.. math::
\text{vec}(S) = (S_{11}, \sqrt{2} \Re(S_{21}), \sqrt{2} \Im(S_{21}), \ldots, \sqrt{2} \Re(S_{k1}), \sqrt{2} \Im(S_{k1}), S_{22}, \\\sqrt{2}\Re(S_{32}), \sqrt{2}\Im(S_{32}), \dots, S_{k-1,k-1}, \sqrt{2}\Re(S_{k,k-1}), \sqrt{2}\Im(S_{k,k-1}), S_{kk}) \in \mathbf{R}^{k^2}.

To recover the matrix solution this operation must be inverted on the components
of the vectors returned by SCS corresponding to each semidefinite cone. That is, the
off-diagonal entries must be scaled by :math:`1/\sqrt{2}` and the upper triangular
entries are filled in by copying the values of lower triangular entries.
Explicitly, the inverse operation takes vector :math:`s \in
Explicitly, in the real case the inverse operation takes vector :math:`s \in
\mathbf{R}^{k(k+1)/2}` and produces the matrix

.. math::
Expand All @@ -118,19 +129,31 @@ Explicitly, the inverse operation takes vector :math:`s \in
\vdots & \vdots & \ddots & \vdots \\
s_{k} / \sqrt{2} & s_{2k-1} / \sqrt{2} & \ldots & s_{k(k+1) / 2} \\
\end{bmatrix}
\in \mathbf{R}^{k \times k}.
\in \mathbf{R}^{k \times k},

whereas in the complex case the inverse operation takes vector :math:`s \in
\mathbf{R}^{k^2}` and produces the matrix

.. math::
\text{mat}(s) = \begin{bmatrix}
s_{1} & (s_{2} - i s_3) / \sqrt{2} & \ldots & (s_{2k-2} - is_{2k-1}) / \sqrt{2} \\
(s_{2} + i s_3) / \sqrt{2} & s_{2k} & \ldots & (s_{4k-5} - is_{4k-4}) / \sqrt{2} \\
\vdots & \vdots & \ddots & \vdots \\
(s_{2k-2} + is_{2k-1}) / \sqrt{2} & (s_{4k-5} + is_{4k-4}) / \sqrt{2} & \ldots & s_{k^2} \\
\end{bmatrix}
\in \mathbf{C}^{k \times k},

So the cone definition that SCS uses is
So the cone definitions that SCS uses are

.. math::
\mathcal{S}_+^k = \{ \text{vec}(S) \mid S \succeq 0\} = \{s \in \mathbf{R}^{k(k+1)/2} \mid \text{mat}(s) \succeq 0 \}.
\mathcal{S}_\mathbf{R}^k = \{ \text{vec}(S) \mid S \succeq 0\} = \{s \in \mathbf{R}^{k(k+1)/2} \mid \text{mat}(s) \succeq 0 \}.\\
\mathcal{S}_\mathbf{C}^k = \{ \text{vec}(S) \mid S \succeq 0\} = \{s \in \mathbf{R}^{k^2 } \mid \text{mat}(s) \succeq 0 \}.

Example
^^^^^^^

For a concrete example in python see :ref:`py_mat_completion`.
Here we consider the symmetric positive semidefinite cone constraint over
For a concrete example in Python see :ref:`py_mat_completion`.
Here we consider the real positive semidefinite cone constraint over
variables :math:`x \in \mathbf{R}^n` and :math:`S \in \mathbf{R}^{k \times k}`

.. math::
Expand Down
6 changes: 4 additions & 2 deletions include/cones.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ struct SCS_CONE_WORK {
scs_float box_t_warm_start;
#ifdef USE_LAPACK
/* workspace for eigenvector decompositions: */
scs_float *Xs, *Z, *e, *work;
blas_int lwork;
scs_float *Xs, *Z, *e, *work, *rwork;
scs_complex_float *cXs, *cZ, *cwork;
blas_int *isuppz, *iwork;
blas_int lwork, lcwork, lrwork, liwork;
#endif
};

Expand Down
4 changes: 4 additions & 0 deletions include/scs.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ typedef struct {
scs_int *s;
/** Length of semidefinite constraints array `s`. */
scs_int ssize;
/** Array of complex semidefinite cone constraints, `len(cs) = cssize`. */
scs_int *cs;
/** Length of complex semidefinite constraints array `cs`. */
scs_int cssize;
/** Number of primal exponential cone triples. */
scs_int ep;
/** Number of dual exponential cone triples. */
Expand Down
4 changes: 4 additions & 0 deletions include/scs_blas.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ extern "C" {
#ifndef SFLOAT
#define BLAS(x) d##x
#define BLASI(x) id##x
#define BLASC(x) z##x
#else
#define BLAS(x) s##x
#define BLASI(x) is##x
#define BLASC(x) c##x
#endif
#else
/* this extra indirection is needed for BLASSUFFIX to work correctly as a
Expand All @@ -31,9 +33,11 @@ extern "C" {
#ifndef SFLOAT
#define BLAS(x) stitch__(d, x, BLASSUFFIX)
#define BLASI(x) stitch__(id, x, BLASSUFFIX)
#define BLASC(x) stitch__(z, x, BLASSUFFIX)
#else
#define BLAS(x) stitch__(s, x, BLASSUFFIX)
#define BLASI(x) stitch__(is, x, BLASSUFFIX)
#define BLASC(x) stitch__(c, x, BLASSUFFIX)
#endif
#endif

Expand Down
4 changes: 4 additions & 0 deletions include/scs_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
extern "C" {
#endif

#include <complex.h>

#ifdef DLONG
/*#ifdef _WIN64
#include <stdint.h>
Expand All @@ -26,8 +28,10 @@ typedef int scs_int;

#ifndef SFLOAT
typedef double scs_float;
typedef double complex scs_complex_float;
#else
typedef float scs_float;
typedef float complex scs_complex_float;
#endif

#ifdef __cplusplus
Expand Down
Loading
Loading