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

[Stable] Add scikit-learn dependency and add CI job without optional dependencies (#436) #439

Merged
Merged
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
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ matrix:
- MPLBACKEND=ps
- PYTHON_VERSION=3.8.1
- TOXENV=py38
- python: "3.8"
name: "Python 3.8 tests without optional dependencies"
stage: all_python
env: TOXENV=no-opt
stage: all_python
script: tox
- if: tag IS present
python: "3.6"
env:
Expand Down
10 changes: 10 additions & 0 deletions releasenotes/notes/missing-dependency-e7c99c7751bcd162.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
upgrade:
- |
A new requirement `scikit-learn <https://scikit-learn.org/stable/>`__ has
been added to the requirements list. This dependency was added in the 0.3.0
release but wasn't properly exposed as a dependency in that release. This
would lead to an ``ImportError`` if the
:mod:`qiskit.ignis.measurement.discriminator.iq_discriminators` module was
imported. This is now correctly listed as a dependency so that
``scikit-learn`` will be installed with qiskit-ignis.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"qiskit-terra>=0.13.0",
"scipy>=0.19,!=0.19.1",
"setuptools>=40.1.0",
"scikit-learn>=0.17",
]


Expand Down
26 changes: 17 additions & 9 deletions test/tomography/test_process_tomography.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,40 @@
from qiskit.quantum_info import Choi

import qiskit.ignis.verification.tomography as tomo
from qiskit.ignis.verification.tomography.fitters import cvx_fit


def run_circuit_and_tomography(circuit, qubits):
def run_circuit_and_tomography(circuit, qubits, method):
choi_ideal = Choi(circuit).data
qst = tomo.process_tomography_circuits(circuit, qubits)
job = qiskit.execute(qst, Aer.get_backend('qasm_simulator'),
shots=5000)
tomo_fit = tomo.ProcessTomographyFitter(job.result(), qst)
choi_cvx = tomo_fit.fit(method='cvx').data
choi_mle = tomo_fit.fit(method='lstsq').data
return (choi_cvx, choi_mle, choi_ideal)
choi = tomo_fit.fit(method=method).data
return (choi, choi_ideal)


class TestProcessTomography(unittest.TestCase):
def setUp(self):
super().setUp()
self.method = 'lstsq'

def test_bell_2_qubits(self):
q2 = QuantumRegister(2)
bell = QuantumCircuit(q2)
bell.h(q2[0])
bell.cx(q2[0], q2[1])

choi_cvx, choi_mle, choi_ideal = run_circuit_and_tomography(bell, q2)
F_bell_cvx = state_fidelity(choi_ideal/4, choi_cvx/4, validate=False)
self.assertAlmostEqual(F_bell_cvx, 1, places=1)
F_bell_mle = state_fidelity(choi_ideal/4, choi_mle/4, validate=False)
self.assertAlmostEqual(F_bell_mle, 1, places=1)
choi, choi_ideal = run_circuit_and_tomography(bell, q2, self.method)
F_bell = state_fidelity(choi_ideal/4, choi/4, validate=False)
self.assertAlmostEqual(F_bell, 1, places=1)


@unittest.skipUnless(cvx_fit._HAS_CVX, 'cvxpy is required for this test')
class TestProcessTomographyCVX(TestProcessTomography):
def setUp(self):
super().setUp()
self.method = 'cvx'


if __name__ == '__main__':
Expand Down
67 changes: 32 additions & 35 deletions test/tomography/test_state_tomography.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@
import qiskit.ignis.verification.tomography.fitters.cvx_fit as cvx_fit


def run_circuit_and_tomography(circuit, qubits):
def run_circuit_and_tomography(circuit, qubits, method='lstsq'):
psi = Statevector.from_instruction(circuit)
qst = tomo.state_tomography_circuits(circuit, qubits)
job = qiskit.execute(qst, Aer.get_backend('qasm_simulator'),
shots=5000)
tomo_fit = tomo.StateTomographyFitter(job.result(), qst)
rho_cvx = tomo_fit.fit(method='cvx')
rho_mle = tomo_fit.fit(method='lstsq')
return (rho_cvx, rho_mle, psi)
rho = tomo_fit.fit(method=method)
return (rho, psi)


@unittest.skipUnless(cvx_fit._HAS_CVX, 'cvxpy is required to run this test')
class TestFitter(unittest.TestCase):

def test_trace_constraint(self):
p = numpy.array([1/2, 1/2, 1/2, 1/2, 1/2, 1/2])

Expand All @@ -58,29 +57,28 @@ def test_trace_constraint(self):


class TestStateTomography(unittest.TestCase):
def setUp(self):
super().setUp()
self.method = 'lstsq'

def test_bell_2_qubits(self):
q2 = QuantumRegister(2)
bell = QuantumCircuit(q2)
bell.h(q2[0])
bell.cx(q2[0], q2[1])

