Skip to content
This repository has been archived by the owner on Jun 12, 2023. It is now read-only.

Commit

Permalink
Update 'auto' method to not use SCS solver for CVXPY (#536)
Browse files Browse the repository at this point in the history
Fix the "auto" method of the tomography fitters to only use "cvx" if CVXPY is installed and a third-party SDP solver other than SCS is available.

This is because the SCS solver has lower accuracy than other solver methods and often returns a density matrix or Choi-matrix that is not completely-positive and fails validation when used state_fidelity or process_fidelity functions
  • Loading branch information
chriseclectic authored Nov 11, 2020
1 parent 563d969 commit 006876e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
32 changes: 23 additions & 9 deletions qiskit/ignis/verification/tomography/fitters/base_fitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class TomographyFitter:
"""Base maximum-likelihood estimate tomography fitter class"""

_HAS_SDP_SOLVER = None
_HAS_SDP_SOLVER_NOT_SCS = False

def __init__(self,
result: Union[Result, List[Result]],
Expand Down Expand Up @@ -120,12 +121,14 @@ def fit(self,
**kwargs) -> np.array:
r"""Reconstruct a quantum state using CVXPY convex optimization.
**Fitter method**
**Fitter method**
The ``cvx`` fitter method used CVXPY convex optimization package.
The ``lstsq`` method uses least-squares fitting (linear inversion).
The ``auto`` method will use 'cvx' if the CVXPY package is found on
the system, otherwise it will default to 'lstsq'.
The ``'cvx'`` fitter method uses the CVXPY convex optimization package
with a SDP solver.
The ``'lstsq'`` method uses least-squares fitting.
The ``'auto'`` method will use ``'cvx'`` if the both the CVXPY and a suitable
SDP solver packages are found on the system, otherwise it will default
to ``'lstsq'``.
**Objective function**
Expand Down Expand Up @@ -165,9 +168,14 @@ def fit(self,
**CVXPY Solvers:**
Various solvers can be called in CVXPY using the `solver` keyword
argument. See the `CVXPY documentation
argument. If ``psd=True`` an SDP solver is required other an SOCP
solver is required. See the `CVXPY documentation
<https://www.cvxpy.org/tutorial/advanced/index.html#solve-method-options>`_
for more information on solvers.
Note that the default SDP solver ('SCS') distributed
with CVXPY will not be used for the ``'auto'`` method due its reduced
accuracy compared to other solvers. When using the ``'cvx'`` method we
strongly recommend installing one of the other supported SDP solvers.
References:
Expand Down Expand Up @@ -200,7 +208,11 @@ def fit(self,
# Choose automatic method
if method == 'auto':
self._check_for_sdp_solver()
if self._HAS_SDP_SOLVER:
if self._HAS_SDP_SOLVER_NOT_SCS:
# We don't use the SCS solver for automatic method as it has
# lower accuracy than the other supported SDP solvers which
# typically results in the returned matrix not being
# completely positive.
method = 'cvx'
else:
method = 'lstsq'
Expand Down Expand Up @@ -516,15 +528,17 @@ def _check_for_sdp_solver(cls):
# pylint:disable=import-error
import cvxpy
solvers = cvxpy.installed_solvers()
if 'CVXOPT' in solvers:
# Check for other SDP solvers cvxpy supports
if 'CVXOPT' in solvers or 'MOSEK' in solvers:
cls._HAS_SDP_SOLVER_NOT_SCS = True
cls._HAS_SDP_SOLVER = True
return
if 'SCS' in solvers:
# Try example problem to see if built with BLAS
# SCS solver cannot solver larger than 2x2 matrix
# problems without BLAS
try:
var = cvxpy.Variable((4, 4), PSD=True)
var = cvxpy.Variable((5, 5), PSD=True)
obj = cvxpy.Minimize(cvxpy.norm(var))
cvxpy.Problem(obj).solve(solver='SCS')
cls._HAS_SDP_SOLVER = True
Expand Down
2 changes: 2 additions & 0 deletions qiskit/ignis/verification/tomography/fitters/cvx_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ def cvx_fit(data: np.array,
if 'solver' not in kwargs:
if 'CVXOPT' in cvxpy.installed_solvers():
kwargs['solver'] = 'CVXOPT'
elif 'MOSEK' in cvxpy.installed_solvers():
kwargs['solver'] = 'MOSEK'

problem_solved = False
while not problem_solved:
Expand Down
13 changes: 13 additions & 0 deletions releasenotes/notes/no-auto-scs-b82ebef53508fc7b.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
fixes:
- |
Fix the ``"auto"`` method of the
:class:`~qiskit.ignis.verification.tomography.TomographyFitter`,
:class:`~qiskit.ignis.verification.tomography.StateTomographyFitter`, and
:class:`~qiskit.ignis.verification.tomography.ProcessTomographyFitter` to
only use ``"cvx"`` if CVXPY is installed *and* a third-party SDP solver
other than SCS is available. This is because the SCS solver has lower
accuracy than other solver methods and often returns a density matrix or
Choi-matrix that is not completely-positive and fails validation when used
with the :func:`qiskit.quantum_info.state_fidelity` or
:func:`qiskit.quantum_info.process_fidelity` functions.

0 comments on commit 006876e

Please sign in to comment.