qiskit 1.2.0rc1__cp38-abi3-macosx_10_9_universal2.whl → 1.2.2__cp38-abi3-macosx_10_9_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/__init__.py +15 -2
- qiskit/circuit/library/basis_change/qft.py +3 -1
- qiskit/circuit/library/data_preparation/initializer.py +5 -2
- qiskit/circuit/library/data_preparation/state_preparation.py +2 -2
- qiskit/circuit/library/pauli_evolution.py +1 -0
- qiskit/circuit/library/standard_gates/__init__.py +32 -25
- qiskit/circuit/quantumcircuit.py +43 -18
- qiskit/compiler/transpiler.py +1 -1
- qiskit/dagcircuit/dagcircuit.py +1 -1
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +9 -1
- qiskit/providers/basic_provider/basic_simulator.py +1 -1
- qiskit/providers/fake_provider/fake_openpulse_2q.py +3 -3
- qiskit/providers/fake_provider/fake_openpulse_3q.py +2 -3
- qiskit/providers/fake_provider/fake_pulse_backend.py +2 -1
- qiskit/providers/fake_provider/fake_qasm_backend.py +2 -1
- qiskit/providers/fake_provider/generic_backend_v2.py +434 -18
- qiskit/providers/models/__init__.py +47 -21
- qiskit/pulse/builder.py +16 -7
- qiskit/pulse/instructions/directives.py +5 -0
- qiskit/pulse/library/symbolic_pulses.py +4 -3
- qiskit/pulse/schedule.py +5 -9
- qiskit/pulse/transforms/alignments.py +3 -1
- qiskit/pulse/transforms/dag.py +7 -0
- qiskit/qasm2/parse.py +29 -0
- qiskit/qasm3/exporter.py +20 -7
- qiskit/qpy/__init__.py +1 -1
- qiskit/quantum_info/operators/operator.py +24 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +2 -0
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +6 -1
- qiskit/synthesis/clifford/clifford_decompose_bm.py +1 -1
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +1 -1
- qiskit/synthesis/linear/cnot_synth.py +1 -1
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +2 -1
- qiskit/synthesis/permutation/permutation_full.py +2 -2
- qiskit/synthesis/permutation/permutation_lnn.py +3 -1
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +2 -2
- qiskit/transpiler/__init__.py +6 -1
- qiskit/transpiler/instruction_durations.py +4 -0
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +2 -1
- qiskit/transpiler/passes/calibration/rx_builder.py +1 -1
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +7 -1
- qiskit/transpiler/passes/optimization/elide_permutations.py +2 -2
- qiskit/transpiler/passes/optimization/hoare_opt.py +12 -8
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +16 -20
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +9 -3
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +3 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +16 -6
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +1 -1
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +12 -55
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +9 -0
- qiskit/utils/optionals.py +173 -150
- qiskit/visualization/bloch.py +44 -1
- qiskit/visualization/dag_visualization.py +10 -3
- qiskit/visualization/gate_map.py +28 -6
- qiskit/visualization/pass_manager_visualization.py +3 -14
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/METADATA +20 -20
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/RECORD +67 -67
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/WHEEL +1 -1
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/entry_points.txt +0 -0
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/top_level.txt +0 -0
@@ -968,6 +968,10 @@ class QFTSynthesisFull(HighLevelSynthesisPlugin):
|
|
968
968
|
This plugin name is :``qft.full`` which can be used as the key on
|
969
969
|
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
970
970
|
|
971
|
+
Note that the plugin mechanism is not applied if the gate is called ``qft`` but
|
972
|
+
is not an instance of ``QFTGate``. This allows users to create custom gates with
|
973
|
+
name ``qft``.
|
974
|
+
|
971
975
|
The plugin supports the following additional options:
|
972
976
|
|
973
977
|
* reverse_qubits (bool): Whether to synthesize the "QFT" operation (if ``False``,
|
@@ -995,10 +999,11 @@ class QFTSynthesisFull(HighLevelSynthesisPlugin):
|
|
995
999
|
|
996
1000
|
def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
|
997
1001
|
"""Run synthesis for the given QFTGate."""
|
1002
|
+
|
1003
|
+
# Even though the gate is called "qft", it's not a QFTGate,
|
1004
|
+
# and we should not synthesize it using the plugin.
|
998
1005
|
if not isinstance(high_level_object, QFTGate):
|
999
|
-
|
1000
|
-
"The synthesis plugin 'qft.full` only applies to objects of type QFTGate."
|
1001
|
-
)
|
1006
|
+
return None
|
1002
1007
|
|
1003
1008
|
reverse_qubits = options.get("reverse_qubits", False)
|
1004
1009
|
approximation_degree = options.get("approximation_degree", 0)
|
@@ -1023,6 +1028,10 @@ class QFTSynthesisLine(HighLevelSynthesisPlugin):
|
|
1023
1028
|
This plugin name is :``qft.line`` which can be used as the key on
|
1024
1029
|
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
|
1025
1030
|
|
1031
|
+
Note that the plugin mechanism is not applied if the gate is called ``qft`` but
|
1032
|
+
is not an instance of ``QFTGate``. This allows users to create custom gates with
|
1033
|
+
name ``qft``.
|
1034
|
+
|
1026
1035
|
The plugin supports the following additional options:
|
1027
1036
|
|
1028
1037
|
* reverse_qubits (bool): Whether to synthesize the "QFT" operation (if ``False``,
|
@@ -1047,10 +1056,11 @@ class QFTSynthesisLine(HighLevelSynthesisPlugin):
|
|
1047
1056
|
|
1048
1057
|
def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
|
1049
1058
|
"""Run synthesis for the given QFTGate."""
|
1059
|
+
|
1060
|
+
# Even though the gate is called "qft", it's not a QFTGate,
|
1061
|
+
# and we should not synthesize it using the plugin.
|
1050
1062
|
if not isinstance(high_level_object, QFTGate):
|
1051
|
-
|
1052
|
-
"The synthesis plugin 'qft.line` only applies to objects of type QFTGate."
|
1053
|
-
)
|
1063
|
+
return None
|
1054
1064
|
|
1055
1065
|
reverse_qubits = options.get("reverse_qubits", False)
|
1056
1066
|
approximation_degree = options.get("approximation_degree", 0)
|
@@ -54,7 +54,7 @@ from qiskit.circuit.library.standard_gates import (
|
|
54
54
|
from qiskit.converters import circuit_to_dag, dag_to_circuit
|
55
55
|
from qiskit.dagcircuit.dagcircuit import DAGCircuit, DAGOpNode
|
56
56
|
from qiskit.exceptions import QiskitError
|
57
|
-
from qiskit.providers.models import BackendProperties
|
57
|
+
from qiskit.providers.models.backendproperties import BackendProperties
|
58
58
|
from qiskit.quantum_info import Operator
|
59
59
|
from qiskit.synthesis.one_qubit import one_qubit_decompose
|
60
60
|
from qiskit.synthesis.two_qubit.xx_decompose import XXDecomposer, XXEmbodiments
|
@@ -14,7 +14,6 @@
|
|
14
14
|
|
15
15
|
import os
|
16
16
|
|
17
|
-
from qiskit.circuit import Instruction
|
18
17
|
from qiskit.transpiler.passes.optimization.split_2q_unitaries import Split2QUnitaries
|
19
18
|
from qiskit.transpiler.passmanager import PassManager
|
20
19
|
from qiskit.transpiler.exceptions import TranspilerError
|
@@ -66,7 +65,6 @@ from qiskit.circuit.library.standard_gates import (
|
|
66
65
|
CYGate,
|
67
66
|
SXGate,
|
68
67
|
SXdgGate,
|
69
|
-
get_standard_gate_name_mapping,
|
70
68
|
)
|
71
69
|
from qiskit.utils.parallel import CPU_COUNT
|
72
70
|
from qiskit import user_config
|
@@ -152,7 +150,8 @@ class DefaultInitPassManager(PassManagerStagePlugin):
|
|
152
150
|
pass_manager_config.unitary_synthesis_plugin_config,
|
153
151
|
pass_manager_config.hls_config,
|
154
152
|
)
|
155
|
-
|
153
|
+
if pass_manager_config.routing_method != "none":
|
154
|
+
init.append(ElidePermutations())
|
156
155
|
init.append(RemoveDiagonalGatesBeforeMeasure())
|
157
156
|
init.append(
|
158
157
|
InverseCancellation(
|
@@ -173,58 +172,16 @@ class DefaultInitPassManager(PassManagerStagePlugin):
|
|
173
172
|
)
|
174
173
|
)
|
175
174
|
init.append(CommutativeCancellation())
|
176
|
-
|
177
|
-
|
178
|
-
#
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
True if at least one operation in `ops` is not discrete, False otherwise
|
187
|
-
"""
|
188
|
-
found_one_continuous_gate = False
|
189
|
-
for op in ops:
|
190
|
-
if isinstance(op, str):
|
191
|
-
if op in _discrete_skipped_ops:
|
192
|
-
continue
|
193
|
-
op = stdgates.get(op, None)
|
194
|
-
|
195
|
-
if op is not None and op.name in _discrete_skipped_ops:
|
196
|
-
continue
|
197
|
-
|
198
|
-
if op is None or not isinstance(op, Instruction):
|
199
|
-
return False
|
200
|
-
|
201
|
-
if len(op.params) > 0:
|
202
|
-
found_one_continuous_gate = True
|
203
|
-
return found_one_continuous_gate
|
204
|
-
|
205
|
-
target = pass_manager_config.target
|
206
|
-
basis = pass_manager_config.basis_gates
|
207
|
-
# consolidate gates before routing if the user did not specify a discrete basis gate, i.e.
|
208
|
-
# * no target or basis gate set has been specified
|
209
|
-
# * target has been specified, and we have one non-discrete gate in the target's spec
|
210
|
-
# * basis gates have been specified, and we have one non-discrete gate in that set
|
211
|
-
do_consolidate_blocks_init = target is None and basis is None
|
212
|
-
do_consolidate_blocks_init |= target is not None and _is_one_op_non_discrete(
|
213
|
-
target.operations
|
214
|
-
)
|
215
|
-
do_consolidate_blocks_init |= basis is not None and _is_one_op_non_discrete(basis)
|
216
|
-
|
217
|
-
if do_consolidate_blocks_init:
|
218
|
-
init.append(Collect2qBlocks())
|
219
|
-
init.append(ConsolidateBlocks())
|
220
|
-
# If approximation degree is None that indicates a request to approximate up to the
|
221
|
-
# error rates in the target. However, in the init stage we don't yet know the target
|
222
|
-
# qubits being used to figure out the fidelity so just use the default fidelity parameter
|
223
|
-
# in this case.
|
224
|
-
if pass_manager_config.approximation_degree is not None:
|
225
|
-
init.append(Split2QUnitaries(pass_manager_config.approximation_degree))
|
226
|
-
else:
|
227
|
-
init.append(Split2QUnitaries())
|
175
|
+
init.append(Collect2qBlocks())
|
176
|
+
init.append(ConsolidateBlocks())
|
177
|
+
# If approximation degree is None that indicates a request to approximate up to the
|
178
|
+
# error rates in the target. However, in the init stage we don't yet know the target
|
179
|
+
# qubits being used to figure out the fidelity so just use the default fidelity parameter
|
180
|
+
# in this case.
|
181
|
+
if pass_manager_config.approximation_degree is not None:
|
182
|
+
init.append(Split2QUnitaries(pass_manager_config.approximation_degree))
|
183
|
+
else:
|
184
|
+
init.append(Split2QUnitaries())
|
228
185
|
else:
|
229
186
|
raise TranspilerError(f"Invalid optimization level {optimization_level}")
|
230
187
|
return init
|
@@ -343,6 +343,7 @@ def generate_preset_pass_manager(
|
|
343
343
|
# Parse non-target dependent pm options
|
344
344
|
initial_layout = _parse_initial_layout(initial_layout)
|
345
345
|
approximation_degree = _parse_approximation_degree(approximation_degree)
|
346
|
+
seed_transpiler = _parse_seed_transpiler(seed_transpiler)
|
346
347
|
|
347
348
|
pm_options = {
|
348
349
|
"target": target,
|
@@ -516,3 +517,11 @@ def _parse_approximation_degree(approximation_degree):
|
|
516
517
|
if approximation_degree < 0.0 or approximation_degree > 1.0:
|
517
518
|
raise TranspilerError("Approximation degree must be in [0.0, 1.0]")
|
518
519
|
return approximation_degree
|
520
|
+
|
521
|
+
|
522
|
+
def _parse_seed_transpiler(seed_transpiler):
|
523
|
+
if seed_transpiler is None:
|
524
|
+
return None
|
525
|
+
if not isinstance(seed_transpiler, int) or seed_transpiler < 0:
|
526
|
+
raise ValueError("Expected non-negative integer as seed for transpiler.")
|
527
|
+
return seed_transpiler
|
qiskit/utils/optionals.py
CHANGED
@@ -25,172 +25,195 @@ Available Testers
|
|
25
25
|
Qiskit Components
|
26
26
|
-----------------
|
27
27
|
|
28
|
-
..
|
29
|
-
:widths: 25 75
|
28
|
+
.. py:data:: HAS_AER
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
the quantum circuits constructed within Qiskit.
|
30
|
+
`Qiskit Aer <https://qiskit.github.io/qiskit-aer/>` provides high-performance simulators for
|
31
|
+
the quantum circuits constructed within Qiskit.
|
34
32
|
|
35
|
-
|
36
|
-
- The :mod:`Qiskit IBMQ Provider <qiskit.providers.ibmq>` is used for accessing IBM Quantum
|
37
|
-
hardware in the IBM cloud.
|
33
|
+
.. py:data:: HAS_IBMQ
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
characterization, and error correction.
|
35
|
+
The :mod:`Qiskit IBMQ Provider <qiskit.providers.ibmq>` is used for accessing IBM Quantum
|
36
|
+
hardware in the IBM cloud.
|
42
37
|
|
43
|
-
|
44
|
-
|
45
|
-
|
38
|
+
.. py:data:: HAS_IGNIS
|
39
|
+
|
40
|
+
:mod:`Qiskit Ignis <qiskit.ignis>` provides tools for quantum hardware verification, noise
|
41
|
+
characterization, and error correction.
|
42
|
+
|
43
|
+
.. py:data:: HAS_TOQM
|
44
|
+
|
45
|
+
`Qiskit TOQM <https://github.com/qiskit-toqm/qiskit-toqm>`__ provides transpiler passes
|
46
|
+
for the `Time-optimal Qubit mapping algorithm <https://doi.org/10.1145/3445814.3446706>`__.
|
46
47
|
|
47
48
|
|
48
49
|
External Python Libraries
|
49
50
|
-------------------------
|
50
51
|
|
51
|
-
..
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
52
|
+
.. py:data:: HAS_CONSTRAINT
|
53
|
+
|
54
|
+
`python-constraint <https://github.com/python-constraint/python-constraint>`__ is a
|
55
|
+
constraint satisfaction problem solver, used in the :class:`~.CSPLayout` transpiler pass.
|
56
|
+
|
57
|
+
.. py:data:: HAS_CPLEX
|
58
|
+
|
59
|
+
The `IBM CPLEX Optimizer <https://www.ibm.com/analytics/cplex-optimizer>`__ is a
|
60
|
+
high-performance mathematical programming solver for linear, mixed-integer and quadratic
|
61
|
+
programming. This is no longer by Qiskit, but it weas historically and the optional
|
62
|
+
remains for backwards compatibility.
|
63
|
+
|
64
|
+
.. py:data:: HAS_CVXPY
|
65
|
+
|
66
|
+
`CVXPY <https://www.cvxpy.org/>`__ is a Python package for solving convex optimization
|
67
|
+
problems. It is required for calculating diamond norms with
|
68
|
+
:func:`.quantum_info.diamond_norm`.
|
69
|
+
|
70
|
+
.. py:data:: HAS_DOCPLEX
|
71
|
+
|
72
|
+
`IBM Decision Optimization CPLEX Modelling
|
73
|
+
<http://ibmdecisionoptimization.github.io/docplex-doc/>`__ is a library for prescriptive
|
74
|
+
analysis. Like CPLEX, this is no longer by Qiskit, but it weas historically and the
|
75
|
+
optional remains for backwards compatibility.
|
76
|
+
|
77
|
+
.. py:data:: HAS_FIXTURES
|
78
|
+
|
79
|
+
The test suite has additional features that are available if the optional `fixtures
|
80
|
+
<https://launchpad.net/python-fixtures>`__ module is installed. This generally also needs
|
81
|
+
:data:`HAS_TESTTOOLS` as well. This is generally only needed for Qiskit developers.
|
82
|
+
|
83
|
+
.. py:data:: HAS_IPYTHON
|
84
|
+
|
85
|
+
If `the IPython kernel <https://ipython.org/>`__ is available, certain additional
|
86
|
+
visualizations and line magics are made available.
|
87
|
+
|
88
|
+
.. py:data:: HAS_IPYWIDGETS
|
89
|
+
|
90
|
+
Monitoring widgets for jobs running on external backends can be provided if `ipywidgets
|
91
|
+
<https://ipywidgets.readthedocs.io/en/latest/>`__ is available.
|
92
|
+
|
93
|
+
.. py:data:: HAS_JAX
|
94
|
+
|
95
|
+
Some methods of gradient calculation within :mod:`.opflow.gradients` require `JAX
|
96
|
+
<https://github.com/google/jax>`__ for autodifferentiation.
|
97
|
+
|
98
|
+
.. py:data:: HAS_JUPYTER
|
99
|
+
|
100
|
+
Some of the tests require a complete `Jupyter <https://jupyter.org/>`__ installation to test
|
101
|
+
interactivity features.
|
102
|
+
|
103
|
+
.. py:data:: HAS_MATPLOTLIB
|
104
|
+
|
105
|
+
Qiskit provides several visualization tools in the :mod:`.visualization` module.
|
106
|
+
Almost all of these are built using `Matplotlib <https://matplotlib.org/>`__, which must
|
107
|
+
be installed in order to use them.
|
108
|
+
|
109
|
+
.. py:data:: HAS_NETWORKX
|
110
|
+
|
111
|
+
No longer used by Qiskit. Internally, Qiskit now uses the high-performance `rustworkx
|
112
|
+
<https://github.com/Qiskit/rustworkx>`__ library as a core dependency, and during the
|
113
|
+
change-over period, it was sometimes convenient to convert things into the Python-only
|
114
|
+
`NetworkX <https://networkx.org/>`__ format. Some tests of application modules, such as
|
115
|
+
`Qiskit Nature <https://qiskit-community.github.io/qiskit-nature/>`__ still use NetworkX.
|
116
|
+
|
117
|
+
.. py:data:: HAS_NLOPT
|
118
|
+
|
119
|
+
`NLopt <https://nlopt.readthedocs.io/en/latest/>`__ is a nonlinear optimization library,
|
120
|
+
used by the global optimizers in the :mod:`.algorithms.optimizers` module.
|
121
|
+
|
122
|
+
.. py:data:: HAS_PIL
|
123
|
+
|
124
|
+
PIL is a Python image-manipulation library. Qiskit actually uses the `pillow
|
125
|
+
<https://pillow.readthedocs.io/en/stable/>`__ fork of PIL if it is available when generating
|
126
|
+
certain visualizations, for example of both :class:`.QuantumCircuit` and
|
127
|
+
:class:`.DAGCircuit` in certain modes.
|
128
|
+
|
129
|
+
.. py:data:: HAS_PYDOT
|
130
|
+
|
131
|
+
For some graph visualizations, Qiskit uses `pydot <https://github.com/pydot/pydot>`__ as an
|
132
|
+
interface to GraphViz (see :data:`HAS_GRAPHVIZ`).
|
133
|
+
|
134
|
+
.. py:data:: HAS_PYGMENTS
|
135
|
+
|
136
|
+
Pygments is a code highlighter and formatter used by many environments that involve rich
|
137
|
+
display of code blocks, including Sphinx and Jupyter. Qiskit uses this when producing rich
|
138
|
+
output for these environments.
|
139
|
+
|
140
|
+
.. py:data:: HAS_PYLATEX
|
141
|
+
|
142
|
+
Various LaTeX-based visualizations, especially the circuit drawers, need access to the
|
143
|
+
`pylatexenc <https://github.com/phfaist/pylatexenc>`__ project to work correctly.
|
144
|
+
|
145
|
+
.. py:data:: HAS_QASM3_IMPORT
|
146
|
+
|
147
|
+
The functions :func:`.qasm3.load` and :func:`.qasm3.loads` for importing OpenQASM 3 programs
|
148
|
+
into :class:`.QuantumCircuit` instances use `an external importer package
|
149
|
+
<https://qiskit.github.io/qiskit-qasm3-import>`__.
|
150
|
+
|
151
|
+
.. py:data:: HAS_SEABORN
|
152
|
+
|
153
|
+
Qiskit provides several visualization tools in the :mod:`.visualization` module. Some
|
154
|
+
of these are built using `Seaborn <https://seaborn.pydata.org/>`__, which must be installed
|
155
|
+
in order to use them.
|
156
|
+
|
157
|
+
.. py:data:: HAS_SKLEARN
|
158
|
+
|
159
|
+
Some of the gradient functions in :mod:`.opflow.gradients` use regularisation methods from
|
160
|
+
`Scikit Learn <https://scikit-learn.org/stable/>`__.
|
161
|
+
|
162
|
+
.. py:data:: HAS_SKQUANT
|
163
|
+
|
164
|
+
Some of the optimisers in :mod:`.algorithms.optimizers` are based on those found in `Scikit
|
165
|
+
Quant <https://github.com/scikit-quant/scikit-quant>`__, which must be installed to use
|
166
|
+
them.
|
167
|
+
|
168
|
+
.. py:data:: HAS_SQSNOBFIT
|
169
|
+
|
170
|
+
`SQSnobFit <https://pypi.org/project/SQSnobFit/>`__ is a library for the "stable noisy
|
171
|
+
optimization by branch and fit" algorithm. It is used by the :class:`.SNOBFIT` optimizer.
|
172
|
+
|
173
|
+
.. py:data:: HAS_SYMENGINE
|
174
|
+
|
175
|
+
`Symengine <https://github.com/symengine/symengine>`__ is a fast C++ backend for the
|
176
|
+
symbolic-manipulation library `Sympy <https://www.sympy.org/en/index.html>`__. Qiskit uses
|
177
|
+
special methods from Symengine to accelerate its handling of
|
178
|
+
:class:`~.circuit.Parameter`\\ s if available.
|
179
|
+
|
180
|
+
.. py:data:: HAS_TESTTOOLS
|
181
|
+
|
182
|
+
Qiskit's test suite has more advanced functionality available if the optional
|
183
|
+
`testtools <https://pypi.org/project/testtools/>`__ library is installed. This is generally
|
184
|
+
only needed for Qiskit developers.
|
185
|
+
|
186
|
+
.. py:data:: HAS_TWEEDLEDUM
|
187
|
+
|
188
|
+
`Tweedledum <https://github.com/boschmitt/tweedledum>`__ is an extension library for
|
189
|
+
synthesis and optimization of circuits that may involve classical oracles. Qiskit's
|
190
|
+
:class:`.PhaseOracle` uses this, which is used in turn by amplification algorithms via
|
191
|
+
the :class:`.AmplificationProblem`.
|
192
|
+
|
193
|
+
.. py:data:: HAS_Z3
|
194
|
+
|
195
|
+
`Z3 <https://github.com/Z3Prover/z3>`__ is a theorem prover, used in the
|
196
|
+
:class:`.CrosstalkAdaptiveSchedule` and :class:`.HoareOptimizer` transpiler passes.
|
174
197
|
|
175
198
|
External Command-Line Tools
|
176
199
|
---------------------------
|
177
200
|
|
178
|
-
..
|
179
|
-
|
201
|
+
.. py:data:: HAS_GRAPHVIZ
|
202
|
+
|
203
|
+
For some graph visualizations, Qiskit uses the `GraphViz <https://graphviz.org/>`__
|
204
|
+
visualization tool via its ``pydot`` interface (see :data:`HAS_PYDOT`).
|
205
|
+
|
206
|
+
.. py:data:: HAS_PDFLATEX
|
180
207
|
|
181
|
-
|
182
|
-
|
183
|
-
|
208
|
+
Visualization tools that use LaTeX in their output, such as the circuit drawers, require
|
209
|
+
``pdflatex`` to be available. You will generally need to ensure that you have a working
|
210
|
+
LaTeX installation available, and the ``qcircuit.tex`` package.
|
184
211
|
|
185
|
-
|
186
|
-
- Visualization tools that use LaTeX in their output, such as the circuit drawers, require
|
187
|
-
``pdflatex`` to be available. You will generally need to ensure that you have a working
|
188
|
-
LaTeX installation available, and the ``qcircuit.tex`` package.
|
212
|
+
.. py:data:: HAS_PDFTOCAIRO
|
189
213
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
<https://poppler.freedesktop.org/>`__.
|
214
|
+
Visualization tools that convert LaTeX-generated files into rasterized images use the
|
215
|
+
``pdftocairo`` tool. This is part of the `Poppler suite of PDF tools
|
216
|
+
<https://poppler.freedesktop.org/>`__.
|
194
217
|
|
195
218
|
|
196
219
|
Lazy Checker Classes
|
qiskit/visualization/bloch.py
CHANGED
@@ -50,6 +50,7 @@ __all__ = ["Bloch"]
|
|
50
50
|
|
51
51
|
import math
|
52
52
|
import os
|
53
|
+
import re
|
53
54
|
import numpy as np
|
54
55
|
import matplotlib
|
55
56
|
import matplotlib.pyplot as plt
|
@@ -60,6 +61,47 @@ from mpl_toolkits.mplot3d.art3d import Patch3D
|
|
60
61
|
from .utils import matplotlib_close_if_inline
|
61
62
|
|
62
63
|
|
64
|
+
# This version pattern is taken from the pypa packaging project:
|
65
|
+
# https://github.com/pypa/packaging/blob/21.3/packaging/version.py#L223-L254
|
66
|
+
# which is dual licensed Apache 2.0 and BSD see the source for the original
|
67
|
+
# authors and other details
|
68
|
+
VERSION_PATTERN = (
|
69
|
+
"^"
|
70
|
+
+ r"""
|
71
|
+
v?
|
72
|
+
(?:
|
73
|
+
(?:(?P<epoch>[0-9]+)!)? # epoch
|
74
|
+
(?P<release>[0-9]+(?:\.[0-9]+)*) # release segment
|
75
|
+
(?P<pre> # pre-release
|
76
|
+
[-_\.]?
|
77
|
+
(?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
|
78
|
+
[-_\.]?
|
79
|
+
(?P<pre_n>[0-9]+)?
|
80
|
+
)?
|
81
|
+
(?P<post> # post release
|
82
|
+
(?:-(?P<post_n1>[0-9]+))
|
83
|
+
|
|
84
|
+
(?:
|
85
|
+
[-_\.]?
|
86
|
+
(?P<post_l>post|rev|r)
|
87
|
+
[-_\.]?
|
88
|
+
(?P<post_n2>[0-9]+)?
|
89
|
+
)
|
90
|
+
)?
|
91
|
+
(?P<dev> # dev release
|
92
|
+
[-_\.]?
|
93
|
+
(?P<dev_l>dev)
|
94
|
+
[-_\.]?
|
95
|
+
(?P<dev_n>[0-9]+)?
|
96
|
+
)?
|
97
|
+
)
|
98
|
+
(?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
|
99
|
+
"""
|
100
|
+
+ "$"
|
101
|
+
)
|
102
|
+
VERSION_PATTERN_REGEX = re.compile(VERSION_PATTERN, re.VERBOSE | re.IGNORECASE)
|
103
|
+
|
104
|
+
|
63
105
|
class Arrow3D(Patch3D, FancyArrowPatch):
|
64
106
|
"""Makes a fancy arrow"""
|
65
107
|
|
@@ -419,7 +461,8 @@ class Bloch:
|
|
419
461
|
self.fig = plt.figure(figsize=self.figsize)
|
420
462
|
|
421
463
|
if not self._ext_axes:
|
422
|
-
|
464
|
+
version_match = VERSION_PATTERN_REGEX.search(matplotlib.__version__)
|
465
|
+
if tuple(int(x) for x in version_match.group("release").split(".")) >= (3, 4, 0):
|
423
466
|
self.axes = Axes3D(
|
424
467
|
self.fig, azim=self.view[0], elev=self.view[1], auto_add_to_figure=False
|
425
468
|
)
|
@@ -174,10 +174,13 @@ def dag_drawer(dag, scale=0.7, filename=None, style="color"):
|
|
174
174
|
label = register_bit_labels.get(
|
175
175
|
node.wire, f"q_{dag.find_bit(node.wire).index}"
|
176
176
|
)
|
177
|
-
|
177
|
+
elif isinstance(node.wire, Clbit):
|
178
178
|
label = register_bit_labels.get(
|
179
179
|
node.wire, f"c_{dag.find_bit(node.wire).index}"
|
180
180
|
)
|
181
|
+
else:
|
182
|
+
label = str(node.wire.name)
|
183
|
+
|
181
184
|
n["label"] = label
|
182
185
|
n["color"] = "black"
|
183
186
|
n["style"] = "filled"
|
@@ -187,10 +190,12 @@ def dag_drawer(dag, scale=0.7, filename=None, style="color"):
|
|
187
190
|
label = register_bit_labels.get(
|
188
191
|
node.wire, f"q[{dag.find_bit(node.wire).index}]"
|
189
192
|
)
|
190
|
-
|
193
|
+
elif isinstance(node.wire, Clbit):
|
191
194
|
label = register_bit_labels.get(
|
192
195
|
node.wire, f"c[{dag.find_bit(node.wire).index}]"
|
193
196
|
)
|
197
|
+
else:
|
198
|
+
label = str(node.wire.name)
|
194
199
|
n["label"] = label
|
195
200
|
n["color"] = "black"
|
196
201
|
n["style"] = "filled"
|
@@ -203,8 +208,10 @@ def dag_drawer(dag, scale=0.7, filename=None, style="color"):
|
|
203
208
|
e = {}
|
204
209
|
if isinstance(edge, Qubit):
|
205
210
|
label = register_bit_labels.get(edge, f"q_{dag.find_bit(edge).index}")
|
206
|
-
|
211
|
+
elif isinstance(edge, Clbit):
|
207
212
|
label = register_bit_labels.get(edge, f"c_{dag.find_bit(edge).index}")
|
213
|
+
else:
|
214
|
+
label = str(edge.name)
|
208
215
|
e["label"] = label
|
209
216
|
return e
|
210
217
|
|