qiskit 2.0.3__cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.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 -0
- qiskit/__init__.py +141 -0
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/circuit/__init__.py +1343 -0
- qiskit/circuit/_add_control.py +312 -0
- qiskit/circuit/_classical_resource_map.py +150 -0
- qiskit/circuit/_standard_gates_commutations.py +3849 -0
- qiskit/circuit/_utils.py +167 -0
- qiskit/circuit/annotated_operation.py +279 -0
- qiskit/circuit/barrier.py +46 -0
- qiskit/circuit/classical/__init__.py +41 -0
- qiskit/circuit/classical/expr/__init__.py +266 -0
- qiskit/circuit/classical/expr/constructors.py +764 -0
- qiskit/circuit/classical/expr/expr.py +498 -0
- qiskit/circuit/classical/expr/visitors.py +375 -0
- qiskit/circuit/classical/types/__init__.py +113 -0
- qiskit/circuit/classical/types/ordering.py +229 -0
- qiskit/circuit/classical/types/types.py +153 -0
- qiskit/circuit/commutation_checker.py +133 -0
- qiskit/circuit/commutation_library.py +20 -0
- qiskit/circuit/controlflow/__init__.py +59 -0
- qiskit/circuit/controlflow/_builder_utils.py +211 -0
- qiskit/circuit/controlflow/box.py +163 -0
- qiskit/circuit/controlflow/break_loop.py +56 -0
- qiskit/circuit/controlflow/builder.py +791 -0
- qiskit/circuit/controlflow/continue_loop.py +56 -0
- qiskit/circuit/controlflow/control_flow.py +94 -0
- qiskit/circuit/controlflow/for_loop.py +218 -0
- qiskit/circuit/controlflow/if_else.py +498 -0
- qiskit/circuit/controlflow/switch_case.py +411 -0
- qiskit/circuit/controlflow/while_loop.py +166 -0
- qiskit/circuit/controlledgate.py +274 -0
- qiskit/circuit/delay.py +157 -0
- qiskit/circuit/duration.py +80 -0
- qiskit/circuit/equivalence.py +94 -0
- qiskit/circuit/equivalence_library.py +18 -0
- qiskit/circuit/exceptions.py +19 -0
- qiskit/circuit/gate.py +261 -0
- qiskit/circuit/instruction.py +564 -0
- qiskit/circuit/instructionset.py +132 -0
- qiskit/circuit/library/__init__.py +984 -0
- qiskit/circuit/library/arithmetic/__init__.py +40 -0
- qiskit/circuit/library/arithmetic/adders/__init__.py +18 -0
- qiskit/circuit/library/arithmetic/adders/adder.py +235 -0
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +123 -0
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +129 -0
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +95 -0
- qiskit/circuit/library/arithmetic/exact_reciprocal.py +131 -0
- qiskit/circuit/library/arithmetic/functional_pauli_rotations.py +114 -0
- qiskit/circuit/library/arithmetic/integer_comparator.py +200 -0
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +363 -0
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +243 -0
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +17 -0
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +145 -0
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +201 -0
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +108 -0
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +502 -0
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +387 -0
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +493 -0
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +389 -0
- qiskit/circuit/library/arithmetic/quadratic_form.py +364 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +409 -0
- qiskit/circuit/library/basis_change/__init__.py +15 -0
- qiskit/circuit/library/basis_change/qft.py +316 -0
- qiskit/circuit/library/bit_flip_oracle.py +130 -0
- qiskit/circuit/library/blueprintcircuit.py +316 -0
- qiskit/circuit/library/boolean_logic/__init__.py +18 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +157 -0
- qiskit/circuit/library/boolean_logic/quantum_and.py +204 -0
- qiskit/circuit/library/boolean_logic/quantum_or.py +206 -0
- qiskit/circuit/library/boolean_logic/quantum_xor.py +167 -0
- qiskit/circuit/library/data_preparation/__init__.py +57 -0
- qiskit/circuit/library/data_preparation/_z_feature_map.py +115 -0
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
- qiskit/circuit/library/data_preparation/initializer.py +107 -0
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +656 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +336 -0
- qiskit/circuit/library/fourier_checking.py +160 -0
- qiskit/circuit/library/generalized_gates/__init__.py +30 -0
- qiskit/circuit/library/generalized_gates/diagonal.py +159 -0
- qiskit/circuit/library/generalized_gates/gms.py +175 -0
- qiskit/circuit/library/generalized_gates/gr.py +219 -0
- qiskit/circuit/library/generalized_gates/isometry.py +370 -0
- qiskit/circuit/library/generalized_gates/linear_function.py +318 -0
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +143 -0
- qiskit/circuit/library/generalized_gates/mcmt.py +316 -0
- qiskit/circuit/library/generalized_gates/pauli.py +84 -0
- qiskit/circuit/library/generalized_gates/permutation.py +198 -0
- qiskit/circuit/library/generalized_gates/rv.py +96 -0
- qiskit/circuit/library/generalized_gates/uc.py +303 -0
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +164 -0
- qiskit/circuit/library/generalized_gates/ucrx.py +32 -0
- qiskit/circuit/library/generalized_gates/ucry.py +32 -0
- qiskit/circuit/library/generalized_gates/ucrz.py +32 -0
- qiskit/circuit/library/generalized_gates/unitary.py +217 -0
- qiskit/circuit/library/graph_state.py +172 -0
- qiskit/circuit/library/grover_operator.py +583 -0
- qiskit/circuit/library/hamiltonian_gate.py +142 -0
- qiskit/circuit/library/hidden_linear_function.py +163 -0
- qiskit/circuit/library/iqp.py +180 -0
- qiskit/circuit/library/n_local/__init__.py +45 -0
- qiskit/circuit/library/n_local/efficient_su2.py +282 -0
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +520 -0
- qiskit/circuit/library/n_local/excitation_preserving.py +303 -0
- qiskit/circuit/library/n_local/n_local.py +1477 -0
- qiskit/circuit/library/n_local/pauli_two_design.py +246 -0
- qiskit/circuit/library/n_local/qaoa_ansatz.py +367 -0
- qiskit/circuit/library/n_local/real_amplitudes.py +312 -0
- qiskit/circuit/library/n_local/two_local.py +289 -0
- qiskit/circuit/library/overlap.py +183 -0
- qiskit/circuit/library/pauli_evolution.py +201 -0
- qiskit/circuit/library/phase_estimation.py +177 -0
- qiskit/circuit/library/phase_oracle.py +239 -0
- qiskit/circuit/library/quantum_volume.py +180 -0
- qiskit/circuit/library/standard_gates/__init__.py +141 -0
- qiskit/circuit/library/standard_gates/dcx.py +77 -0
- qiskit/circuit/library/standard_gates/ecr.py +129 -0
- qiskit/circuit/library/standard_gates/equivalence_library.py +1800 -0
- qiskit/circuit/library/standard_gates/global_phase.py +84 -0
- qiskit/circuit/library/standard_gates/h.py +253 -0
- qiskit/circuit/library/standard_gates/i.py +76 -0
- qiskit/circuit/library/standard_gates/iswap.py +133 -0
- qiskit/circuit/library/standard_gates/p.py +422 -0
- qiskit/circuit/library/standard_gates/r.py +114 -0
- qiskit/circuit/library/standard_gates/rx.py +293 -0
- qiskit/circuit/library/standard_gates/rxx.py +180 -0
- qiskit/circuit/library/standard_gates/ry.py +286 -0
- qiskit/circuit/library/standard_gates/ryy.py +180 -0
- qiskit/circuit/library/standard_gates/rz.py +307 -0
- qiskit/circuit/library/standard_gates/rzx.py +226 -0
- qiskit/circuit/library/standard_gates/rzz.py +193 -0
- qiskit/circuit/library/standard_gates/s.py +419 -0
- qiskit/circuit/library/standard_gates/swap.py +281 -0
- qiskit/circuit/library/standard_gates/sx.py +310 -0
- qiskit/circuit/library/standard_gates/t.py +178 -0
- qiskit/circuit/library/standard_gates/u.py +395 -0
- qiskit/circuit/library/standard_gates/u1.py +490 -0
- qiskit/circuit/library/standard_gates/u2.py +145 -0
- qiskit/circuit/library/standard_gates/u3.py +428 -0
- qiskit/circuit/library/standard_gates/x.py +1481 -0
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +202 -0
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +236 -0
- qiskit/circuit/library/standard_gates/y.py +257 -0
- qiskit/circuit/library/standard_gates/z.py +338 -0
- qiskit/circuit/library/templates/__init__.py +92 -0
- qiskit/circuit/library/templates/clifford/__init__.py +33 -0
- qiskit/circuit/library/templates/clifford/clifford_2_1.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +35 -0
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +34 -0
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +35 -0
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +37 -0
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +38 -0
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +40 -0
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +42 -0
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +42 -0
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +41 -0
- qiskit/circuit/library/templates/nct/__init__.py +67 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +34 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +35 -0
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +37 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +39 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +40 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +41 -0
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +45 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +43 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +44 -0
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +44 -0
- qiskit/circuit/library/templates/rzx/__init__.py +25 -0
- qiskit/circuit/library/templates/rzx/rzx_cy.py +47 -0
- qiskit/circuit/library/templates/rzx/rzx_xz.py +54 -0
- qiskit/circuit/library/templates/rzx/rzx_yz.py +45 -0
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +69 -0
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +59 -0
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +59 -0
- qiskit/circuit/measure.py +53 -0
- qiskit/circuit/operation.py +68 -0
- qiskit/circuit/parameter.py +179 -0
- qiskit/circuit/parameterexpression.py +703 -0
- qiskit/circuit/parametertable.py +119 -0
- qiskit/circuit/parametervector.py +140 -0
- qiskit/circuit/quantumcircuit.py +7540 -0
- qiskit/circuit/quantumcircuitdata.py +136 -0
- qiskit/circuit/random/__init__.py +15 -0
- qiskit/circuit/random/utils.py +366 -0
- qiskit/circuit/reset.py +37 -0
- qiskit/circuit/singleton.py +600 -0
- qiskit/circuit/store.py +89 -0
- qiskit/circuit/tools/__init__.py +16 -0
- qiskit/circuit/tools/pi_check.py +193 -0
- qiskit/circuit/twirling.py +145 -0
- qiskit/compiler/__init__.py +27 -0
- qiskit/compiler/transpiler.py +375 -0
- qiskit/converters/__init__.py +74 -0
- qiskit/converters/circuit_to_dag.py +80 -0
- qiskit/converters/circuit_to_dagdependency.py +49 -0
- qiskit/converters/circuit_to_dagdependency_v2.py +46 -0
- qiskit/converters/circuit_to_gate.py +107 -0
- qiskit/converters/circuit_to_instruction.py +142 -0
- qiskit/converters/dag_to_circuit.py +79 -0
- qiskit/converters/dag_to_dagdependency.py +54 -0
- qiskit/converters/dag_to_dagdependency_v2.py +43 -0
- qiskit/converters/dagdependency_to_circuit.py +40 -0
- qiskit/converters/dagdependency_to_dag.py +48 -0
- qiskit/dagcircuit/__init__.py +55 -0
- qiskit/dagcircuit/collect_blocks.py +407 -0
- qiskit/dagcircuit/dagcircuit.py +24 -0
- qiskit/dagcircuit/dagdependency.py +612 -0
- qiskit/dagcircuit/dagdependency_v2.py +566 -0
- qiskit/dagcircuit/dagdepnode.py +160 -0
- qiskit/dagcircuit/dagnode.py +188 -0
- qiskit/dagcircuit/exceptions.py +42 -0
- qiskit/exceptions.py +153 -0
- qiskit/passmanager/__init__.py +258 -0
- qiskit/passmanager/base_tasks.py +230 -0
- qiskit/passmanager/compilation_status.py +74 -0
- qiskit/passmanager/exceptions.py +19 -0
- qiskit/passmanager/flow_controllers.py +116 -0
- qiskit/passmanager/passmanager.py +353 -0
- qiskit/primitives/__init__.py +490 -0
- qiskit/primitives/backend_estimator_v2.py +530 -0
- qiskit/primitives/backend_sampler_v2.py +339 -0
- qiskit/primitives/base/__init__.py +20 -0
- qiskit/primitives/base/base_estimator.py +247 -0
- qiskit/primitives/base/base_primitive_job.py +78 -0
- qiskit/primitives/base/base_primitive_v1.py +45 -0
- qiskit/primitives/base/base_result_v1.py +65 -0
- qiskit/primitives/base/base_sampler.py +196 -0
- qiskit/primitives/base/estimator_result_v1.py +46 -0
- qiskit/primitives/base/sampler_result_v1.py +45 -0
- qiskit/primitives/base/validation_v1.py +250 -0
- qiskit/primitives/containers/__init__.py +26 -0
- qiskit/primitives/containers/bindings_array.py +391 -0
- qiskit/primitives/containers/bit_array.py +764 -0
- qiskit/primitives/containers/data_bin.py +175 -0
- qiskit/primitives/containers/estimator_pub.py +222 -0
- qiskit/primitives/containers/object_array.py +94 -0
- qiskit/primitives/containers/observables_array.py +296 -0
- qiskit/primitives/containers/primitive_result.py +53 -0
- qiskit/primitives/containers/pub_result.py +51 -0
- qiskit/primitives/containers/sampler_pub.py +193 -0
- qiskit/primitives/containers/sampler_pub_result.py +74 -0
- qiskit/primitives/containers/shape.py +129 -0
- qiskit/primitives/primitive_job.py +81 -0
- qiskit/primitives/statevector_estimator.py +175 -0
- qiskit/primitives/statevector_sampler.py +290 -0
- qiskit/primitives/utils.py +72 -0
- qiskit/providers/__init__.py +677 -0
- qiskit/providers/backend.py +364 -0
- qiskit/providers/basic_provider/__init__.py +47 -0
- qiskit/providers/basic_provider/basic_provider.py +121 -0
- qiskit/providers/basic_provider/basic_provider_job.py +65 -0
- qiskit/providers/basic_provider/basic_provider_tools.py +218 -0
- qiskit/providers/basic_provider/basic_simulator.py +693 -0
- qiskit/providers/basic_provider/exceptions.py +30 -0
- qiskit/providers/exceptions.py +33 -0
- qiskit/providers/fake_provider/__init__.py +69 -0
- qiskit/providers/fake_provider/generic_backend_v2.py +374 -0
- qiskit/providers/fake_provider/utils/__init__.py +15 -0
- qiskit/providers/job.py +147 -0
- qiskit/providers/jobstatus.py +30 -0
- qiskit/providers/options.py +273 -0
- qiskit/providers/providerutils.py +110 -0
- qiskit/qasm/libs/dummy/stdgates.inc +75 -0
- qiskit/qasm/libs/qelib1.inc +266 -0
- qiskit/qasm/libs/stdgates.inc +82 -0
- qiskit/qasm2/__init__.py +669 -0
- qiskit/qasm2/exceptions.py +27 -0
- qiskit/qasm2/export.py +364 -0
- qiskit/qasm2/parse.py +438 -0
- qiskit/qasm3/__init__.py +372 -0
- qiskit/qasm3/ast.py +782 -0
- qiskit/qasm3/exceptions.py +27 -0
- qiskit/qasm3/experimental.py +70 -0
- qiskit/qasm3/exporter.py +1340 -0
- qiskit/qasm3/printer.py +608 -0
- qiskit/qpy/__init__.py +1965 -0
- qiskit/qpy/binary_io/__init__.py +35 -0
- qiskit/qpy/binary_io/circuits.py +1455 -0
- qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
- qiskit/qpy/binary_io/schedules.py +308 -0
- qiskit/qpy/binary_io/value.py +1165 -0
- qiskit/qpy/common.py +353 -0
- qiskit/qpy/exceptions.py +53 -0
- qiskit/qpy/formats.py +442 -0
- qiskit/qpy/interface.py +344 -0
- qiskit/qpy/type_keys.py +409 -0
- qiskit/quantum_info/__init__.py +162 -0
- qiskit/quantum_info/analysis/__init__.py +17 -0
- qiskit/quantum_info/analysis/average.py +47 -0
- qiskit/quantum_info/analysis/distance.py +104 -0
- qiskit/quantum_info/analysis/make_observable.py +44 -0
- qiskit/quantum_info/analysis/z2_symmetries.py +484 -0
- qiskit/quantum_info/operators/__init__.py +28 -0
- qiskit/quantum_info/operators/base_operator.py +145 -0
- qiskit/quantum_info/operators/channel/__init__.py +29 -0
- qiskit/quantum_info/operators/channel/chi.py +191 -0
- qiskit/quantum_info/operators/channel/choi.py +218 -0
- qiskit/quantum_info/operators/channel/kraus.py +337 -0
- qiskit/quantum_info/operators/channel/ptm.py +204 -0
- qiskit/quantum_info/operators/channel/quantum_channel.py +348 -0
- qiskit/quantum_info/operators/channel/stinespring.py +296 -0
- qiskit/quantum_info/operators/channel/superop.py +373 -0
- qiskit/quantum_info/operators/channel/transformations.py +490 -0
- qiskit/quantum_info/operators/custom_iterator.py +48 -0
- qiskit/quantum_info/operators/dihedral/__init__.py +18 -0
- qiskit/quantum_info/operators/dihedral/dihedral.py +511 -0
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +216 -0
- qiskit/quantum_info/operators/dihedral/polynomial.py +313 -0
- qiskit/quantum_info/operators/dihedral/random.py +64 -0
- qiskit/quantum_info/operators/linear_op.py +25 -0
- qiskit/quantum_info/operators/measures.py +418 -0
- qiskit/quantum_info/operators/mixins/__init__.py +52 -0
- qiskit/quantum_info/operators/mixins/adjoint.py +52 -0
- qiskit/quantum_info/operators/mixins/group.py +171 -0
- qiskit/quantum_info/operators/mixins/linear.py +84 -0
- qiskit/quantum_info/operators/mixins/multiply.py +62 -0
- qiskit/quantum_info/operators/mixins/tolerances.py +72 -0
- qiskit/quantum_info/operators/op_shape.py +525 -0
- qiskit/quantum_info/operators/operator.py +869 -0
- qiskit/quantum_info/operators/operator_utils.py +76 -0
- qiskit/quantum_info/operators/predicates.py +183 -0
- qiskit/quantum_info/operators/random.py +154 -0
- qiskit/quantum_info/operators/scalar_op.py +254 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +23 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +719 -0
- qiskit/quantum_info/operators/symplectic/clifford.py +1032 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +558 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +755 -0
- qiskit/quantum_info/operators/symplectic/pauli_list.py +1242 -0
- qiskit/quantum_info/operators/symplectic/pauli_utils.py +40 -0
- qiskit/quantum_info/operators/symplectic/random.py +117 -0
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1239 -0
- qiskit/quantum_info/operators/utils/__init__.py +20 -0
- qiskit/quantum_info/operators/utils/anti_commutator.py +36 -0
- qiskit/quantum_info/operators/utils/commutator.py +36 -0
- qiskit/quantum_info/operators/utils/double_commutator.py +76 -0
- qiskit/quantum_info/quaternion.py +156 -0
- qiskit/quantum_info/random.py +26 -0
- qiskit/quantum_info/states/__init__.py +28 -0
- qiskit/quantum_info/states/densitymatrix.py +857 -0
- qiskit/quantum_info/states/measures.py +288 -0
- qiskit/quantum_info/states/quantum_state.py +503 -0
- qiskit/quantum_info/states/random.py +157 -0
- qiskit/quantum_info/states/stabilizerstate.py +805 -0
- qiskit/quantum_info/states/statevector.py +977 -0
- qiskit/quantum_info/states/utils.py +247 -0
- qiskit/result/__init__.py +61 -0
- qiskit/result/counts.py +189 -0
- qiskit/result/distributions/__init__.py +17 -0
- qiskit/result/distributions/probability.py +100 -0
- qiskit/result/distributions/quasi.py +154 -0
- qiskit/result/exceptions.py +40 -0
- qiskit/result/models.py +241 -0
- qiskit/result/postprocess.py +239 -0
- qiskit/result/result.py +385 -0
- qiskit/result/sampled_expval.py +74 -0
- qiskit/result/utils.py +294 -0
- qiskit/synthesis/__init__.py +240 -0
- qiskit/synthesis/arithmetic/__init__.py +18 -0
- qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
- qiskit/synthesis/arithmetic/comparators/__init__.py +16 -0
- qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
- qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
- qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +103 -0
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +100 -0
- qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
- qiskit/synthesis/boolean/__init__.py +13 -0
- qiskit/synthesis/boolean/boolean_expression.py +231 -0
- qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
- qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
- qiskit/synthesis/clifford/__init__.py +19 -0
- qiskit/synthesis/clifford/clifford_decompose_ag.py +178 -0
- qiskit/synthesis/clifford/clifford_decompose_bm.py +46 -0
- qiskit/synthesis/clifford/clifford_decompose_full.py +64 -0
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +58 -0
- qiskit/synthesis/clifford/clifford_decompose_layers.py +447 -0
- qiskit/synthesis/cnotdihedral/__init__.py +17 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +52 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +141 -0
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_two_qubits.py +266 -0
- qiskit/synthesis/discrete_basis/__init__.py +16 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +265 -0
- qiskit/synthesis/discrete_basis/gate_sequence.py +421 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +165 -0
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +240 -0
- qiskit/synthesis/evolution/__init__.py +21 -0
- qiskit/synthesis/evolution/evolution_synthesis.py +48 -0
- qiskit/synthesis/evolution/lie_trotter.py +120 -0
- qiskit/synthesis/evolution/matrix_synthesis.py +47 -0
- qiskit/synthesis/evolution/pauli_network.py +80 -0
- qiskit/synthesis/evolution/product_formula.py +313 -0
- qiskit/synthesis/evolution/qdrift.py +130 -0
- qiskit/synthesis/evolution/suzuki_trotter.py +224 -0
- qiskit/synthesis/linear/__init__.py +26 -0
- qiskit/synthesis/linear/cnot_synth.py +69 -0
- qiskit/synthesis/linear/linear_circuits_utils.py +128 -0
- qiskit/synthesis/linear/linear_depth_lnn.py +61 -0
- qiskit/synthesis/linear/linear_matrix_utils.py +27 -0
- qiskit/synthesis/linear_phase/__init__.py +17 -0
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +206 -0
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +61 -0
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +58 -0
- qiskit/synthesis/multi_controlled/__init__.py +25 -0
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +359 -0
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
- qiskit/synthesis/one_qubit/__init__.py +15 -0
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +288 -0
- qiskit/synthesis/permutation/__init__.py +18 -0
- qiskit/synthesis/permutation/permutation_full.py +78 -0
- qiskit/synthesis/permutation/permutation_lnn.py +54 -0
- qiskit/synthesis/permutation/permutation_reverse_lnn.py +93 -0
- qiskit/synthesis/permutation/permutation_utils.py +16 -0
- qiskit/synthesis/qft/__init__.py +16 -0
- qiskit/synthesis/qft/qft_decompose_full.py +97 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +79 -0
- qiskit/synthesis/stabilizer/__init__.py +16 -0
- qiskit/synthesis/stabilizer/stabilizer_circuit.py +149 -0
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +194 -0
- qiskit/synthesis/two_qubit/__init__.py +20 -0
- qiskit/synthesis/two_qubit/local_invariance.py +63 -0
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +583 -0
- qiskit/synthesis/two_qubit/xx_decompose/__init__.py +19 -0
- qiskit/synthesis/two_qubit/xx_decompose/circuits.py +300 -0
- qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +324 -0
- qiskit/synthesis/two_qubit/xx_decompose/embodiments.py +163 -0
- qiskit/synthesis/two_qubit/xx_decompose/paths.py +412 -0
- qiskit/synthesis/two_qubit/xx_decompose/polytopes.py +262 -0
- qiskit/synthesis/two_qubit/xx_decompose/utilities.py +40 -0
- qiskit/synthesis/two_qubit/xx_decompose/weyl.py +133 -0
- qiskit/synthesis/unitary/__init__.py +13 -0
- qiskit/synthesis/unitary/aqc/__init__.py +177 -0
- qiskit/synthesis/unitary/aqc/approximate.py +116 -0
- qiskit/synthesis/unitary/aqc/aqc.py +175 -0
- qiskit/synthesis/unitary/aqc/cnot_structures.py +300 -0
- qiskit/synthesis/unitary/aqc/cnot_unit_circuit.py +103 -0
- qiskit/synthesis/unitary/aqc/cnot_unit_objective.py +299 -0
- qiskit/synthesis/unitary/aqc/elementary_operations.py +108 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/__init__.py +164 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_grad_utils.py +237 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +226 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/layer.py +370 -0
- qiskit/synthesis/unitary/aqc/fast_gradient/pmatrix.py +312 -0
- qiskit/synthesis/unitary/qsd.py +288 -0
- qiskit/transpiler/__init__.py +1345 -0
- qiskit/transpiler/basepasses.py +190 -0
- qiskit/transpiler/coupling.py +500 -0
- qiskit/transpiler/exceptions.py +59 -0
- qiskit/transpiler/instruction_durations.py +281 -0
- qiskit/transpiler/layout.py +740 -0
- qiskit/transpiler/passes/__init__.py +276 -0
- qiskit/transpiler/passes/analysis/__init__.py +23 -0
- qiskit/transpiler/passes/analysis/count_ops.py +30 -0
- qiskit/transpiler/passes/analysis/count_ops_longest_path.py +26 -0
- qiskit/transpiler/passes/analysis/dag_longest_path.py +24 -0
- qiskit/transpiler/passes/analysis/depth.py +33 -0
- qiskit/transpiler/passes/analysis/num_qubits.py +26 -0
- qiskit/transpiler/passes/analysis/num_tensor_factors.py +26 -0
- qiskit/transpiler/passes/analysis/resource_estimation.py +41 -0
- qiskit/transpiler/passes/analysis/size.py +36 -0
- qiskit/transpiler/passes/analysis/width.py +27 -0
- qiskit/transpiler/passes/basis/__init__.py +19 -0
- qiskit/transpiler/passes/basis/basis_translator.py +138 -0
- qiskit/transpiler/passes/basis/decompose.py +137 -0
- qiskit/transpiler/passes/basis/translate_parameterized.py +175 -0
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +84 -0
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +110 -0
- qiskit/transpiler/passes/layout/__init__.py +26 -0
- qiskit/transpiler/passes/layout/_csp_custom_solver.py +65 -0
- qiskit/transpiler/passes/layout/apply_layout.py +128 -0
- qiskit/transpiler/passes/layout/csp_layout.py +132 -0
- qiskit/transpiler/passes/layout/dense_layout.py +177 -0
- qiskit/transpiler/passes/layout/disjoint_utils.py +219 -0
- qiskit/transpiler/passes/layout/enlarge_with_ancilla.py +49 -0
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +116 -0
- qiskit/transpiler/passes/layout/layout_2q_distance.py +77 -0
- qiskit/transpiler/passes/layout/sabre_layout.py +506 -0
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +225 -0
- qiskit/transpiler/passes/layout/set_layout.py +69 -0
- qiskit/transpiler/passes/layout/trivial_layout.py +66 -0
- qiskit/transpiler/passes/layout/vf2_layout.py +256 -0
- qiskit/transpiler/passes/layout/vf2_post_layout.py +376 -0
- qiskit/transpiler/passes/layout/vf2_utils.py +235 -0
- qiskit/transpiler/passes/optimization/__init__.py +42 -0
- qiskit/transpiler/passes/optimization/_gate_extension.py +80 -0
- qiskit/transpiler/passes/optimization/collect_1q_runs.py +31 -0
- qiskit/transpiler/passes/optimization/collect_2q_blocks.py +35 -0
- qiskit/transpiler/passes/optimization/collect_and_collapse.py +117 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +109 -0
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +85 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +242 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +44 -0
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +82 -0
- qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +140 -0
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +176 -0
- qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
- qiskit/transpiler/passes/optimization/elide_permutations.py +91 -0
- qiskit/transpiler/passes/optimization/hoare_opt.py +420 -0
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +95 -0
- qiskit/transpiler/passes/optimization/light_cone.py +135 -0
- qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +267 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +250 -0
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +384 -0
- qiskit/transpiler/passes/optimization/optimize_annotated.py +449 -0
- qiskit/transpiler/passes/optimization/optimize_cliffords.py +89 -0
- qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +71 -0
- qiskit/transpiler/passes/optimization/remove_diagonal_gates_before_measure.py +41 -0
- qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +70 -0
- qiskit/transpiler/passes/optimization/remove_reset_in_zero_state.py +37 -0
- qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +50 -0
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +63 -0
- qiskit/transpiler/passes/optimization/template_matching/__init__.py +19 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +749 -0
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +452 -0
- qiskit/transpiler/passes/optimization/template_matching/maximal_matches.py +77 -0
- qiskit/transpiler/passes/optimization/template_matching/template_matching.py +370 -0
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +639 -0
- qiskit/transpiler/passes/optimization/template_optimization.py +158 -0
- qiskit/transpiler/passes/routing/__init__.py +21 -0
- qiskit/transpiler/passes/routing/algorithms/__init__.py +33 -0
- qiskit/transpiler/passes/routing/algorithms/token_swapper.py +105 -0
- qiskit/transpiler/passes/routing/algorithms/types.py +46 -0
- qiskit/transpiler/passes/routing/algorithms/util.py +103 -0
- qiskit/transpiler/passes/routing/basic_swap.py +166 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/__init__.py +25 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_block.py +60 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +397 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/pauli_2q_evolution_commutation.py +145 -0
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +306 -0
- qiskit/transpiler/passes/routing/layout_transformation.py +119 -0
- qiskit/transpiler/passes/routing/lookahead_swap.py +390 -0
- qiskit/transpiler/passes/routing/sabre_swap.py +463 -0
- qiskit/transpiler/passes/routing/star_prerouting.py +408 -0
- qiskit/transpiler/passes/routing/utils.py +35 -0
- qiskit/transpiler/passes/scheduling/__init__.py +21 -0
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +79 -0
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +70 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +251 -0
- qiskit/transpiler/passes/scheduling/padding/__init__.py +16 -0
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +284 -0
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +415 -0
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +90 -0
- qiskit/transpiler/passes/scheduling/scheduling/__init__.py +17 -0
- qiskit/transpiler/passes/scheduling/scheduling/alap.py +93 -0
- qiskit/transpiler/passes/scheduling/scheduling/asap.py +100 -0
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +88 -0
- qiskit/transpiler/passes/scheduling/scheduling/set_io_latency.py +64 -0
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +237 -0
- qiskit/transpiler/passes/synthesis/__init__.py +20 -0
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +153 -0
- qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +429 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +1963 -0
- qiskit/transpiler/passes/synthesis/linear_functions_synthesis.py +41 -0
- qiskit/transpiler/passes/synthesis/plugin.py +738 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +313 -0
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +425 -0
- qiskit/transpiler/passes/utils/__init__.py +32 -0
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +41 -0
- qiskit/transpiler/passes/utils/check_gate_direction.py +60 -0
- qiskit/transpiler/passes/utils/check_map.py +78 -0
- qiskit/transpiler/passes/utils/contains_instruction.py +45 -0
- qiskit/transpiler/passes/utils/control_flow.py +61 -0
- qiskit/transpiler/passes/utils/dag_fixed_point.py +36 -0
- qiskit/transpiler/passes/utils/error.py +69 -0
- qiskit/transpiler/passes/utils/filter_op_nodes.py +66 -0
- qiskit/transpiler/passes/utils/fixed_point.py +48 -0
- qiskit/transpiler/passes/utils/gate_direction.py +93 -0
- qiskit/transpiler/passes/utils/gates_basis.py +51 -0
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +163 -0
- qiskit/transpiler/passes/utils/minimum_point.py +118 -0
- qiskit/transpiler/passes/utils/remove_barriers.py +50 -0
- qiskit/transpiler/passes/utils/remove_final_measurements.py +121 -0
- qiskit/transpiler/passes/utils/unroll_forloops.py +81 -0
- qiskit/transpiler/passmanager.py +503 -0
- qiskit/transpiler/passmanager_config.py +151 -0
- qiskit/transpiler/preset_passmanagers/__init__.py +93 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +993 -0
- qiskit/transpiler/preset_passmanagers/common.py +672 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +437 -0
- qiskit/transpiler/preset_passmanagers/level0.py +104 -0
- qiskit/transpiler/preset_passmanagers/level1.py +108 -0
- qiskit/transpiler/preset_passmanagers/level2.py +109 -0
- qiskit/transpiler/preset_passmanagers/level3.py +110 -0
- qiskit/transpiler/preset_passmanagers/plugin.py +346 -0
- qiskit/transpiler/target.py +905 -0
- qiskit/transpiler/timing_constraints.py +59 -0
- qiskit/user_config.py +266 -0
- qiskit/utils/__init__.py +90 -0
- qiskit/utils/classtools.py +146 -0
- qiskit/utils/deprecation.py +382 -0
- qiskit/utils/lazy_tester.py +363 -0
- qiskit/utils/optionals.py +354 -0
- qiskit/utils/parallel.py +318 -0
- qiskit/utils/units.py +146 -0
- qiskit/version.py +84 -0
- qiskit/visualization/__init__.py +290 -0
- qiskit/visualization/array.py +207 -0
- qiskit/visualization/bloch.py +778 -0
- qiskit/visualization/circuit/__init__.py +15 -0
- qiskit/visualization/circuit/_utils.py +675 -0
- qiskit/visualization/circuit/circuit_visualization.py +735 -0
- qiskit/visualization/circuit/latex.py +661 -0
- qiskit/visualization/circuit/matplotlib.py +2019 -0
- qiskit/visualization/circuit/qcstyle.py +278 -0
- qiskit/visualization/circuit/styles/__init__.py +13 -0
- qiskit/visualization/circuit/styles/bw.json +202 -0
- qiskit/visualization/circuit/styles/clifford.json +202 -0
- qiskit/visualization/circuit/styles/iqp-dark.json +214 -0
- qiskit/visualization/circuit/styles/iqp.json +214 -0
- qiskit/visualization/circuit/styles/textbook.json +202 -0
- qiskit/visualization/circuit/text.py +1849 -0
- qiskit/visualization/circuit_visualization.py +19 -0
- qiskit/visualization/counts_visualization.py +487 -0
- qiskit/visualization/dag_visualization.py +318 -0
- qiskit/visualization/exceptions.py +21 -0
- qiskit/visualization/gate_map.py +1424 -0
- qiskit/visualization/library.py +40 -0
- qiskit/visualization/pass_manager_visualization.py +312 -0
- qiskit/visualization/state_visualization.py +1546 -0
- qiskit/visualization/timeline/__init__.py +21 -0
- qiskit/visualization/timeline/core.py +495 -0
- qiskit/visualization/timeline/drawings.py +260 -0
- qiskit/visualization/timeline/generators.py +506 -0
- qiskit/visualization/timeline/interface.py +444 -0
- qiskit/visualization/timeline/layouts.py +115 -0
- qiskit/visualization/timeline/plotters/__init__.py +16 -0
- qiskit/visualization/timeline/plotters/base_plotter.py +58 -0
- qiskit/visualization/timeline/plotters/matplotlib.py +195 -0
- qiskit/visualization/timeline/stylesheet.py +301 -0
- qiskit/visualization/timeline/types.py +148 -0
- qiskit/visualization/transition_visualization.py +369 -0
- qiskit/visualization/utils.py +49 -0
- qiskit-2.0.3.dist-info/METADATA +220 -0
- qiskit-2.0.3.dist-info/RECORD +690 -0
- qiskit-2.0.3.dist-info/WHEEL +6 -0
- qiskit-2.0.3.dist-info/entry_points.txt +82 -0
- qiskit-2.0.3.dist-info/licenses/LICENSE.txt +203 -0
- qiskit-2.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2018.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Init for circuit visualizations"""
|
14
|
+
|
15
|
+
from .circuit_visualization import circuit_drawer
|
@@ -0,0 +1,675 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2018.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Common circuit visualization utilities."""
|
14
|
+
|
15
|
+
import re
|
16
|
+
from collections import OrderedDict
|
17
|
+
from warnings import warn
|
18
|
+
|
19
|
+
import numpy as np
|
20
|
+
|
21
|
+
from qiskit.circuit import (
|
22
|
+
ClassicalRegister,
|
23
|
+
Clbit,
|
24
|
+
ControlFlowOp,
|
25
|
+
ControlledGate,
|
26
|
+
Delay,
|
27
|
+
Gate,
|
28
|
+
Instruction,
|
29
|
+
Measure,
|
30
|
+
QuantumCircuit,
|
31
|
+
Qubit,
|
32
|
+
)
|
33
|
+
from qiskit.circuit.annotated_operation import AnnotatedOperation, InverseModifier, PowerModifier
|
34
|
+
from qiskit.circuit.controlflow import condition_resources
|
35
|
+
from qiskit.circuit.library import PauliEvolutionGate, PhaseOracleGate, BitFlipOracleGate
|
36
|
+
from qiskit.circuit.tools import pi_check
|
37
|
+
from qiskit.converters import circuit_to_dag
|
38
|
+
from qiskit.utils import optionals as _optionals
|
39
|
+
|
40
|
+
from ..exceptions import VisualizationError
|
41
|
+
|
42
|
+
|
43
|
+
def _is_boolean_expression(gate_text, op):
|
44
|
+
return isinstance(op, (PhaseOracleGate, BitFlipOracleGate)) and gate_text == op.label
|
45
|
+
|
46
|
+
|
47
|
+
def get_gate_ctrl_text(op, drawer, style=None):
|
48
|
+
"""Load the gate_text and ctrl_text strings based on names and labels"""
|
49
|
+
anno_list = []
|
50
|
+
anno_text = ""
|
51
|
+
if isinstance(op, AnnotatedOperation) and op.modifiers:
|
52
|
+
for modifier in op.modifiers:
|
53
|
+
if isinstance(modifier, InverseModifier):
|
54
|
+
anno_list.append("Inv")
|
55
|
+
elif isinstance(modifier, PowerModifier):
|
56
|
+
anno_list.append("Pow(" + str(round(modifier.power, 1)) + ")")
|
57
|
+
anno_text = ", ".join(anno_list)
|
58
|
+
|
59
|
+
op_label = getattr(op, "label", None)
|
60
|
+
op_type = type(op)
|
61
|
+
base_name = base_label = base_type = None
|
62
|
+
if hasattr(op, "base_gate"):
|
63
|
+
base_name = op.base_gate.name
|
64
|
+
base_label = op.base_gate.label
|
65
|
+
base_type = type(op.base_gate)
|
66
|
+
if hasattr(op, "base_op"):
|
67
|
+
base_name = op.base_op.name
|
68
|
+
ctrl_text = None
|
69
|
+
|
70
|
+
if base_label:
|
71
|
+
gate_text = base_label
|
72
|
+
ctrl_text = op_label
|
73
|
+
elif op_label and isinstance(op, ControlledGate):
|
74
|
+
gate_text = base_name
|
75
|
+
ctrl_text = op_label
|
76
|
+
elif op_label:
|
77
|
+
gate_text = op_label
|
78
|
+
elif base_name:
|
79
|
+
gate_text = base_name
|
80
|
+
else:
|
81
|
+
gate_text = op.name
|
82
|
+
|
83
|
+
# raw_gate_text is used in color selection in mpl instead of op.name, since
|
84
|
+
# if it's a controlled gate, the color will likely not be the base_name color
|
85
|
+
raw_gate_text = op.name if gate_text == base_name else gate_text
|
86
|
+
|
87
|
+
# For mpl and latex drawers, check style['disptex'] in qcstyle.py
|
88
|
+
if drawer != "text" and gate_text in style["disptex"]:
|
89
|
+
# First check if this entry is in the old style disptex that
|
90
|
+
# included "$\\mathrm{ }$". If so, take it as is.
|
91
|
+
if style["disptex"][gate_text][0] == "$" and style["disptex"][gate_text][-1] == "$":
|
92
|
+
gate_text = style["disptex"][gate_text]
|
93
|
+
else:
|
94
|
+
gate_text = f"$\\mathrm{{{style['disptex'][gate_text]}}}$"
|
95
|
+
|
96
|
+
elif drawer == "latex":
|
97
|
+
# Special formatting for Booleans in latex (due to '~' causing crash)
|
98
|
+
if _is_boolean_expression(gate_text, op):
|
99
|
+
gate_text = gate_text.replace("~", "$\\neg$").replace("&", "\\&")
|
100
|
+
gate_text = f"$\\texttt{{{gate_text}}}$"
|
101
|
+
# Capitalize if not a user-created gate or instruction
|
102
|
+
elif (
|
103
|
+
(gate_text == op.name and op_type not in (Gate, Instruction))
|
104
|
+
or (gate_text == base_name and base_type not in (Gate, Instruction))
|
105
|
+
) and (op_type is not PauliEvolutionGate):
|
106
|
+
gate_text = f"$\\mathrm{{{gate_text.capitalize()}}}$"
|
107
|
+
else:
|
108
|
+
gate_text = f"$\\mathrm{{{gate_text}}}$"
|
109
|
+
# Remove mathmode _, ^, and - formatting from user names and labels
|
110
|
+
gate_text = gate_text.replace("_", "\\_")
|
111
|
+
gate_text = gate_text.replace("^", "\\string^")
|
112
|
+
gate_text = gate_text.replace("-", "\\mbox{-}")
|
113
|
+
ctrl_text = f"$\\mathrm{{{ctrl_text}}}$"
|
114
|
+
|
115
|
+
# Only capitalize internally-created gate or instruction names
|
116
|
+
elif (
|
117
|
+
(gate_text == op.name and op_type not in (Gate, Instruction))
|
118
|
+
or (gate_text == base_name and base_type not in (Gate, Instruction))
|
119
|
+
) and (op_type is not PauliEvolutionGate):
|
120
|
+
gate_text = gate_text.capitalize()
|
121
|
+
|
122
|
+
if anno_text:
|
123
|
+
gate_text += " - " + anno_text
|
124
|
+
|
125
|
+
return gate_text, ctrl_text, raw_gate_text
|
126
|
+
|
127
|
+
|
128
|
+
def get_param_str(op, drawer, ndigits=3):
|
129
|
+
"""Get the params as a string to add to the gate text display"""
|
130
|
+
if (
|
131
|
+
not hasattr(op, "params")
|
132
|
+
or any(isinstance(param, np.ndarray) for param in op.params)
|
133
|
+
or any(isinstance(param, QuantumCircuit) for param in op.params)
|
134
|
+
):
|
135
|
+
return ""
|
136
|
+
|
137
|
+
if isinstance(op, Delay):
|
138
|
+
param_list = [f"{op.params[0]}[{op.unit}]"]
|
139
|
+
else:
|
140
|
+
param_list = []
|
141
|
+
for count, param in enumerate(op.params):
|
142
|
+
# Latex drawer will cause an xy-pic error and mpl drawer will overwrite
|
143
|
+
# the right edge if param string too long, so limit params.
|
144
|
+
if (drawer == "latex" and count > 3) or (drawer == "mpl" and count > 15):
|
145
|
+
param_list.append("...")
|
146
|
+
break
|
147
|
+
try:
|
148
|
+
param_list.append(pi_check(param, output=drawer, ndigits=ndigits))
|
149
|
+
except TypeError:
|
150
|
+
param_list.append(str(param))
|
151
|
+
|
152
|
+
param_str = ""
|
153
|
+
if param_list:
|
154
|
+
if drawer == "latex":
|
155
|
+
param_str = f"\\,(\\mathrm{{{','.join(param_list)}}})"
|
156
|
+
elif drawer == "mpl":
|
157
|
+
param_str = f"{', '.join(param_list)}".replace("-", "$-$")
|
158
|
+
else:
|
159
|
+
param_str = f"({','.join(param_list)})"
|
160
|
+
|
161
|
+
return param_str
|
162
|
+
|
163
|
+
|
164
|
+
def get_wire_map(circuit, bits, cregbundle):
|
165
|
+
"""Map the bits and registers to the index from the top of the drawing.
|
166
|
+
The key to the dict is either the (Qubit, Clbit) or if cregbundle True,
|
167
|
+
the register that is being bundled.
|
168
|
+
|
169
|
+
Args:
|
170
|
+
circuit (QuantumCircuit): the circuit being drawn
|
171
|
+
bits (list(Qubit, Clbit)): the Qubit's and Clbit's in the circuit
|
172
|
+
cregbundle (bool): if True bundle classical registers. Default: ``True``.
|
173
|
+
|
174
|
+
Returns:
|
175
|
+
dict((Qubit, Clbit, ClassicalRegister): index): map of bits/registers
|
176
|
+
to index
|
177
|
+
"""
|
178
|
+
prev_reg = None
|
179
|
+
wire_index = 0
|
180
|
+
wire_map = {}
|
181
|
+
for bit in bits:
|
182
|
+
register = get_bit_register(circuit, bit)
|
183
|
+
if register is None or not isinstance(bit, Clbit) or not cregbundle:
|
184
|
+
wire_map[bit] = wire_index
|
185
|
+
wire_index += 1
|
186
|
+
elif register is not None and cregbundle and register != prev_reg:
|
187
|
+
prev_reg = register
|
188
|
+
wire_map[register] = wire_index
|
189
|
+
wire_index += 1
|
190
|
+
|
191
|
+
return wire_map
|
192
|
+
|
193
|
+
|
194
|
+
def get_bit_register(circuit, bit):
|
195
|
+
"""Get the register for a bit if there is one
|
196
|
+
|
197
|
+
Args:
|
198
|
+
circuit (QuantumCircuit): the circuit being drawn
|
199
|
+
bit (Qubit, Clbit): the bit to use to find the register and indexes
|
200
|
+
|
201
|
+
Returns:
|
202
|
+
ClassicalRegister: register associated with the bit
|
203
|
+
"""
|
204
|
+
bit_loc = circuit.find_bit(bit)
|
205
|
+
return bit_loc.registers[0][0] if bit_loc.registers else None
|
206
|
+
|
207
|
+
|
208
|
+
def get_bit_reg_index(circuit, bit):
|
209
|
+
"""Get the register for a bit if there is one, and the index of the bit
|
210
|
+
from the top of the circuit, or the index of the bit within a register.
|
211
|
+
|
212
|
+
Args:
|
213
|
+
circuit (QuantumCircuit): the circuit being drawn
|
214
|
+
bit (Qubit, Clbit): the bit to use to find the register and indexes
|
215
|
+
|
216
|
+
Returns:
|
217
|
+
(ClassicalRegister, None): register associated with the bit
|
218
|
+
int: index of the bit from the top of the circuit
|
219
|
+
int: index of the bit within the register, if there is a register
|
220
|
+
"""
|
221
|
+
bit_loc = circuit.find_bit(bit)
|
222
|
+
bit_index = bit_loc.index
|
223
|
+
register, reg_index = bit_loc.registers[0] if bit_loc.registers else (None, None)
|
224
|
+
return register, bit_index, reg_index
|
225
|
+
|
226
|
+
|
227
|
+
def get_wire_label(drawer, register, index, layout=None, cregbundle=True):
|
228
|
+
"""Get the bit labels to display to the left of the wires.
|
229
|
+
|
230
|
+
Args:
|
231
|
+
drawer (str): which drawer is calling ("text", "mpl", or "latex")
|
232
|
+
register (QuantumRegister or ClassicalRegister): get wire_label for this register
|
233
|
+
index (int): index of bit in register
|
234
|
+
layout (Layout): Optional. mapping of virtual to physical bits
|
235
|
+
cregbundle (bool): Optional. if set True bundle classical registers.
|
236
|
+
Default: ``True``.
|
237
|
+
|
238
|
+
Returns:
|
239
|
+
str: label to display for the register/index
|
240
|
+
"""
|
241
|
+
index_str = f"{index}" if drawer == "text" else f"{{{index}}}"
|
242
|
+
if register is None:
|
243
|
+
wire_label = index_str
|
244
|
+
return wire_label
|
245
|
+
|
246
|
+
if drawer == "text":
|
247
|
+
reg_name = f"{register.name}"
|
248
|
+
reg_name_index = f"{register.name}_{index}"
|
249
|
+
else:
|
250
|
+
reg_name = f"{{{fix_special_characters(register.name)}}}"
|
251
|
+
reg_name_index = f"{reg_name}_{{{index}}}"
|
252
|
+
|
253
|
+
# Clbits
|
254
|
+
if isinstance(register, ClassicalRegister):
|
255
|
+
if cregbundle and drawer != "latex":
|
256
|
+
wire_label = f"{register.name}"
|
257
|
+
return wire_label
|
258
|
+
|
259
|
+
if register.size == 1 or cregbundle:
|
260
|
+
wire_label = reg_name
|
261
|
+
else:
|
262
|
+
wire_label = reg_name_index
|
263
|
+
return wire_label
|
264
|
+
|
265
|
+
# Qubits
|
266
|
+
if register.size == 1:
|
267
|
+
wire_label = reg_name
|
268
|
+
elif layout is None:
|
269
|
+
wire_label = reg_name_index
|
270
|
+
elif layout[index]:
|
271
|
+
virt_bit = layout[index]
|
272
|
+
try:
|
273
|
+
virt_reg = next(reg for reg in layout.get_registers() if virt_bit in reg)
|
274
|
+
if drawer == "text":
|
275
|
+
wire_label = f"{virt_reg.name}_{virt_reg[:].index(virt_bit)} -> {index}"
|
276
|
+
else:
|
277
|
+
wire_label = (
|
278
|
+
f"{{{virt_reg.name}}}_{{{virt_reg[:].index(virt_bit)}}} \\mapsto {{{index}}}"
|
279
|
+
)
|
280
|
+
except StopIteration:
|
281
|
+
if virt_bit._register is not None:
|
282
|
+
virt_reg = virt_bit._register
|
283
|
+
if drawer == "text":
|
284
|
+
wire_label = f"{virt_reg.name}_{virt_reg[:].index(virt_bit)} -> {index}"
|
285
|
+
else:
|
286
|
+
wire_label = (
|
287
|
+
f"{{{virt_reg.name}}}_"
|
288
|
+
f"{{{virt_reg[:].index(virt_bit)}}} "
|
289
|
+
f"\\mapsto {{{index}}}"
|
290
|
+
)
|
291
|
+
else:
|
292
|
+
if drawer == "text":
|
293
|
+
wire_label = f"{index_str} -> {index}"
|
294
|
+
else:
|
295
|
+
wire_label = f"{index_str} \\mapsto {{{index}}}"
|
296
|
+
if drawer != "text":
|
297
|
+
wire_label = wire_label.replace(" ", "\\;") # use wider spaces
|
298
|
+
else:
|
299
|
+
wire_label = index_str
|
300
|
+
|
301
|
+
return wire_label
|
302
|
+
|
303
|
+
|
304
|
+
def get_condition_label_val(condition, circuit, cregbundle):
|
305
|
+
"""Get the label and value list to display a condition
|
306
|
+
|
307
|
+
Args:
|
308
|
+
condition (Union[Clbit, ClassicalRegister], int): classical condition
|
309
|
+
circuit (QuantumCircuit): the circuit that is being drawn
|
310
|
+
cregbundle (bool): if set True bundle classical registers
|
311
|
+
|
312
|
+
Returns:
|
313
|
+
str: label to display for the condition
|
314
|
+
list(str): list of 1's and 0's indicating values of condition
|
315
|
+
"""
|
316
|
+
cond_is_bit = bool(isinstance(condition[0], Clbit))
|
317
|
+
cond_val = int(condition[1])
|
318
|
+
|
319
|
+
# if condition on a register, return list of 1's and 0's indicating
|
320
|
+
# closed or open, else only one element is returned
|
321
|
+
if isinstance(condition[0], ClassicalRegister) and not cregbundle:
|
322
|
+
val_bits = list(f"{cond_val:0{condition[0].size}b}")[::-1]
|
323
|
+
else:
|
324
|
+
val_bits = list(str(cond_val))
|
325
|
+
|
326
|
+
label = ""
|
327
|
+
if cond_is_bit and cregbundle:
|
328
|
+
register, _, reg_index = get_bit_reg_index(circuit, condition[0])
|
329
|
+
if register is not None:
|
330
|
+
label = f"{register.name}_{reg_index}={hex(cond_val)}"
|
331
|
+
elif not cond_is_bit:
|
332
|
+
label = hex(cond_val)
|
333
|
+
|
334
|
+
return label, val_bits
|
335
|
+
|
336
|
+
|
337
|
+
def fix_special_characters(label):
|
338
|
+
"""
|
339
|
+
Convert any special characters for mpl and latex drawers.
|
340
|
+
Currently only checks for multiple underscores in register names
|
341
|
+
and uses wider space for mpl and latex drawers.
|
342
|
+
|
343
|
+
Args:
|
344
|
+
label (str): the label to fix
|
345
|
+
|
346
|
+
Returns:
|
347
|
+
str: label to display
|
348
|
+
"""
|
349
|
+
label = label.replace("_", r"\_").replace(" ", "\\;")
|
350
|
+
return label
|
351
|
+
|
352
|
+
|
353
|
+
@_optionals.HAS_PYLATEX.require_in_call("the latex and latex_source circuit drawers")
|
354
|
+
def generate_latex_label(label):
|
355
|
+
"""Convert a label to a valid latex string."""
|
356
|
+
from pylatexenc.latexencode import utf8tolatex
|
357
|
+
|
358
|
+
regex = re.compile(r"(?<!\\)\$(.*)(?<!\\)\$")
|
359
|
+
match = regex.search(label)
|
360
|
+
if not match:
|
361
|
+
label = label.replace(r"\$", "$")
|
362
|
+
final_str = utf8tolatex(label, non_ascii_only=True)
|
363
|
+
else:
|
364
|
+
mathmode_string = match.group(1).replace(r"\$", "$")
|
365
|
+
before_match = label[: match.start()]
|
366
|
+
before_match = before_match.replace(r"\$", "$")
|
367
|
+
after_match = label[match.end() :]
|
368
|
+
after_match = after_match.replace(r"\$", "$")
|
369
|
+
final_str = (
|
370
|
+
utf8tolatex(before_match, non_ascii_only=True)
|
371
|
+
+ mathmode_string
|
372
|
+
+ utf8tolatex(after_match, non_ascii_only=True)
|
373
|
+
)
|
374
|
+
return final_str.replace(" ", "\\,") # Put in proper spaces
|
375
|
+
|
376
|
+
|
377
|
+
def _get_valid_justify_arg(justify):
|
378
|
+
"""Returns a valid `justify` argument, warning if necessary."""
|
379
|
+
if isinstance(justify, str):
|
380
|
+
justify = justify.lower()
|
381
|
+
|
382
|
+
if justify is None:
|
383
|
+
justify = "left"
|
384
|
+
|
385
|
+
if justify not in ("left", "right", "none"):
|
386
|
+
# This code should be changed to an error raise, once the deprecation is complete.
|
387
|
+
warn(
|
388
|
+
f"Setting QuantumCircuit.draw()’s or circuit_drawer()'s justify argument: {justify}, to a "
|
389
|
+
"value other than 'left', 'right', 'none' or None (='left'). Default 'left' will be used. "
|
390
|
+
"Support for invalid justify arguments is deprecated as of Qiskit 1.2.0. Starting no "
|
391
|
+
"earlier than 3 months after the release date, invalid arguments will error.",
|
392
|
+
DeprecationWarning,
|
393
|
+
2,
|
394
|
+
)
|
395
|
+
justify = "left"
|
396
|
+
|
397
|
+
return justify
|
398
|
+
|
399
|
+
|
400
|
+
def _get_layered_instructions(
|
401
|
+
circuit, reverse_bits=False, justify=None, idle_wires=True, wire_order=None, wire_map=None
|
402
|
+
):
|
403
|
+
"""
|
404
|
+
Given a circuit, return a tuple (qubits, clbits, nodes) where
|
405
|
+
qubits and clbits are the quantum and classical registers
|
406
|
+
in order (based on reverse_bits or wire_order) and nodes
|
407
|
+
is a list of DAGOpNodes.
|
408
|
+
|
409
|
+
Args:
|
410
|
+
circuit (QuantumCircuit): From where the information is extracted.
|
411
|
+
reverse_bits (bool): If true the order of the bits in the registers is
|
412
|
+
reversed.
|
413
|
+
justify (str) : `left`, `right` or `none`. Defaults to `left`. Says how
|
414
|
+
the circuit should be justified. If an invalid value is provided,
|
415
|
+
default `left` will be used.
|
416
|
+
idle_wires (bool): Include idle wires. Default is True.
|
417
|
+
wire_order (list): A list of ints that modifies the order of the bits.
|
418
|
+
|
419
|
+
Returns:
|
420
|
+
Tuple(list,list,list): To be consumed by the visualizer directly.
|
421
|
+
|
422
|
+
Raises:
|
423
|
+
VisualizationError: if both reverse_bits and wire_order are entered.
|
424
|
+
"""
|
425
|
+
justify = _get_valid_justify_arg(justify)
|
426
|
+
|
427
|
+
if wire_map is not None:
|
428
|
+
qubits = [bit for bit in wire_map if isinstance(bit, Qubit)]
|
429
|
+
else:
|
430
|
+
qubits = circuit.qubits.copy()
|
431
|
+
clbits = circuit.clbits.copy()
|
432
|
+
nodes = []
|
433
|
+
|
434
|
+
# Create a mapping of each register to the max layer number for all measure ops
|
435
|
+
# with that register as the target. Then when an op with condition is seen,
|
436
|
+
# it will be placed to the right of the measure op if the register matches.
|
437
|
+
measure_map = OrderedDict([(c, -1) for c in clbits])
|
438
|
+
|
439
|
+
if reverse_bits and wire_order is not None:
|
440
|
+
raise VisualizationError("Cannot set both reverse_bits and wire_order in the same drawing.")
|
441
|
+
|
442
|
+
if reverse_bits:
|
443
|
+
qubits.reverse()
|
444
|
+
clbits.reverse()
|
445
|
+
elif wire_order is not None:
|
446
|
+
new_qubits = []
|
447
|
+
new_clbits = []
|
448
|
+
for bit in wire_order:
|
449
|
+
if bit < len(qubits):
|
450
|
+
new_qubits.append(qubits[bit])
|
451
|
+
else:
|
452
|
+
new_clbits.append(clbits[bit - len(qubits)])
|
453
|
+
qubits = new_qubits
|
454
|
+
clbits = new_clbits
|
455
|
+
|
456
|
+
dag = circuit_to_dag(circuit)
|
457
|
+
|
458
|
+
if justify == "none":
|
459
|
+
for node in dag.topological_op_nodes():
|
460
|
+
nodes.append([node])
|
461
|
+
else:
|
462
|
+
nodes = _LayerSpooler(dag, qubits, clbits, justify, measure_map)
|
463
|
+
|
464
|
+
if not idle_wires:
|
465
|
+
# Optionally remove all idle wires and instructions that are on them and
|
466
|
+
# on them only.
|
467
|
+
for wire in dag.idle_wires(ignore=["barrier", "delay"]):
|
468
|
+
if wire in qubits:
|
469
|
+
qubits.remove(wire)
|
470
|
+
if wire in clbits:
|
471
|
+
clbits.remove(wire)
|
472
|
+
|
473
|
+
nodes = [[node for node in layer if any(q in qubits for q in node.qargs)] for layer in nodes]
|
474
|
+
|
475
|
+
return qubits, clbits, nodes
|
476
|
+
|
477
|
+
|
478
|
+
def _sorted_nodes(dag_layer):
|
479
|
+
"""Convert DAG layer into list of nodes sorted by node_id
|
480
|
+
qiskit-terra #2802
|
481
|
+
"""
|
482
|
+
nodes = dag_layer["graph"].op_nodes()
|
483
|
+
# sort into the order they were input
|
484
|
+
nodes.sort(key=lambda nd: nd._node_id)
|
485
|
+
return nodes
|
486
|
+
|
487
|
+
|
488
|
+
def _get_gate_span(qubits, node):
|
489
|
+
"""Get the list of qubits drawing this gate would cover
|
490
|
+
qiskit-terra #2802
|
491
|
+
"""
|
492
|
+
min_index = len(qubits)
|
493
|
+
max_index = 0
|
494
|
+
for qreg in node.qargs:
|
495
|
+
index = qubits.index(qreg)
|
496
|
+
|
497
|
+
if index < min_index:
|
498
|
+
min_index = index
|
499
|
+
if index > max_index:
|
500
|
+
max_index = index
|
501
|
+
|
502
|
+
# Because of wrapping boxes for mpl control flow ops, this
|
503
|
+
# type of op must be the only op in the layer
|
504
|
+
if isinstance(node.op, ControlFlowOp):
|
505
|
+
span = qubits
|
506
|
+
elif node.cargs or getattr(node, "condition", None):
|
507
|
+
span = qubits[min_index : len(qubits)]
|
508
|
+
else:
|
509
|
+
span = qubits[min_index : max_index + 1]
|
510
|
+
|
511
|
+
return span
|
512
|
+
|
513
|
+
|
514
|
+
def _any_crossover(qubits, node, nodes):
|
515
|
+
"""Return True .IFF. 'node' crosses over any 'nodes'."""
|
516
|
+
return bool(
|
517
|
+
set(_get_gate_span(qubits, node)).intersection(
|
518
|
+
bit for check_node in nodes for bit in _get_gate_span(qubits, check_node)
|
519
|
+
)
|
520
|
+
)
|
521
|
+
|
522
|
+
|
523
|
+
_GLOBAL_NID = 0
|
524
|
+
|
525
|
+
|
526
|
+
class _LayerSpooler(list):
|
527
|
+
"""Manipulate list of layer dicts for _get_layered_instructions."""
|
528
|
+
|
529
|
+
def __init__(self, dag, qubits, clbits, justification, measure_map):
|
530
|
+
"""Create spool"""
|
531
|
+
super().__init__()
|
532
|
+
self.dag = dag
|
533
|
+
self.qubits = qubits
|
534
|
+
self.clbits = clbits
|
535
|
+
self.justification = justification
|
536
|
+
self.measure_map = measure_map
|
537
|
+
self.cregs = [self.dag.cregs[reg] for reg in self.dag.cregs]
|
538
|
+
|
539
|
+
if self.justification == "left":
|
540
|
+
for dag_layer in dag.layers():
|
541
|
+
current_index = len(self) - 1
|
542
|
+
dag_nodes = _sorted_nodes(dag_layer)
|
543
|
+
for node in dag_nodes:
|
544
|
+
self.add(node, current_index)
|
545
|
+
else:
|
546
|
+
dag_layers = []
|
547
|
+
for dag_layer in dag.layers():
|
548
|
+
dag_layers.append(dag_layer)
|
549
|
+
|
550
|
+
# going right to left!
|
551
|
+
dag_layers.reverse()
|
552
|
+
|
553
|
+
for dag_layer in dag_layers:
|
554
|
+
current_index = 0
|
555
|
+
dag_nodes = _sorted_nodes(dag_layer)
|
556
|
+
for node in dag_nodes:
|
557
|
+
self.add(node, current_index)
|
558
|
+
|
559
|
+
def is_found_in(self, node, nodes):
|
560
|
+
"""Is any qreq in node found in any of nodes?"""
|
561
|
+
all_qargs = []
|
562
|
+
for a_node in nodes:
|
563
|
+
for qarg in a_node.qargs:
|
564
|
+
all_qargs.append(qarg)
|
565
|
+
return any(i in node.qargs for i in all_qargs)
|
566
|
+
|
567
|
+
def insertable(self, node, nodes):
|
568
|
+
"""True .IFF. we can add 'node' to layer 'nodes'"""
|
569
|
+
return not _any_crossover(self.qubits, node, nodes)
|
570
|
+
|
571
|
+
def slide_from_left(self, node, index):
|
572
|
+
"""Insert node into first layer where there is no conflict going l > r"""
|
573
|
+
measure_layer = None
|
574
|
+
if isinstance(node.op, Measure):
|
575
|
+
measure_bit = next(bit for bit in self.measure_map if node.cargs[0] == bit)
|
576
|
+
|
577
|
+
if not self:
|
578
|
+
inserted = True
|
579
|
+
self.append([node])
|
580
|
+
else:
|
581
|
+
inserted = False
|
582
|
+
curr_index = index
|
583
|
+
last_insertable_index = -1
|
584
|
+
index_stop = -1
|
585
|
+
if (condition := getattr(node, "condition", None)) is not None:
|
586
|
+
index_stop = max(
|
587
|
+
(self.measure_map[bit] for bit in condition_resources(condition).clbits),
|
588
|
+
default=index_stop,
|
589
|
+
)
|
590
|
+
if node.cargs:
|
591
|
+
for carg in node.cargs:
|
592
|
+
try:
|
593
|
+
carg_bit = next(bit for bit in self.measure_map if carg == bit)
|
594
|
+
if self.measure_map[carg_bit] > index_stop:
|
595
|
+
index_stop = self.measure_map[carg_bit]
|
596
|
+
except StopIteration:
|
597
|
+
pass
|
598
|
+
while curr_index > index_stop:
|
599
|
+
if self.is_found_in(node, self[curr_index]):
|
600
|
+
break
|
601
|
+
if self.insertable(node, self[curr_index]):
|
602
|
+
last_insertable_index = curr_index
|
603
|
+
curr_index = curr_index - 1
|
604
|
+
|
605
|
+
if last_insertable_index >= 0:
|
606
|
+
inserted = True
|
607
|
+
self[last_insertable_index].append(node)
|
608
|
+
measure_layer = last_insertable_index
|
609
|
+
else:
|
610
|
+
inserted = False
|
611
|
+
curr_index = index
|
612
|
+
while curr_index < len(self):
|
613
|
+
if self.insertable(node, self[curr_index]):
|
614
|
+
self[curr_index].append(node)
|
615
|
+
measure_layer = curr_index
|
616
|
+
inserted = True
|
617
|
+
break
|
618
|
+
curr_index = curr_index + 1
|
619
|
+
|
620
|
+
if not inserted:
|
621
|
+
self.append([node])
|
622
|
+
|
623
|
+
if isinstance(node.op, Measure):
|
624
|
+
if not measure_layer:
|
625
|
+
measure_layer = len(self) - 1
|
626
|
+
if measure_layer > self.measure_map[measure_bit]:
|
627
|
+
self.measure_map[measure_bit] = measure_layer
|
628
|
+
|
629
|
+
def slide_from_right(self, node, index):
|
630
|
+
"""Insert node into rightmost layer as long there is no conflict."""
|
631
|
+
if not self:
|
632
|
+
self.insert(0, [node])
|
633
|
+
inserted = True
|
634
|
+
else:
|
635
|
+
inserted = False
|
636
|
+
curr_index = index
|
637
|
+
last_insertable_index = None
|
638
|
+
|
639
|
+
while curr_index < len(self):
|
640
|
+
if self.is_found_in(node, self[curr_index]):
|
641
|
+
break
|
642
|
+
if self.insertable(node, self[curr_index]):
|
643
|
+
last_insertable_index = curr_index
|
644
|
+
curr_index = curr_index + 1
|
645
|
+
|
646
|
+
if last_insertable_index:
|
647
|
+
self[last_insertable_index].append(node)
|
648
|
+
inserted = True
|
649
|
+
else:
|
650
|
+
curr_index = index
|
651
|
+
while curr_index > -1:
|
652
|
+
if self.insertable(node, self[curr_index]):
|
653
|
+
self[curr_index].append(node)
|
654
|
+
inserted = True
|
655
|
+
break
|
656
|
+
curr_index = curr_index - 1
|
657
|
+
|
658
|
+
if not inserted:
|
659
|
+
self.insert(0, [node])
|
660
|
+
|
661
|
+
def add(self, node, index):
|
662
|
+
"""Add 'node' where it belongs, starting the try at 'index'."""
|
663
|
+
# Before we add the node, we set its node ID to be globally unique
|
664
|
+
# within this spooler. This is necessary because nodes may span
|
665
|
+
# layers (which are separate DAGs), and thus can falsely compare
|
666
|
+
# as equal if their contents and node IDs happen to be the same.
|
667
|
+
# This is particularly important for the matplotlib drawer, which
|
668
|
+
# keys several of its internal data structures with these nodes.
|
669
|
+
global _GLOBAL_NID # pylint: disable=global-statement
|
670
|
+
node._node_id = _GLOBAL_NID
|
671
|
+
_GLOBAL_NID += 1
|
672
|
+
if self.justification == "left":
|
673
|
+
self.slide_from_left(node, index)
|
674
|
+
else:
|
675
|
+
self.slide_from_right(node, index)
|