qiskit 1.0.2__cp38-abi3-win32.whl → 1.1.0__cp38-abi3-win32.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 (263) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +27 -16
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/_numpy_compat.py +73 -0
  5. qiskit/assembler/__init__.py +5 -10
  6. qiskit/assembler/disassemble.py +5 -6
  7. qiskit/circuit/__init__.py +1061 -232
  8. qiskit/circuit/_classical_resource_map.py +10 -6
  9. qiskit/circuit/_utils.py +18 -8
  10. qiskit/circuit/annotated_operation.py +21 -0
  11. qiskit/circuit/barrier.py +10 -13
  12. qiskit/circuit/bit.py +0 -1
  13. qiskit/circuit/classical/__init__.py +2 -2
  14. qiskit/circuit/classical/expr/__init__.py +39 -5
  15. qiskit/circuit/classical/expr/constructors.py +84 -1
  16. qiskit/circuit/classical/expr/expr.py +83 -13
  17. qiskit/circuit/classical/expr/visitors.py +83 -0
  18. qiskit/circuit/classical/types/__init__.py +5 -4
  19. qiskit/circuit/classicalfunction/__init__.py +1 -0
  20. qiskit/circuit/commutation_checker.py +86 -51
  21. qiskit/circuit/controlflow/_builder_utils.py +9 -1
  22. qiskit/circuit/controlflow/break_loop.py +8 -22
  23. qiskit/circuit/controlflow/builder.py +116 -1
  24. qiskit/circuit/controlflow/continue_loop.py +8 -22
  25. qiskit/circuit/controlflow/control_flow.py +47 -8
  26. qiskit/circuit/controlflow/for_loop.py +8 -23
  27. qiskit/circuit/controlflow/if_else.py +13 -27
  28. qiskit/circuit/controlflow/switch_case.py +14 -21
  29. qiskit/circuit/controlflow/while_loop.py +9 -23
  30. qiskit/circuit/controlledgate.py +2 -2
  31. qiskit/circuit/delay.py +7 -5
  32. qiskit/circuit/gate.py +20 -7
  33. qiskit/circuit/instruction.py +31 -30
  34. qiskit/circuit/instructionset.py +9 -22
  35. qiskit/circuit/library/__init__.py +3 -13
  36. qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
  37. qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
  38. qiskit/circuit/library/blueprintcircuit.py +29 -7
  39. qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
  40. qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
  41. qiskit/circuit/library/generalized_gates/isometry.py +51 -254
  42. qiskit/circuit/library/generalized_gates/pauli.py +2 -2
  43. qiskit/circuit/library/generalized_gates/permutation.py +4 -1
  44. qiskit/circuit/library/generalized_gates/rv.py +15 -11
  45. qiskit/circuit/library/generalized_gates/uc.py +2 -98
  46. qiskit/circuit/library/generalized_gates/unitary.py +9 -4
  47. qiskit/circuit/library/hamiltonian_gate.py +11 -5
  48. qiskit/circuit/library/n_local/efficient_su2.py +5 -5
  49. qiskit/circuit/library/n_local/n_local.py +100 -49
  50. qiskit/circuit/library/n_local/two_local.py +3 -59
  51. qiskit/circuit/library/overlap.py +3 -3
  52. qiskit/circuit/library/phase_oracle.py +1 -1
  53. qiskit/circuit/library/quantum_volume.py +39 -38
  54. qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
  55. qiskit/circuit/library/standard_gates/global_phase.py +4 -2
  56. qiskit/circuit/library/standard_gates/i.py +1 -2
  57. qiskit/circuit/library/standard_gates/iswap.py +1 -2
  58. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
  59. qiskit/circuit/library/standard_gates/p.py +31 -15
  60. qiskit/circuit/library/standard_gates/r.py +4 -3
  61. qiskit/circuit/library/standard_gates/rx.py +7 -4
  62. qiskit/circuit/library/standard_gates/rxx.py +4 -3
  63. qiskit/circuit/library/standard_gates/ry.py +7 -4
  64. qiskit/circuit/library/standard_gates/ryy.py +4 -3
  65. qiskit/circuit/library/standard_gates/rz.py +7 -4
  66. qiskit/circuit/library/standard_gates/rzx.py +4 -3
  67. qiskit/circuit/library/standard_gates/rzz.py +4 -3
  68. qiskit/circuit/library/standard_gates/s.py +4 -8
  69. qiskit/circuit/library/standard_gates/t.py +2 -4
  70. qiskit/circuit/library/standard_gates/u.py +16 -11
  71. qiskit/circuit/library/standard_gates/u1.py +6 -2
  72. qiskit/circuit/library/standard_gates/u2.py +4 -2
  73. qiskit/circuit/library/standard_gates/u3.py +9 -5
  74. qiskit/circuit/library/standard_gates/x.py +22 -11
  75. qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
  76. qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
  77. qiskit/circuit/library/standard_gates/z.py +1 -2
  78. qiskit/circuit/measure.py +4 -1
  79. qiskit/circuit/operation.py +13 -8
  80. qiskit/circuit/parameter.py +11 -6
  81. qiskit/circuit/quantumcircuit.py +1910 -260
  82. qiskit/circuit/quantumcircuitdata.py +2 -2
  83. qiskit/circuit/reset.py +5 -2
  84. qiskit/circuit/store.py +95 -0
  85. qiskit/compiler/assembler.py +22 -22
  86. qiskit/compiler/transpiler.py +63 -112
  87. qiskit/converters/__init__.py +17 -2
  88. qiskit/converters/circuit_to_dag.py +7 -0
  89. qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
  90. qiskit/converters/circuit_to_gate.py +2 -0
  91. qiskit/converters/circuit_to_instruction.py +22 -0
  92. qiskit/converters/dag_to_circuit.py +4 -0
  93. qiskit/converters/dag_to_dagdependency_v2.py +44 -0
  94. qiskit/dagcircuit/collect_blocks.py +15 -10
  95. qiskit/dagcircuit/dagcircuit.py +434 -124
  96. qiskit/dagcircuit/dagdependency.py +19 -12
  97. qiskit/dagcircuit/dagdependency_v2.py +641 -0
  98. qiskit/dagcircuit/dagdepnode.py +19 -16
  99. qiskit/dagcircuit/dagnode.py +14 -4
  100. qiskit/passmanager/passmanager.py +11 -11
  101. qiskit/primitives/__init__.py +22 -12
  102. qiskit/primitives/backend_estimator.py +3 -5
  103. qiskit/primitives/backend_estimator_v2.py +410 -0
  104. qiskit/primitives/backend_sampler_v2.py +287 -0
  105. qiskit/primitives/base/base_estimator.py +4 -9
  106. qiskit/primitives/base/base_sampler.py +2 -2
  107. qiskit/primitives/containers/__init__.py +6 -4
  108. qiskit/primitives/containers/bit_array.py +293 -2
  109. qiskit/primitives/containers/data_bin.py +123 -50
  110. qiskit/primitives/containers/estimator_pub.py +10 -3
  111. qiskit/primitives/containers/observables_array.py +2 -2
  112. qiskit/primitives/containers/pub_result.py +1 -1
  113. qiskit/primitives/containers/sampler_pub.py +19 -3
  114. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  115. qiskit/primitives/containers/shape.py +4 -4
  116. qiskit/primitives/statevector_estimator.py +4 -4
  117. qiskit/primitives/statevector_sampler.py +7 -12
  118. qiskit/providers/__init__.py +65 -34
  119. qiskit/providers/backend.py +2 -2
  120. qiskit/providers/backend_compat.py +8 -10
  121. qiskit/providers/basic_provider/__init__.py +2 -23
  122. qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
  123. qiskit/providers/basic_provider/basic_simulator.py +81 -21
  124. qiskit/providers/fake_provider/__init__.py +1 -1
  125. qiskit/providers/fake_provider/fake_1q.py +1 -1
  126. qiskit/providers/fake_provider/fake_backend.py +3 -408
  127. qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
  128. qiskit/providers/models/__init__.py +2 -2
  129. qiskit/providers/provider.py +16 -0
  130. qiskit/pulse/builder.py +4 -1
  131. qiskit/pulse/parameter_manager.py +60 -4
  132. qiskit/pulse/schedule.py +29 -13
  133. qiskit/pulse/utils.py +61 -20
  134. qiskit/qasm2/__init__.py +1 -5
  135. qiskit/qasm2/parse.py +1 -4
  136. qiskit/qasm3/__init__.py +42 -5
  137. qiskit/qasm3/ast.py +19 -0
  138. qiskit/qasm3/exporter.py +178 -106
  139. qiskit/qasm3/printer.py +27 -5
  140. qiskit/qobj/converters/pulse_instruction.py +6 -6
  141. qiskit/qpy/__init__.py +299 -67
  142. qiskit/qpy/binary_io/circuits.py +216 -47
  143. qiskit/qpy/binary_io/schedules.py +42 -36
  144. qiskit/qpy/binary_io/value.py +201 -22
  145. qiskit/qpy/common.py +1 -1
  146. qiskit/qpy/exceptions.py +20 -0
  147. qiskit/qpy/formats.py +29 -0
  148. qiskit/qpy/type_keys.py +21 -0
  149. qiskit/quantum_info/analysis/distance.py +3 -3
  150. qiskit/quantum_info/analysis/make_observable.py +2 -1
  151. qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
  152. qiskit/quantum_info/operators/channel/chi.py +9 -8
  153. qiskit/quantum_info/operators/channel/choi.py +10 -9
  154. qiskit/quantum_info/operators/channel/kraus.py +2 -1
  155. qiskit/quantum_info/operators/channel/ptm.py +10 -9
  156. qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
  157. qiskit/quantum_info/operators/channel/stinespring.py +2 -1
  158. qiskit/quantum_info/operators/channel/superop.py +12 -11
  159. qiskit/quantum_info/operators/channel/transformations.py +12 -11
  160. qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
  161. qiskit/quantum_info/operators/operator.py +43 -30
  162. qiskit/quantum_info/operators/scalar_op.py +10 -9
  163. qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
  164. qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
  165. qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
  166. qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
  167. qiskit/quantum_info/operators/symplectic/random.py +3 -2
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
  169. qiskit/quantum_info/states/densitymatrix.py +13 -13
  170. qiskit/quantum_info/states/stabilizerstate.py +3 -3
  171. qiskit/quantum_info/states/statevector.py +14 -13
  172. qiskit/quantum_info/states/utils.py +5 -3
  173. qiskit/result/__init__.py +6 -0
  174. qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
  175. qiskit/result/mitigation/local_readout_mitigator.py +2 -1
  176. qiskit/result/mitigation/utils.py +3 -2
  177. qiskit/scheduler/__init__.py +10 -1
  178. qiskit/scheduler/methods/__init__.py +1 -8
  179. qiskit/synthesis/__init__.py +3 -6
  180. qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
  181. qiskit/synthesis/evolution/lie_trotter.py +7 -14
  182. qiskit/synthesis/evolution/qdrift.py +3 -4
  183. qiskit/synthesis/linear/cnot_synth.py +1 -3
  184. qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
  185. qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
  186. qiskit/synthesis/permutation/__init__.py +1 -0
  187. qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
  188. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
  189. qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
  190. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
  191. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
  192. qiskit/synthesis/unitary/aqc/__init__.py +1 -1
  193. qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
  194. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
  195. qiskit/synthesis/unitary/qsd.py +3 -2
  196. qiskit/transpiler/__init__.py +7 -3
  197. qiskit/transpiler/layout.py +140 -61
  198. qiskit/transpiler/passes/__init__.py +10 -2
  199. qiskit/transpiler/passes/basis/basis_translator.py +9 -4
  200. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  201. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  202. qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
  203. qiskit/transpiler/passes/layout/apply_layout.py +8 -3
  204. qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
  205. qiskit/transpiler/passes/layout/set_layout.py +1 -1
  206. qiskit/transpiler/passes/optimization/__init__.py +2 -0
  207. qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
  208. qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
  209. qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
  210. qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
  211. qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
  212. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
  213. qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
  214. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  215. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
  216. qiskit/transpiler/passes/routing/__init__.py +1 -0
  217. qiskit/transpiler/passes/routing/basic_swap.py +13 -2
  218. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
  219. qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
  220. qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
  221. qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
  222. qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
  223. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  224. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  225. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
  226. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
  227. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
  228. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
  229. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  230. qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
  231. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
  232. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
  233. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
  234. qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
  235. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
  236. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
  237. qiskit/transpiler/passes/utils/gates_basis.py +3 -3
  238. qiskit/transpiler/passmanager.py +44 -1
  239. qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
  240. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
  241. qiskit/transpiler/preset_passmanagers/common.py +4 -6
  242. qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
  243. qiskit/utils/__init__.py +3 -2
  244. qiskit/utils/optionals.py +6 -2
  245. qiskit/utils/parallel.py +24 -15
  246. qiskit/visualization/array.py +1 -1
  247. qiskit/visualization/bloch.py +2 -3
  248. qiskit/visualization/circuit/matplotlib.py +44 -14
  249. qiskit/visualization/circuit/text.py +38 -18
  250. qiskit/visualization/counts_visualization.py +3 -6
  251. qiskit/visualization/dag_visualization.py +6 -7
  252. qiskit/visualization/gate_map.py +9 -1
  253. qiskit/visualization/pulse_v2/interface.py +8 -3
  254. qiskit/visualization/state_visualization.py +3 -2
  255. qiskit/visualization/timeline/interface.py +18 -8
  256. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
  257. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/RECORD +261 -251
  258. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
  259. qiskit/_qasm2.pyd +0 -0
  260. qiskit/_qasm3.pyd +0 -0
  261. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
  262. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
  263. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/top_level.txt +0 -0