rho_cvx, rho_mle, psi = run_circuit_and_tomography(bell, q2)
F_bell_cvx = state_fidelity(psi, rho_cvx, validate=False)
self.assertAlmostEqual(F_bell_cvx, 1, places=1)
F_bell_mle = state_fidelity(psi, rho_mle, validate=False)
self.assertAlmostEqual(F_bell_mle, 1, places=1)
rho, psi = run_circuit_and_tomography(bell, q2, self.method)
F_bell = state_fidelity(psi, rho, validate=False)
self.assertAlmostEqual(F_bell, 1, places=1)

def test_bell_2_qubits_no_register(self):
bell = QuantumCircuit(2)
bell.h(0)
bell.cx(0, 1)

rho_cvx, rho_mle, psi = run_circuit_and_tomography(bell, (0, 1))
F_bell_cvx = state_fidelity(psi, rho_cvx, validate=False)
self.assertAlmostEqual(F_bell_cvx, 1, places=1)
F_bell_mle = state_fidelity(psi, rho_mle, validate=False)
self.assertAlmostEqual(F_bell_mle, 1, places=1)
rho, psi = run_circuit_and_tomography(bell, (0, 1), self.method)
F_bell = state_fidelity(psi, rho, validate=False)
self.assertAlmostEqual(F_bell, 1, places=1)

def test_different_qubit_sets(self):
circuit = QuantumCircuit(5)
Expand All @@ -92,12 +90,10 @@ def test_different_qubit_sets(self):
circuit.cx(1, 3)

for qubit_pair in [(0, 1), (2, 3), (1, 4), (0, 3)]:
rho_cvx, rho_mle, psi = run_circuit_and_tomography(circuit, qubit_pair)
rho, psi = run_circuit_and_tomography(circuit, qubit_pair, self.method)
psi = partial_trace(psi, [x for x in range(5) if x not in qubit_pair])
F_cvx = state_fidelity(psi, rho_cvx, validate=False)
self.assertAlmostEqual(F_cvx, 1, places=1)
F_mle = state_fidelity(psi, rho_mle, validate=False)
self.assertAlmostEqual(F_mle, 1, places=1)
F = state_fidelity(psi, rho, validate=False)
self.assertAlmostEqual(F, 1, places=1)

def test_bell_3_qubits(self):
q3 = QuantumRegister(3)
Expand All @@ -106,22 +102,18 @@ def test_bell_3_qubits(self):
bell.cx(q3[0], q3[1])
bell.cx(q3[1], q3[2])

rho_cvx, rho_mle, psi = run_circuit_and_tomography(bell, q3)
F_bell_cvx = state_fidelity(psi, rho_cvx, validate=False)
self.assertAlmostEqual(F_bell_cvx, 1, places=1)
F_bell_mle = state_fidelity(psi, rho_mle, validate=False)
self.assertAlmostEqual(F_bell_mle, 1, places=1)
rho, psi = run_circuit_and_tomography(bell, q3, self.method)
F_bell = state_fidelity(psi, rho, validate=False)
self.assertAlmostEqual(F_bell, 1, places=1)

def test_complex_1_qubit_circuit(self):
q = QuantumRegister(1)
circ = QuantumCircuit(q)
circ.u3(1, 1, 1, q[0])

rho_cvx, rho_mle, psi = run_circuit_and_tomography(circ, q)
F_bell_cvx = state_fidelity(psi, rho_cvx, validate=False)
self.assertAlmostEqual(F_bell_cvx, 1, places=1)
F_bell_mle = state_fidelity(psi, rho_mle, validate=False)
self.assertAlmostEqual(F_bell_mle, 1, places=1)
rho, psi = run_circuit_and_tomography(circ, q, self.method)
F_bell = state_fidelity(psi, rho, validate=False)
self.assertAlmostEqual(F_bell, 1, places=1)

def test_complex_3_qubit_circuit(self):
def rand_angles():
Expand All @@ -133,11 +125,16 @@ def rand_angles():
for j in range(3):
circ.u3(*rand_angles(), q[j])

rho_cvx, rho_mle, psi = run_circuit_and_tomography(circ, q)
F_bell_cvx = state_fidelity(psi, rho_cvx, validate=False)
self.assertAlmostEqual(F_bell_cvx, 1, places=1)
F_bell_mle = state_fidelity(psi, rho_mle, validate=False)
self.assertAlmostEqual(F_bell_mle, 1, places=1)
rho, psi = run_circuit_and_tomography(circ, q, self.method)
F_bell = state_fidelity(psi, rho, validate=False)
self.assertAlmostEqual(F_bell, 1, places=1)


@unittest.skipUnless(cvx_fit._HAS_CVX, 'cvxpy is required to run this test')
class TestStateTomographyCVX(TestStateTomography):
def setUp(self):
super().setUp()
self.method = 'cvx'


if __name__ == '__main__':
Expand Down
9 changes: 9 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ commands =
pip check
stestr run {posargs}

[testenv:no-opt]
deps =
qiskit-aer
ddt>=1.2.0,!=1.4.0
stestr>=2.5.0
commands =
pip check
stestr run {posargs}

[testenv:lint]
basepython = python3
deps =
Expand Down