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.
Files changed (67) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/_accelerate.abi3.so +0 -0
  3. qiskit/circuit/__init__.py +15 -2
  4. qiskit/circuit/library/basis_change/qft.py +3 -1
  5. qiskit/circuit/library/data_preparation/initializer.py +5 -2
  6. qiskit/circuit/library/data_preparation/state_preparation.py +2 -2
  7. qiskit/circuit/library/pauli_evolution.py +1 -0
  8. qiskit/circuit/library/standard_gates/__init__.py +32 -25
  9. qiskit/circuit/quantumcircuit.py +43 -18
  10. qiskit/compiler/transpiler.py +1 -1
  11. qiskit/dagcircuit/dagcircuit.py +1 -1
  12. qiskit/primitives/base/base_estimator.py +2 -2
  13. qiskit/primitives/containers/data_bin.py +9 -1
  14. qiskit/providers/basic_provider/basic_simulator.py +1 -1
  15. qiskit/providers/fake_provider/fake_openpulse_2q.py +3 -3
  16. qiskit/providers/fake_provider/fake_openpulse_3q.py +2 -3
  17. qiskit/providers/fake_provider/fake_pulse_backend.py +2 -1
  18. qiskit/providers/fake_provider/fake_qasm_backend.py +2 -1
  19. qiskit/providers/fake_provider/generic_backend_v2.py +434 -18
  20. qiskit/providers/models/__init__.py +47 -21
  21. qiskit/pulse/builder.py +16 -7
  22. qiskit/pulse/instructions/directives.py +5 -0
  23. qiskit/pulse/library/symbolic_pulses.py +4 -3
  24. qiskit/pulse/schedule.py +5 -9
  25. qiskit/pulse/transforms/alignments.py +3 -1
  26. qiskit/pulse/transforms/dag.py +7 -0
  27. qiskit/qasm2/parse.py +29 -0
  28. qiskit/qasm3/exporter.py +20 -7
  29. qiskit/qpy/__init__.py +1 -1
  30. qiskit/quantum_info/operators/operator.py +24 -0
  31. qiskit/quantum_info/operators/symplectic/pauli.py +2 -0
  32. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +6 -1
  33. qiskit/synthesis/clifford/clifford_decompose_bm.py +1 -1
  34. qiskit/synthesis/clifford/clifford_decompose_greedy.py +1 -1
  35. qiskit/synthesis/linear/cnot_synth.py +1 -1
  36. qiskit/synthesis/one_qubit/one_qubit_decompose.py +2 -1
  37. qiskit/synthesis/permutation/permutation_full.py +2 -2
  38. qiskit/synthesis/permutation/permutation_lnn.py +3 -1
  39. qiskit/synthesis/two_qubit/two_qubit_decompose.py +2 -2
  40. qiskit/transpiler/__init__.py +6 -1
  41. qiskit/transpiler/instruction_durations.py +4 -0
  42. qiskit/transpiler/passes/__init__.py +2 -0
  43. qiskit/transpiler/passes/basis/basis_translator.py +2 -1
  44. qiskit/transpiler/passes/calibration/rx_builder.py +1 -1
  45. qiskit/transpiler/passes/optimization/__init__.py +1 -0
  46. qiskit/transpiler/passes/optimization/consolidate_blocks.py +7 -1
  47. qiskit/transpiler/passes/optimization/elide_permutations.py +2 -2
  48. qiskit/transpiler/passes/optimization/hoare_opt.py +12 -8
  49. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +16 -20
  50. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +1 -1
  51. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +9 -3
  52. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +3 -0
  53. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +16 -6
  54. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +1 -1
  55. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +12 -55
  56. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +9 -0
  57. qiskit/utils/optionals.py +173 -150
  58. qiskit/visualization/bloch.py +44 -1
  59. qiskit/visualization/dag_visualization.py +10 -3
  60. qiskit/visualization/gate_map.py +28 -6
  61. qiskit/visualization/pass_manager_visualization.py +3 -14
  62. {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/METADATA +20 -20
  63. {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/RECORD +67 -67
  64. {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/WHEEL +1 -1
  65. {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/LICENSE.txt +0 -0
  66. {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/entry_points.txt +0 -0
  67. {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
- raise TranspilerError(
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
- raise TranspilerError(
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
- init.append(ElidePermutations())
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
- # skip peephole optimization before routing if target basis gate set is discrete,
177
- # i.e. only consists of Cliffords that an user might want to keep
178
- # use rz, sx, x, cx as basis, rely on physical optimziation to fix everything later one
179
- stdgates = get_standard_gate_name_mapping()
180
-
181
- def _is_one_op_non_discrete(ops):
182
- """Checks if one operation in `ops` is not discrete, i.e. is parameterizable
183
- Args:
184
- ops (List(Operation)): list of operations to check
185
- Returns
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
- .. list-table::
29
- :widths: 25 75
28
+ .. py:data:: HAS_AER
30
29
 
31
- * - .. py:data:: HAS_AER
32
- - `Qiskit Aer <https://qiskit.github.io/qiskit-aer/>` provides high-performance simulators for
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
- * - .. py:data:: HAS_IBMQ
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
- * - .. py:data:: HAS_IGNIS
40
- - :mod:`Qiskit Ignis <qiskit.ignis>` provides tools for quantum hardware verification, noise
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
- * - .. py:data:: HAS_TOQM
44
- - `Qiskit TOQM <https://github.com/qiskit-toqm/qiskit-toqm>`__ provides transpiler passes
45
- for the `Time-optimal Qubit mapping algorithm <https://doi.org/10.1145/3445814.3446706>`__.
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
- .. list-table::
52
- :widths: 25 75
53
-
54
- * - .. py:data:: HAS_CONSTRAINT
55
- - `python-constraint <https://github.com/python-constraint/python-constraint>`__ is a
56
- constraint satisfaction problem solver, used in the :class:`~.CSPLayout` transpiler pass.
57
-
58
- * - .. py:data:: HAS_CPLEX
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
- - `CVXPY <https://www.cvxpy.org/>`__ is a Python package for solving convex optimization
66
- problems. It is required for calculating diamond norms with
67
- :func:`.quantum_info.diamond_norm`.
68
-
69
- * - .. py:data:: HAS_DOCPLEX
70
- - `IBM Decision Optimization CPLEX Modelling
71
- <http://ibmdecisionoptimization.github.io/docplex-doc/>`__ is a library for prescriptive
72
- analysis. Like CPLEX, this is no longer by Qiskit, but it weas historically and the
73
- optional remains for backwards compatibility.
74
-
75
- * - .. py:data:: HAS_FIXTURES
76
- - The test suite has additional features that are available if the optional `fixtures
77
- <https://launchpad.net/python-fixtures>`__ module is installed. This generally also needs
78
- :data:`HAS_TESTTOOLS` as well. This is generally only needed for Qiskit developers.
79
-
80
- * - .. py:data:: HAS_IPYTHON
81
- - If `the IPython kernel <https://ipython.org/>`__ is available, certain additional
82
- visualizations and line magics are made available.
83
-
84
- * - .. py:data:: HAS_IPYWIDGETS
85
- - Monitoring widgets for jobs running on external backends can be provided if `ipywidgets
86
- <https://ipywidgets.readthedocs.io/en/latest/>`__ is available.
87
-
88
- * - .. py:data:: HAS_JAX
89
- - Some methods of gradient calculation within :mod:`.opflow.gradients` require `JAX
90
- <https://github.com/google/jax>`__ for autodifferentiation.
91
-
92
- * - .. py:data:: HAS_JUPYTER
93
- - Some of the tests require a complete `Jupyter <https://jupyter.org/>`__ installation to test
94
- interactivity features.
95
-
96
- * - .. py:data:: HAS_MATPLOTLIB
97
- - Qiskit provides several visualization tools in the :mod:`.visualization` module.
98
- Almost all of these are built using `Matplotlib <https://matplotlib.org/>`__, which must
99
- be installed in order to use them.
100
-
101
- * - .. py:data:: HAS_NETWORKX
102
- - No longer used by Qiskit. Internally, Qiskit now uses the high-performance `rustworkx
103
- <https://github.com/Qiskit/rustworkx>`__ library as a core dependency, and during the
104
- change-over period, it was sometimes convenient to convert things into the Python-only
105
- `NetworkX <https://networkx.org/>`__ format. Some tests of application modules, such as
106
- `Qiskit Nature <https://qiskit-community.github.io/qiskit-nature/>`__ still use NetworkX.
107
-
108
- * - .. py:data:: HAS_NLOPT
109
- - `NLopt <https://nlopt.readthedocs.io/en/latest/>`__ is a nonlinear optimization library,
110
- used by the global optimizers in the :mod:`.algorithms.optimizers` module.
111
-
112
- * - .. py:data:: HAS_PIL
113
- - PIL is a Python image-manipulation library. Qiskit actually uses the `pillow
114
- <https://pillow.readthedocs.io/en/stable/>`__ fork of PIL if it is available when generating
115
- certain visualizations, for example of both :class:`.QuantumCircuit` and
116
- :class:`.DAGCircuit` in certain modes.
117
-
118
- * - .. py:data:: HAS_PYDOT
119
- - For some graph visualizations, Qiskit uses `pydot <https://github.com/pydot/pydot>`__ as an
120
- interface to GraphViz (see :data:`HAS_GRAPHVIZ`).
121
-
122
- * - .. py:data:: HAS_PYGMENTS
123
- - Pygments is a code highlighter and formatter used by many environments that involve rich
124
- display of code blocks, including Sphinx and Jupyter. Qiskit uses this when producing rich
125
- output for these environments.
126
-
127
- * - .. py:data:: HAS_PYLATEX
128
- - Various LaTeX-based visualizations, especially the circuit drawers, need access to the
129
- `pylatexenc <https://github.com/phfaist/pylatexenc>`__ project to work correctly.
130
-
131
- * - .. py:data:: HAS_QASM3_IMPORT
132
- - The functions :func:`.qasm3.load` and :func:`.qasm3.loads` for importing OpenQASM 3 programs
133
- into :class:`.QuantumCircuit` instances use `an external importer package
134
- <https://qiskit.github.io/qiskit-qasm3-import>`__.
135
-
136
- * - .. py:data:: HAS_SEABORN
137
- - Qiskit provides several visualization tools in the :mod:`.visualization` module. Some
138
- of these are built using `Seaborn <https://seaborn.pydata.org/>`__, which must be installed
139
- in order to use them.
140
-
141
- * - .. py:data:: HAS_SKLEARN
142
- - Some of the gradient functions in :mod:`.opflow.gradients` use regularisation methods from
143
- `Scikit Learn <https://scikit-learn.org/stable/>`__.
144
-
145
- * - .. py:data:: HAS_SKQUANT
146
- - Some of the optimisers in :mod:`.algorithms.optimizers` are based on those found in `Scikit
147
- Quant <https://github.com/scikit-quant/scikit-quant>`__, which must be installed to use
148
- them.
149
-
150
- * - .. py:data:: HAS_SQSNOBFIT
151
- - `SQSnobFit <https://pypi.org/project/SQSnobFit/>`__ is a library for the "stable noisy
152
- optimization by branch and fit" algorithm. It is used by the :class:`.SNOBFIT` optimizer.
153
-
154
- * - .. py:data:: HAS_SYMENGINE
155
- - `Symengine <https://github.com/symengine/symengine>`__ is a fast C++ backend for the
156
- symbolic-manipulation library `Sympy <https://www.sympy.org/en/index.html>`__. Qiskit uses
157
- special methods from Symengine to accelerate its handling of
158
- :class:`~.circuit.Parameter`\\ s if available.
159
-
160
- * - .. py:data:: HAS_TESTTOOLS
161
- - Qiskit's test suite has more advanced functionality available if the optional
162
- `testtools <https://pypi.org/project/testtools/>`__ library is installed. This is generally
163
- only needed for Qiskit developers.
164
-
165
- * - .. py:data:: HAS_TWEEDLEDUM
166
- - `Tweedledum <https://github.com/boschmitt/tweedledum>`__ is an extension library for
167
- synthesis and optimization of circuits that may involve classical oracles. Qiskit's
168
- :class:`.PhaseOracle` uses this, which is used in turn by amplification algorithms via
169
- the :class:`.AmplificationProblem`.
170
-
171
- * - .. py:data:: HAS_Z3
172
- - `Z3 <https://github.com/Z3Prover/z3>`__ is a theorem prover, used in the
173
- :class:`.CrosstalkAdaptiveSchedule` and :class:`.HoareOptimizer` transpiler passes.
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
- .. list-table::
179
- :widths: 25 75
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
- * - .. py:data:: HAS_GRAPHVIZ
182
- - For some graph visualizations, Qiskit uses the `GraphViz <https://graphviz.org/>`__
183
- visualization tool via its ``pydot`` interface (see :data:`HAS_PYDOT`).
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
- * - .. py:data:: HAS_PDFLATEX
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
- * - .. py:data:: HAS_PDFTOCAIRO
191
- - Visualization tools that convert LaTeX-generated files into rasterized images use the
192
- ``pdftocairo`` tool. This is part of the `Poppler suite of PDF tools
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
@@ -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
- if tuple(int(x) for x in matplotlib.__version__.split(".")) >= (3, 4, 0):
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
- else:
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
- else:
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
- else:
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