qiskit/utils/parallel.py CHANGED
@@ -48,6 +48,8 @@ Routines for running Python functions in parallel using process pools
48
48
  from the multiprocessing library.
49
49
  """
50
50
 
51
+ from __future__ import annotations
52
+
51
53
  import os
52
54
  from concurrent.futures import ProcessPoolExecutor
53
55
  import sys
@@ -101,6 +103,21 @@ def _task_wrapper(param):
101
103
  return task(value, *task_args, **task_kwargs)
102
104
 
103
105
 
106
+ def should_run_in_parallel(num_processes: int | None = None) -> bool:
107
+ """Return whether the current parallelisation configuration suggests that we should run things
108
+ like :func:`parallel_map` in parallel (``True``) or degrade to serial (``False``).
109
+
110
+ Args:
111
+ num_processes: the number of processes requested for use (if given).
112
+ """
113
+ num_processes = CPU_COUNT if num_processes is None else num_processes
114
+ return (
115
+ num_processes > 1
116
+ and os.getenv("QISKIT_IN_PARALLEL", "FALSE") == "FALSE"
117
+ and CONFIG.get("parallel_enabled", PARALLEL_DEFAULT)
118
+ )
119
+
120
+
104
121
  def parallel_map( # pylint: disable=dangerous-default-value
105
122
  task, values, task_args=(), task_kwargs={}, num_processes=CPU_COUNT
106
123
  ):
@@ -110,21 +127,20 @@ def parallel_map( # pylint: disable=dangerous-default-value
110
127
 
111
128
  result = [task(value, *task_args, **task_kwargs) for value in values]
112
129
 
113
- On Windows this function defaults to a serial implementation to avoid the
114
- overhead from spawning processes in Windows.
130
+ This will parallelise the results if the number of ``values`` is greater than one, and the
131
+ current system configuration permits parallelization.
115
132
 
116
133
  Args:
117
134
  task (func): Function that is to be called for each value in ``values``.
118
- values (array_like): List or array of values for which the ``task``
119
- function is to be evaluated.
135
+ values (array_like): List or array of values for which the ``task`` function is to be
136
+ evaluated.
120
137
  task_args (list): Optional additional arguments to the ``task`` function.
121
138
  task_kwargs (dict): Optional additional keyword argument to the ``task`` function.
122
139
  num_processes (int): Number of processes to spawn.
123
140
 
124
141
  Returns:
125
- result: The result list contains the value of
126
- ``task(value, *task_args, **task_kwargs)`` for
127
- each value in ``values``.
142
+ result: The result list contains the value of ``task(value, *task_args, **task_kwargs)`` for
143
+ each value in ``values``.
128
144
 
129
145
  Raises:
130
146
  QiskitError: If user interrupts via keyboard.
@@ -147,12 +163,7 @@ def parallel_map( # pylint: disable=dangerous-default-value
147
163
  if len(values) == 1:
148
164
  return [task(values[0], *task_args, **task_kwargs)]
149
165
 
150
- # Run in parallel if not Win and not in parallel already
151
- if (
152
- num_processes > 1
153
- and os.getenv("QISKIT_IN_PARALLEL") == "FALSE"
154
- and CONFIG.get("parallel_enabled", PARALLEL_DEFAULT)
155
- ):
166
+ if should_run_in_parallel(num_processes):
156
167
  os.environ["QISKIT_IN_PARALLEL"] = "TRUE"
157
168
  try:
158
169
  results = []
@@ -173,8 +184,6 @@ def parallel_map( # pylint: disable=dangerous-default-value
173
184
  os.environ["QISKIT_IN_PARALLEL"] = "FALSE"
174
185
  return results
175
186
 
176
- # Cannot do parallel on Windows , if another parallel_map is running in parallel,
177
- # or len(values) == 1.
178
187
  results = []
179
188
  for _, value in enumerate(values):
180
189
  result = task(value, *task_args, **task_kwargs)
@@ -33,7 +33,7 @@ def _num_to_latex(raw_value, decimals=15, first_term=True, coefficient=False):
33
33
  """
34
34
  import sympy # runtime import
35
35
 
36
- raw_value = np.around(raw_value, decimals=decimals)
36
+ raw_value = np.around(raw_value, decimals=decimals).item()
37
37
  value = sympy.nsimplify(raw_value, rational=False)
38
38
 
39
39
  if isinstance(value, sympy.core.numbers.Rational) and value.denominator > 50:
@@ -48,6 +48,7 @@
48
48
 
49
49
  __all__ = ["Bloch"]
50
50
 
51
+ import math
51
52
  import os
52
53
  import numpy as np
53
54
  import matplotlib
@@ -648,9 +649,7 @@ class Bloch:
648
649
  )
649
650
 
650
651
  elif self.point_style[k] == "m":
651
- pnt_colors = np.array(
652
- self.point_color * int(np.ceil(num / float(len(self.point_color))))
653
- )
652
+ pnt_colors = np.array(self.point_color * math.ceil(num / len(self.point_color)))
654
653
 
655
654
  pnt_colors = pnt_colors[0:num]
656
655
  pnt_colors = list(pnt_colors[indperm])
@@ -33,6 +33,7 @@ from qiskit.circuit import (
33
33
  IfElseOp,
34
34
  ForLoopOp,
35
35
  SwitchCaseOp,
36
+ CircuitError,
36
37
  )
37
38
  from qiskit.circuit.controlflow import condition_resources
38
39
  from qiskit.circuit.classical import expr
@@ -46,7 +47,8 @@ from qiskit.circuit.library.standard_gates import (
46
47
  XGate,
47
48
  ZGate,
48
49
  )
49
- from qiskit.qasm3.exporter import QASM3Builder
50
+ from qiskit.qasm3 import ast
51
+ from qiskit.qasm3.exporter import _ExprBuilder
50
52
  from qiskit.qasm3.printer import BasicPrinter
51
53
 
52
54
  from qiskit.circuit.tools.pi_check import pi_check
@@ -393,7 +395,7 @@ class MatplotlibDrawer:
393
395
  matplotlib_close_if_inline(mpl_figure)
394
396
  return mpl_figure
395
397
 
396
- def _get_layer_widths(self, node_data, wire_map, outer_circuit, glob_data, builder=None):
398
+ def _get_layer_widths(self, node_data, wire_map, outer_circuit, glob_data):
397
399
  """Compute the layer_widths for the layers"""
398
400
 
399
401
  layer_widths = {}
@@ -482,18 +484,41 @@ class MatplotlibDrawer:
482
484
  if (isinstance(op, SwitchCaseOp) and isinstance(op.target, expr.Expr)) or (
483
485
  getattr(op, "condition", None) and isinstance(op.condition, expr.Expr)
484
486
  ):
485
- condition = op.target if isinstance(op, SwitchCaseOp) else op.condition
486
- if builder is None:
487
- builder = QASM3Builder(
488
- outer_circuit,
489
- includeslist=("stdgates.inc",),
490
- basis_gates=("U",),
491
- disable_constants=False,
492
- allow_aliasing=False,
487
+
488
+ def lookup_var(var):
489
+ """Look up a classical-expression variable or register/bit in our
490
+ internal symbol table, and return an OQ3-like identifier."""
491
+ # We don't attempt to disambiguate anything like register/var naming
492
+ # collisions; we already don't really show classical variables.
493
+ if isinstance(var, expr.Var):
494
+ return ast.Identifier(var.name)
495
+ if isinstance(var, ClassicalRegister):
496
+ return ast.Identifier(var.name)
497
+ # Single clbit. This is not actually the correct way to lookup a bit on
498
+ # the circuit (it doesn't handle bit bindings fully), but the mpl
499
+ # drawer doesn't completely track inner-outer _bit_ bindings, only
500
+ # inner-indices, so we can't fully recover the information losslessly.
501
+ # Since most control-flow uses the control-flow builders, we should
502
+ # decay to something usable most of the time.
503
+ try:
504
+ register, bit_index, reg_index = get_bit_reg_index(
505
+ outer_circuit, var
506
+ )
507
+ except CircuitError:
508
+ # We failed to find the bit due to binding problems - fall back to
509
+ # something that's probably wrong, but at least disambiguating.
510
+ return ast.Identifier(f"bit{wire_map[var]}")
511
+ if register is None:
512
+ return ast.Identifier(f"bit{bit_index}")
513
+ return ast.SubscriptedIdentifier(
514
+ register.name, ast.IntegerLiteral(reg_index)
493
515
  )
494
- builder.build_classical_declarations()
516
+
517
+ condition = op.target if isinstance(op, SwitchCaseOp) else op.condition
495
518
  stream = StringIO()
496
- BasicPrinter(stream, indent=" ").visit(builder.build_expression(condition))
519
+ BasicPrinter(stream, indent=" ").visit(
520
+ condition.accept(_ExprBuilder(lookup_var))
521
+ )
497
522
  expr_text = stream.getvalue()
498
523
  # Truncate expr_text so that first gate is no more than about 3 x_index's over
499
524
  if len(expr_text) > self._expr_len:
@@ -570,7 +595,7 @@ class MatplotlibDrawer:
570
595
 
571
596
  # Recursively call _get_layer_widths for the circuit inside the ControlFlowOp
572
597
  flow_widths = flow_drawer._get_layer_widths(
573
- node_data, flow_wire_map, outer_circuit, glob_data, builder
598
+ node_data, flow_wire_map, outer_circuit, glob_data
574
599
  )
575
600
  layer_widths.update(flow_widths)
576
601
 
@@ -1243,6 +1268,11 @@ class MatplotlibDrawer:
1243
1268
  self._ax.add_patch(box)
1244
1269
  xy_plot.append(xy)
1245
1270
 
1271
+ if not xy_plot:
1272
+ # Expression that's only on new-style `expr.Var` nodes, and doesn't need any vertical
1273
+ # line drawing.
1274
+ return
1275
+
1246
1276
  qubit_b = min(node_data[node].q_xy, key=lambda xy: xy[1])
1247
1277
  clbit_b = min(xy_plot, key=lambda xy: xy[1])
1248
1278
 
@@ -1544,7 +1574,7 @@ class MatplotlibDrawer:
1544
1574
  while end_x > 0.0:
1545
1575
  x_shift = fold_level * self._fold
1546
1576
  y_shift = fold_level * (glob_data["n_lines"] + 1)
1547
- end_x = xpos + box_width - x_shift
1577
+ end_x = xpos + box_width - x_shift if self._fold > 0 else 0.0
1548
1578
 
1549
1579
  if isinstance(node.op, IfElseOp):
1550
1580
  flow_text = " If"
@@ -20,7 +20,7 @@ from shutil import get_terminal_size
20
20
  import collections
21
21
  import sys
22
22
 
23
- from qiskit.circuit import Qubit, Clbit, ClassicalRegister
23
+ from qiskit.circuit import Qubit, Clbit, ClassicalRegister, CircuitError
24
24
  from qiskit.circuit import ControlledGate, Reset, Measure
25
25
  from qiskit.circuit import ControlFlowOp, WhileLoopOp, IfElseOp, ForLoopOp, SwitchCaseOp
26
26
  from qiskit.circuit.classical import expr
@@ -28,8 +28,9 @@ from qiskit.circuit.controlflow import node_resources
28
28
  from qiskit.circuit.library.standard_gates import IGate, RZZGate, SwapGate, SXGate, SXdgGate
29
29
  from qiskit.circuit.annotated_operation import _canonicalize_modifiers, ControlModifier
30
30
  from qiskit.circuit.tools.pi_check import pi_check
31
- from qiskit.qasm3.exporter import QASM3Builder
31
+ from qiskit.qasm3 import ast
32
32
  from qiskit.qasm3.printer import BasicPrinter
33
+ from qiskit.qasm3.exporter import _ExprBuilder
33
34
 
34
35
  from ._utils import (
35
36
  get_gate_ctrl_text,
@@ -748,7 +749,6 @@ class TextDrawing:
748
749
 
749
750
  self._nest_depth = 0 # nesting depth for control flow ops
750
751
  self._expr_text = "" # expression text to display
751
- self._builder = None # QASM3Builder class instance for expressions
752
752
 
753
753
  # Because jupyter calls both __repr__ and __repr_html__ for some backends,
754
754
  # the entire drawer can be run twice which can result in different output
@@ -1306,25 +1306,44 @@ class TextDrawing:
1306
1306
  if (isinstance(node.op, SwitchCaseOp) and isinstance(node.op.target, expr.Expr)) or (
1307
1307
  getattr(node.op, "condition", None) and isinstance(node.op.condition, expr.Expr)
1308
1308
  ):
1309
+
1310
+ def lookup_var(var):
1311
+ """Look up a classical-expression variable or register/bit in our internal symbol
1312
+ table, and return an OQ3-like identifier."""
1313
+ # We don't attempt to disambiguate anything like register/var naming collisions; we
1314
+ # already don't really show classical variables.
1315
+ if isinstance(var, expr.Var):
1316
+ return ast.Identifier(var.name)
1317
+ if isinstance(var, ClassicalRegister):
1318
+ return ast.Identifier(var.name)
1319
+ # Single clbit. This is not actually the correct way to lookup a bit on the
1320
+ # circuit (it doesn't handle bit bindings fully), but the text drawer doesn't
1321
+ # completely track inner-outer _bit_ bindings, only inner-indices, so we can't fully
1322
+ # recover the information losslessly. Since most control-flow uses the control-flow
1323
+ # builders, we should decay to something usable most of the time.
1324
+ try:
1325
+ register, bit_index, reg_index = get_bit_reg_index(self._circuit, var)
1326
+ except CircuitError:
1327
+ # We failed to find the bit due to binding problems - fall back to something
1328
+ # that's probably wrong, but at least disambiguating.
1329
+ return ast.Identifier(f"_bit{wire_map[var]}")
1330
+ if register is None:
1331
+ return ast.Identifier(f"_bit{bit_index}")
1332
+ return ast.SubscriptedIdentifier(register.name, ast.IntegerLiteral(reg_index))
1333
+
1309
1334
  condition = node.op.target if isinstance(node.op, SwitchCaseOp) else node.op.condition
1310
- if self._builder is None:
1311
- self._builder = QASM3Builder(
1312
- self._circuit,
1313
- includeslist=("stdgates.inc",),
1314
- basis_gates=("U",),
1315
- disable_constants=False,
1316
- allow_aliasing=False,
1317
- )
1318
- self._builder.build_classical_declarations()
1335
+ draw_conditional = bool(node_resources(condition).clbits)
1319
1336
  stream = StringIO()
1320
- BasicPrinter(stream, indent=" ").visit(self._builder.build_expression(condition))
1337
+ BasicPrinter(stream, indent=" ").visit(condition.accept(_ExprBuilder(lookup_var)))
1321
1338
  self._expr_text = stream.getvalue()
1322
1339
  # Truncate expr_text at 30 chars or user-set expr_len
1323
1340
  if len(self._expr_text) > self.expr_len:
1324
1341
  self._expr_text = self._expr_text[: self.expr_len] + "..."
1342
+ else:
1343
+ draw_conditional = not isinstance(node.op, ForLoopOp)
1325
1344
 
1326
1345
  # # Draw a left box such as If, While, For, and Switch
1327
- flow_layer = self.draw_flow_box(node, wire_map, CF_LEFT)
1346
+ flow_layer = self.draw_flow_box(node, wire_map, CF_LEFT, conditional=draw_conditional)
1328
1347
  layers.append(flow_layer.full_layer)
1329
1348
 
1330
1349
  # Get the list of circuits in the ControlFlowOp from the node blocks
@@ -1351,7 +1370,9 @@ class TextDrawing:
1351
1370
 
1352
1371
  if circ_num > 0:
1353
1372
  # Draw a middle box such as Else and Case
1354
- flow_layer = self.draw_flow_box(node, flow_wire_map, CF_MID, circ_num - 1)
1373
+ flow_layer = self.draw_flow_box(
1374
+ node, flow_wire_map, CF_MID, circ_num - 1, conditional=False
1375
+ )
1355
1376
  layers.append(flow_layer.full_layer)
1356
1377
 
1357
1378
  _, _, nodes = _get_layered_instructions(circuit, wire_map=flow_wire_map)
@@ -1380,14 +1401,13 @@ class TextDrawing:
1380
1401
  layers.append(flow_layer2.full_layer)
1381
1402
 
1382
1403
  # Draw the right box for End
1383
- flow_layer = self.draw_flow_box(node, flow_wire_map, CF_RIGHT)
1404
+ flow_layer = self.draw_flow_box(node, flow_wire_map, CF_RIGHT, conditional=False)
1384
1405
  layers.append(flow_layer.full_layer)
1385
1406
 
1386
- def draw_flow_box(self, node, flow_wire_map, section, circ_num=0):
1407
+ def draw_flow_box(self, node, flow_wire_map, section, circ_num=0, conditional=False):
1387
1408
  """Draw the left, middle, or right of a control flow box"""
1388
1409
 
1389
1410
  op = node.op
1390
- conditional = section == CF_LEFT and not isinstance(op, ForLoopOp)
1391
1411
  depth = str(self._nest_depth)
1392
1412
  if section == CF_LEFT:
1393
1413
  etext = ""
@@ -58,7 +58,7 @@ def _is_deprecated_data_format(data) -> bool:
58
58
 
59
59
  def plot_histogram(
60
60
  data,
61
- figsize=(7, 5),
61
+ figsize=None,
62
62
  color=None,
63
63
  number_to_keep=None,
64
64
  sort="asc",
@@ -296,7 +296,7 @@ def _plotting_core(
296
296
 
297
297
  # Set bar colors
298
298
  if color is None:
299
- color = ["#648fff", "#dc267f", "#785ef0", "#ffb000", "#fe6100"]
299
+ color = plt.rcParams["axes.prop_cycle"].by_key()["color"]
300
300
  elif isinstance(color, str):
301
301
  color = [color]
302
302
 
@@ -350,7 +350,7 @@ def _plotting_core(
350
350
  label = None
351
351
  bar_center = (width / 2) * (length - 1)
352
352
  ax.set_xticks(all_inds[item] + bar_center)
353
- ax.set_xticklabels(labels_dict.keys(), fontsize=14, rotation=70)
353
+ ax.set_xticklabels(labels_dict.keys(), rotation=70, ha="right", rotation_mode="anchor")
354
354
  # attach some text labels
355
355
  if bar_labels:
356
356
  for rect in rects:
@@ -391,8 +391,6 @@ def _plotting_core(
391
391
  ax.invert_xaxis()
392
392
 
393
393
  ax.yaxis.set_major_locator(MaxNLocator(5))
394
- for tick in ax.yaxis.get_major_ticks():
395
- tick.label1.set_fontsize(14)
396
394
  plt.grid(which="major", axis="y", zorder=0, linestyle="--")
397
395
  if title:
398
396
  plt.title(title)
@@ -404,7 +402,6 @@ def _plotting_core(
404
402
  ncol=1,
405
403
  borderaxespad=0,
406
404
  frameon=True,
407
- fontsize=12,
408
405
  )
409
406
  if fig:
410
407
  matplotlib_close_if_inline(fig)
@@ -89,6 +89,10 @@ def dag_drawer(dag, scale=0.7, filename=None, style="color"):
89
89
  dag_dep_circ = dagdependency_to_circuit(dag)
90
90
 
91
91
  def node_attr_func(node):
92
+ if "DAGDependencyV2" in type_str:
93
+ nid_str = str(node._node_id)
94
+ else:
95
+ nid_str = str(node.node_id)
92
96
  if style == "plain":
93
97
  return {}
94
98
  if style == "color":
@@ -109,12 +113,7 @@ def dag_drawer(dag, scale=0.7, filename=None, style="color"):
109
113
 
110
114
  n["color"] = "black"
111
115
  n["label"] = (
112
- str(node.node_id)
113
- + ": "
114
- + str(node.name)
115
- + " ("
116
- + str(args)[1:-1].replace("'", "")
117
- + ")"
116
+ nid_str + ": " + str(node.name) + " (" + str(args)[1:-1].replace("'", "") + ")"
118
117
  )
119
118
  if node.name == "barrier":
120
119
  n["style"] = "filled"
@@ -141,7 +140,7 @@ def dag_drawer(dag, scale=0.7, filename=None, style="color"):
141
140
  n["style"] = "filled"
142
141
  n["fillcolor"] = "green"
143
142
  n["label"] = (
144
- str(node.node_id)
143
+ nid_str
145
144
  + ": "
146
145
  + str(node.name)
147
146
  + cond_txt
@@ -1039,7 +1039,9 @@ def plot_coupling_map(
1039
1039
  graph = CouplingMap(coupling_map).graph
1040
1040
 
1041
1041
  if not plot_directed:
1042
+ line_color_map = dict(zip(graph.edge_list(), line_color))
1042
1043
  graph = graph.to_undirected(multigraph=False)
1044
+ line_color = [line_color_map[edge] for edge in graph.edge_list()]
1043
1045
 
1044
1046
  for node in graph.node_indices():
1045
1047
  graph[node] = node
@@ -1122,7 +1124,13 @@ def plot_circuit_layout(circuit, backend, view="virtual", qubit_coordinates=None
1122
1124
  Args:
1123
1125
  circuit (QuantumCircuit): Input quantum circuit.
1124
1126
  backend (Backend): Target backend.
1125
- view (str): Layout view: either 'virtual' or 'physical'.
1127
+ view (str): How to label qubits in the layout. Options:
1128
+
1129
+ - ``"virtual"``: Label each qubit with the index of the virtual qubit that
1130
+ mapped to it.
1131
+ - ``"physical"``: Label each qubit with the index of the physical qubit that it
1132
+ corresponds to on the device.
1133
+
1126
1134
  qubit_coordinates (Sequence): An optional sequence input (list or array being the
1127
1135
  most common) of 2d coordinates for each qubit. The length of the
1128
1136
  sequence must match the number of qubits on the backend. The sequence
@@ -27,8 +27,10 @@ from qiskit.pulse.channels import Channel
27
27
  from qiskit.visualization.exceptions import VisualizationError
28
28
  from qiskit.visualization.pulse_v2 import core, device_info, stylesheet, types
29
29
  from qiskit.exceptions import MissingOptionalLibraryError
30
+ from qiskit.utils import deprecate_arg
30
31
 
31
32
 
33
+ @deprecate_arg("show_barriers", new_alias="plot_barriers", since="1.1.0", pending=True)
32
34
  def draw(
33
35
  program: Union[Waveform, SymbolicPulse, Schedule, ScheduleBlock],
34
36
  style: Optional[Dict[str, Any]] = None,
@@ -39,9 +41,10 @@ def draw(
39
41
  show_snapshot: bool = True,
40
42
  show_framechange: bool = True,
41
43
  show_waveform_info: bool = True,
42
- show_barrier: bool = True,
44
+ plot_barrier: bool = True,
43
45
  plotter: str = types.Plotter.Mpl2D.value,
44
46
  axis: Optional[Any] = None,
47
+ show_barrier: bool = True,
45
48
  ):
46
49
  """Generate visualization data for pulse programs.
47
50
 
@@ -66,7 +69,7 @@ def draw(
66
69
  instructions that modulate phase or frequency of pulse channels.
67
70
  show_waveform_info: Show waveform annotations, i.e. name, of waveforms.
68
71
  Set ``True`` to show additional information about waveforms.
69
- show_barrier: Show barrier lines.
72
+ plot_barrier: Show barrier lines.
70
73
  plotter: Name of plotter API to generate an output image.
71
74
  One of following APIs should be specified::
72
75
 
@@ -79,6 +82,7 @@ def draw(
79
82
  the plotters use a given ``axis`` instead of internally initializing
80
83
  a figure object. This object format depends on the plotter.
81
84
  See plotter argument for details.
85
+ show_barrier: DEPRECATED. Show barrier lines.
82
86
 
83
87
  Returns:
84
88
  Visualization output data.
@@ -379,6 +383,7 @@ def draw(
379
383
  MissingOptionalLibraryError: When required visualization package is not installed.
380
384
  VisualizationError: When invalid plotter API or invalid time range is specified.
381
385
  """
386
+ del show_barrier
382
387
  temp_style = stylesheet.QiskitPulseStyle()
383
388
  temp_style.update(style or stylesheet.IQXStandard())
384
389
 
@@ -425,7 +430,7 @@ def draw(
425
430
  canvas.set_disable_type(types.LabelType.PULSE_NAME, remove=True)
426
431
 
427
432
  # show barrier
428
- if not show_barrier:
433
+ if not plot_barrier:
429
434
  canvas.set_disable_type(types.LineType.BARRIER, remove=True)
430
435
 
431
436
  canvas.update()
@@ -17,6 +17,7 @@
17
17
  Visualization functions for quantum states.
18
18
  """
19
19
 
20
+ import math
20
21
  from typing import List, Union
21
22
  from functools import reduce
22
23
  import colorsys
@@ -97,7 +98,7 @@ def plot_state_hinton(state, title="", figsize=None, ax_real=None, ax_imag=None,
97
98
  num = rho.num_qubits
98
99
  if num is None:
99
100
  raise VisualizationError("Input is not a multi-qubit quantum state.")
100
- max_weight = 2 ** np.ceil(np.log(np.abs(rho.data).max()) / np.log(2))
101
+ max_weight = 2 ** math.ceil(math.log2(np.abs(rho.data).max()))
101
102
  datareal = np.real(rho.data)
102
103
  dataimag = np.imag(rho.data)
103
104
 
@@ -1314,7 +1315,7 @@ def _state_to_latex_ket(
1314
1315
  Returns:
1315
1316
  String with LaTeX representation of the state vector
1316
1317
  """
1317
- num = int(np.log2(len(data)))
1318
+ num = int(math.log2(len(data)))
1318
1319
 
1319
1320
  def ket_name(i):
1320
1321
  return bin(i)[2:].zfill(num)
@@ -25,21 +25,27 @@ from qiskit import circuit
25
25
  from qiskit.exceptions import MissingOptionalLibraryError
26
26
  from qiskit.visualization.exceptions import VisualizationError
27
27
  from qiskit.visualization.timeline import types, core, stylesheet
28
+ from qiskit.utils import deprecate_arg
28
29
 
29
30
 
31
+ @deprecate_arg("show_idle", new_alias="idle_wires", since="1.1.0", pending=True)
32
+ @deprecate_arg("show_barriers", new_alias="plot_barriers", since="1.1.0", pending=True)
30
33
  def draw(
31
34
  program: circuit.QuantumCircuit,
32
35
  style: Optional[Dict[str, Any]] = None,
33
36
  time_range: Tuple[int, int] = None,
34
37
  disable_bits: List[types.Bits] = None,
35
38
  show_clbits: Optional[bool] = None,
36
- show_idle: Optional[bool] = None,
37
- show_barriers: Optional[bool] = None,
39
+ idle_wires: Optional[bool] = None,
40
+ plot_barriers: Optional[bool] = None,
38
41
  show_delays: Optional[bool] = None,
39
42
  show_labels: bool = True,
40
43
  plotter: Optional[str] = types.Plotter.MPL.value,
41
44
  axis: Optional[Any] = None,
42
45
  filename: Optional[str] = None,
46
+ *,
47
+ show_idle: Optional[bool] = None,
48
+ show_barriers: Optional[bool] = None,
43
49
  ):
44
50
  r"""Generate visualization data for scheduled circuit programs.
45
51
 
@@ -55,9 +61,9 @@ def draw(
55
61
  disable_bits: List of qubits of classical bits not shown in the output image.
56
62
  show_clbits: A control property to show classical bits.
57
63
  Set `True` to show classical bits.
58
- show_idle: A control property to show idle timeline.
64
+ idle_wires: A control property to show idle timeline.
59
65
  Set `True` to show timeline without gates.
60
- show_barriers: A control property to show barrier instructions.
66
+ plot_barriers: A control property to show barrier instructions.
61
67
  Set `True` to show barrier instructions.
62
68
  show_delays: A control property to show delay instructions.
63
69
  Set `True` to show delay instructions.
@@ -75,6 +81,8 @@ def draw(
75
81
  the plotters uses given `axis` instead of internally initializing a figure object.
76
82
  This object format depends on the plotter. See plotters section for details.
77
83
  filename: If provided the output image is dumped into a file under the filename.
84
+ show_idle: DEPRECATED.
85
+ show_barriers: DEPRECATED.
78
86
 
79
87
  Returns:
80
88
  Visualization output data.
@@ -347,19 +355,21 @@ def draw(
347
355
  This feature enables you to control the most of appearance of the output image
348
356
  without modifying the codebase of the scheduled circuit drawer.
349
357
  """
358
+ del show_idle
359
+ del show_barriers
350
360
  # update stylesheet
351
361
  temp_style = stylesheet.QiskitTimelineStyle()
352
362
  temp_style.update(style or stylesheet.IQXStandard())
353
363
 
354
364
  # update control properties
355
- if show_idle is not None:
356
- temp_style["formatter.control.show_idle"] = show_idle
365
+ if idle_wires is not None:
366
+ temp_style["formatter.control.show_idle"] = idle_wires
357
367
 
358
368
  if show_clbits is not None:
359
369
  temp_style["formatter.control.show_clbits"] = show_clbits
360
370
 
361
- if show_barriers is not None:
362
- temp_style["formatter.control.show_barriers"] = show_barriers
371
+ if plot_barriers is not None:
372
+ temp_style["formatter.control.show_barriers"] = plot_barriers
363
373
 
364
374
  if show_delays is not None:
365
375
  temp_style["formatter.control.show_delays"] = show_delays