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,498 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2021.
|
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
|
+
"""Circuit operation representing an ``if/else`` statement."""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
from typing import Optional, Union, Iterable, TYPE_CHECKING
|
18
|
+
import itertools
|
19
|
+
|
20
|
+
from qiskit.circuit import ClassicalRegister, Clbit # pylint: disable=cyclic-import
|
21
|
+
from qiskit.circuit.classical import expr
|
22
|
+
from qiskit.circuit.instructionset import InstructionSet
|
23
|
+
from qiskit.circuit.exceptions import CircuitError
|
24
|
+
|
25
|
+
from .builder import ControlFlowBuilderBlock, InstructionPlaceholder, InstructionResources
|
26
|
+
from .control_flow import ControlFlowOp
|
27
|
+
from ._builder_utils import (
|
28
|
+
partition_registers,
|
29
|
+
unify_circuit_resources,
|
30
|
+
validate_condition,
|
31
|
+
condition_resources,
|
32
|
+
)
|
33
|
+
|
34
|
+
if TYPE_CHECKING:
|
35
|
+
from qiskit.circuit import QuantumCircuit
|
36
|
+
|
37
|
+
|
38
|
+
# This is just an indication of what's actually meant to be the public API.
|
39
|
+
__all__ = ("IfElseOp",)
|
40
|
+
|
41
|
+
|
42
|
+
class IfElseOp(ControlFlowOp):
|
43
|
+
"""A circuit operation which executes a program (``true_body``) if a
|
44
|
+
provided condition (``condition``) evaluates to true, and
|
45
|
+
optionally evaluates another program (``false_body``) otherwise.
|
46
|
+
|
47
|
+
If provided, ``false_body`` must be of the same ``num_qubits`` and
|
48
|
+
``num_clbits`` as ``true_body``.
|
49
|
+
|
50
|
+
The classical bits used in ``condition`` must be a subset of those attached
|
51
|
+
to the circuit on which this ``IfElseOp`` will be appended.
|
52
|
+
"""
|
53
|
+
|
54
|
+
def __init__(
|
55
|
+
self,
|
56
|
+
condition: tuple[ClassicalRegister, int] | tuple[Clbit, int] | expr.Expr,
|
57
|
+
true_body: QuantumCircuit,
|
58
|
+
false_body: QuantumCircuit | None = None,
|
59
|
+
label: str | None = None,
|
60
|
+
):
|
61
|
+
"""
|
62
|
+
Args:
|
63
|
+
condition: A condition to be evaluated in real time during circuit execution which,
|
64
|
+
if true, will trigger the evaluation of ``true_body``. Can be
|
65
|
+
specified as either a tuple of a ``ClassicalRegister`` to be
|
66
|
+
tested for equality with a given ``int``, or as a tuple of a
|
67
|
+
``Clbit`` to be compared to either a ``bool`` or an ``int``.
|
68
|
+
true_body: A program to be executed if ``condition`` evaluates
|
69
|
+
to true.
|
70
|
+
false_body: A optional program to be executed if ``condition``
|
71
|
+
evaluates to false.
|
72
|
+
label: An optional label for identifying the instruction.
|
73
|
+
"""
|
74
|
+
# pylint: disable=cyclic-import
|
75
|
+
from qiskit.circuit import QuantumCircuit
|
76
|
+
|
77
|
+
# Type checking generally left to @params.setter, but required here for
|
78
|
+
# finding num_qubits and num_clbits.
|
79
|
+
if not isinstance(true_body, QuantumCircuit):
|
80
|
+
raise CircuitError(
|
81
|
+
"IfElseOp expects a true_body parameter "
|
82
|
+
f"of type QuantumCircuit, but received {type(true_body)}."
|
83
|
+
)
|
84
|
+
|
85
|
+
num_qubits = true_body.num_qubits
|
86
|
+
num_clbits = true_body.num_clbits
|
87
|
+
|
88
|
+
super().__init__("if_else", num_qubits, num_clbits, [true_body, false_body], label=label)
|
89
|
+
|
90
|
+
self._condition = validate_condition(condition)
|
91
|
+
|
92
|
+
@property
|
93
|
+
def params(self):
|
94
|
+
return self._params
|
95
|
+
|
96
|
+
@property
|
97
|
+
def condition(self):
|
98
|
+
"""The condition for the if else operation."""
|
99
|
+
return self._condition
|
100
|
+
|
101
|
+
@condition.setter
|
102
|
+
def condition(self, value):
|
103
|
+
self._condition = value
|
104
|
+
|
105
|
+
@params.setter
|
106
|
+
def params(self, parameters):
|
107
|
+
# pylint: disable=cyclic-import
|
108
|
+
from qiskit.circuit import QuantumCircuit
|
109
|
+
|
110
|
+
true_body, false_body = parameters
|
111
|
+
|
112
|
+
if not isinstance(true_body, QuantumCircuit):
|
113
|
+
raise CircuitError(
|
114
|
+
"IfElseOp expects a true_body parameter of type "
|
115
|
+
f"QuantumCircuit, but received {type(true_body)}."
|
116
|
+
)
|
117
|
+
|
118
|
+
if true_body.num_qubits != self.num_qubits or true_body.num_clbits != self.num_clbits:
|
119
|
+
raise CircuitError(
|
120
|
+
"Attempted to assign a true_body parameter with a num_qubits or "
|
121
|
+
"num_clbits different than that of the IfElseOp. "
|
122
|
+
f"IfElseOp num_qubits/clbits: {self.num_qubits}/{self.num_clbits} "
|
123
|
+
f"Supplied body num_qubits/clbits: {true_body.num_qubits}/{true_body.num_clbits}."
|
124
|
+
)
|
125
|
+
|
126
|
+
if false_body is not None:
|
127
|
+
if not isinstance(false_body, QuantumCircuit):
|
128
|
+
raise CircuitError(
|
129
|
+
"IfElseOp expects a false_body parameter of type "
|
130
|
+
f"QuantumCircuit, but received {type(false_body)}."
|
131
|
+
)
|
132
|
+
|
133
|
+
if false_body.num_qubits != self.num_qubits or false_body.num_clbits != self.num_clbits:
|
134
|
+
raise CircuitError(
|
135
|
+
"Attempted to assign a false_body parameter with a num_qubits or "
|
136
|
+
"num_clbits different than that of the IfElseOp. "
|
137
|
+
f"IfElseOp num_qubits/clbits: {self.num_qubits}/{self.num_clbits} "
|
138
|
+
f"Supplied body num_qubits/clbits: {false_body.num_qubits}/{false_body.num_clbits}."
|
139
|
+
)
|
140
|
+
|
141
|
+
self._params = [true_body, false_body]
|
142
|
+
|
143
|
+
@property
|
144
|
+
def blocks(self):
|
145
|
+
if self.params[1] is None:
|
146
|
+
return (self.params[0],)
|
147
|
+
else:
|
148
|
+
return (self.params[0], self.params[1])
|
149
|
+
|
150
|
+
def replace_blocks(self, blocks: Iterable[QuantumCircuit]) -> "IfElseOp":
|
151
|
+
"""Replace blocks and return new instruction.
|
152
|
+
|
153
|
+
Args:
|
154
|
+
blocks: Iterable of circuits for "if" and "else" condition. If there is no "else"
|
155
|
+
circuit it may be set to None or omitted.
|
156
|
+
|
157
|
+
Returns:
|
158
|
+
New IfElseOp with replaced blocks.
|
159
|
+
"""
|
160
|
+
|
161
|
+
true_body, false_body = (
|
162
|
+
ablock for ablock, _ in itertools.zip_longest(blocks, range(2), fillvalue=None)
|
163
|
+
)
|
164
|
+
return IfElseOp(self._condition, true_body, false_body=false_body, label=self.label)
|
165
|
+
|
166
|
+
|
167
|
+
class IfElsePlaceholder(InstructionPlaceholder):
|
168
|
+
"""A placeholder instruction to use in control-flow context managers, when calculating the
|
169
|
+
number of resources this instruction should block is deferred until the construction of the
|
170
|
+
outer loop.
|
171
|
+
|
172
|
+
This generally should not be instantiated manually; only :obj:`.IfContext` and
|
173
|
+
:obj:`.ElseContext` should do it when they need to defer creation of the concrete instruction.
|
174
|
+
|
175
|
+
.. warning::
|
176
|
+
|
177
|
+
This is an internal interface and no part of it should be relied upon outside of Qiskit
|
178
|
+
Terra.
|
179
|
+
"""
|
180
|
+
|
181
|
+
def __init__(
|
182
|
+
self,
|
183
|
+
condition: tuple[ClassicalRegister, int] | tuple[Clbit, int] | expr.Expr,
|
184
|
+
true_block: ControlFlowBuilderBlock,
|
185
|
+
false_block: ControlFlowBuilderBlock | None = None,
|
186
|
+
*,
|
187
|
+
label: Optional[str] = None,
|
188
|
+
):
|
189
|
+
"""
|
190
|
+
Args:
|
191
|
+
condition: the condition to execute the true block on. This has the same semantics as
|
192
|
+
the ``condition`` argument to :obj:`.IfElseOp`.
|
193
|
+
true_block: the unbuilt scope block that will become the "true" branch at creation time.
|
194
|
+
false_block: if given, the unbuilt scope block that will become the "false" branch at
|
195
|
+
creation time.
|
196
|
+
label: the label to give the operator when it is created.
|
197
|
+
"""
|
198
|
+
# These are protected names because we're not trying to clash with parent attributes.
|
199
|
+
self.__true_block = true_block
|
200
|
+
self.__false_block: Optional[ControlFlowBuilderBlock] = false_block
|
201
|
+
self.__resources = self._calculate_placeholder_resources()
|
202
|
+
super().__init__(
|
203
|
+
"if_else", len(self.__resources.qubits), len(self.__resources.clbits), [], label=label
|
204
|
+
)
|
205
|
+
# Set the condition after super().__init__() has initialized it to None.
|
206
|
+
self._condition = validate_condition(condition)
|
207
|
+
|
208
|
+
def with_false_block(self, false_block: ControlFlowBuilderBlock) -> "IfElsePlaceholder":
|
209
|
+
"""Return a new placeholder instruction, with the false block set to the given value,
|
210
|
+
updating the bits used by both it and the true body, if necessary.
|
211
|
+
|
212
|
+
It is an error to try and set the false block on a placeholder that already has one.
|
213
|
+
|
214
|
+
Args:
|
215
|
+
false_block: The (unbuilt) instruction scope to set the false body to.
|
216
|
+
|
217
|
+
Returns:
|
218
|
+
A new placeholder, with ``false_block`` set to the given input, and both true and false
|
219
|
+
blocks expanded to account for all resources.
|
220
|
+
|
221
|
+
Raises:
|
222
|
+
CircuitError: if the false block of this placeholder instruction is already set.
|
223
|
+
"""
|
224
|
+
if self.__false_block is not None:
|
225
|
+
raise CircuitError(f"false block is already set to {self.__false_block}")
|
226
|
+
true_block = self.__true_block.copy()
|
227
|
+
true_bits = true_block.qubits() | true_block.clbits()
|
228
|
+
false_bits = false_block.qubits() | false_block.clbits()
|
229
|
+
true_block.add_bits(false_bits - true_bits)
|
230
|
+
false_block.add_bits(true_bits - false_bits)
|
231
|
+
return type(self)(self._condition, true_block, false_block, label=self.label)
|
232
|
+
|
233
|
+
def registers(self):
|
234
|
+
"""Get the registers used by the interior blocks."""
|
235
|
+
if self.__false_block is None:
|
236
|
+
return self.__true_block.registers.copy()
|
237
|
+
return self.__true_block.registers | self.__false_block.registers
|
238
|
+
|
239
|
+
def _calculate_placeholder_resources(self) -> InstructionResources:
|
240
|
+
"""Get the placeholder resources (see :meth:`.placeholder_resources`).
|
241
|
+
|
242
|
+
This is a separate function because we use the resources during the initialization to
|
243
|
+
determine how we should set our ``num_qubits`` and ``num_clbits``, so we implement the
|
244
|
+
public version as a cache access for efficiency.
|
245
|
+
"""
|
246
|
+
if self.__false_block is None:
|
247
|
+
qregs, cregs = partition_registers(self.__true_block.registers)
|
248
|
+
return InstructionResources(
|
249
|
+
qubits=tuple(self.__true_block.qubits()),
|
250
|
+
clbits=tuple(self.__true_block.clbits()),
|
251
|
+
qregs=tuple(qregs),
|
252
|
+
cregs=tuple(cregs),
|
253
|
+
)
|
254
|
+
true_qregs, true_cregs = partition_registers(self.__true_block.registers)
|
255
|
+
false_qregs, false_cregs = partition_registers(self.__false_block.registers)
|
256
|
+
return InstructionResources(
|
257
|
+
qubits=tuple(self.__true_block.qubits() | self.__false_block.qubits()),
|
258
|
+
clbits=tuple(self.__true_block.clbits() | self.__false_block.clbits()),
|
259
|
+
qregs=tuple(true_qregs) + tuple(false_qregs),
|
260
|
+
cregs=tuple(true_cregs) + tuple(false_cregs),
|
261
|
+
)
|
262
|
+
|
263
|
+
def placeholder_resources(self):
|
264
|
+
# All the elements of our InstructionResources are immutable (tuple, Bit and Register).
|
265
|
+
return self.__resources
|
266
|
+
|
267
|
+
def concrete_instruction(self, qubits, clbits):
|
268
|
+
current_qubits = self.__true_block.qubits()
|
269
|
+
current_clbits = self.__true_block.clbits()
|
270
|
+
if self.__false_block is not None:
|
271
|
+
current_qubits = current_qubits | self.__false_block.qubits()
|
272
|
+
current_clbits = current_clbits | self.__false_block.clbits()
|
273
|
+
all_bits = qubits | clbits
|
274
|
+
current_bits = current_qubits | current_clbits
|
275
|
+
if current_bits - all_bits:
|
276
|
+
# This _shouldn't_ trigger if the context managers are being used correctly, but is here
|
277
|
+
# to make any potential logic errors noisy.
|
278
|
+
raise CircuitError(
|
279
|
+
"This block contains bits that are not in the operands sets:"
|
280
|
+
f" {current_bits - all_bits!r}"
|
281
|
+
)
|
282
|
+
true_body = self.__true_block.build(qubits, clbits)
|
283
|
+
if self.__false_block is None:
|
284
|
+
false_body = None
|
285
|
+
else:
|
286
|
+
# The bodies are not compelled to use all the resources that the
|
287
|
+
# ControlFlowBuilderBlock.build calls get passed, but they do need to be as wide as each
|
288
|
+
# other. Now we ensure that they are.
|
289
|
+
true_body, false_body = unify_circuit_resources(
|
290
|
+
(true_body, self.__false_block.build(qubits, clbits))
|
291
|
+
)
|
292
|
+
return (
|
293
|
+
IfElseOp(self._condition, true_body, false_body, label=self.label),
|
294
|
+
InstructionResources(
|
295
|
+
qubits=tuple(true_body.qubits),
|
296
|
+
clbits=tuple(true_body.clbits),
|
297
|
+
qregs=tuple(true_body.qregs),
|
298
|
+
cregs=tuple(true_body.cregs),
|
299
|
+
),
|
300
|
+
)
|
301
|
+
|
302
|
+
|
303
|
+
class IfContext:
|
304
|
+
"""A context manager for building up ``if`` statements onto circuits in a natural order, without
|
305
|
+
having to construct the statement body first.
|
306
|
+
|
307
|
+
The return value of this context manager can be used immediately following the block to create
|
308
|
+
an attached ``else`` statement.
|
309
|
+
|
310
|
+
This context should almost invariably be created by a :meth:`.QuantumCircuit.if_test` call, and
|
311
|
+
the resulting instance is a "friend" of the calling circuit. The context will manipulate the
|
312
|
+
circuit's defined scopes when it is entered (by pushing a new scope onto the stack) and exited
|
313
|
+
(by popping its scope, building it, and appending the resulting :obj:`.IfElseOp`).
|
314
|
+
|
315
|
+
.. warning::
|
316
|
+
|
317
|
+
This is an internal interface and no part of it should be relied upon outside of Qiskit
|
318
|
+
Terra.
|
319
|
+
"""
|
320
|
+
|
321
|
+
__slots__ = ("_appended_instructions", "_circuit", "_condition", "_in_loop", "_label")
|
322
|
+
|
323
|
+
def __init__(
|
324
|
+
self,
|
325
|
+
circuit: QuantumCircuit,
|
326
|
+
condition: tuple[ClassicalRegister, int] | tuple[Clbit, int] | expr.Expr,
|
327
|
+
*,
|
328
|
+
in_loop: bool,
|
329
|
+
label: str | None = None,
|
330
|
+
):
|
331
|
+
self._circuit = circuit
|
332
|
+
self._condition = validate_condition(condition)
|
333
|
+
self._label = label
|
334
|
+
self._appended_instructions = None
|
335
|
+
self._in_loop = in_loop
|
336
|
+
|
337
|
+
# Only expose the necessary public interface, and make it read-only. If Python had friend
|
338
|
+
# classes, or a "protected" access modifier, that's what we'd use (since these are only
|
339
|
+
# necessary for ElseContext), but alas.
|
340
|
+
|
341
|
+
@property
|
342
|
+
def circuit(self) -> QuantumCircuit:
|
343
|
+
"""Get the circuit that this context manager is attached to."""
|
344
|
+
return self._circuit
|
345
|
+
|
346
|
+
@property
|
347
|
+
def condition(self) -> tuple[ClassicalRegister, int] | tuple[Clbit, int] | expr.Expr:
|
348
|
+
"""Get the expression that this statement is conditioned on."""
|
349
|
+
return self._condition
|
350
|
+
|
351
|
+
@property
|
352
|
+
def appended_instructions(self) -> Union[InstructionSet, None]:
|
353
|
+
"""Get the instruction set that was created when this block finished. If the block has not
|
354
|
+
yet finished, then this will be ``None``."""
|
355
|
+
return self._appended_instructions
|
356
|
+
|
357
|
+
@property
|
358
|
+
def in_loop(self) -> bool:
|
359
|
+
"""Whether this context manager is enclosed within a loop."""
|
360
|
+
return self._in_loop
|
361
|
+
|
362
|
+
def __enter__(self):
|
363
|
+
resources = condition_resources(self._condition)
|
364
|
+
self._circuit._push_scope(
|
365
|
+
clbits=resources.clbits,
|
366
|
+
registers=resources.cregs,
|
367
|
+
allow_jumps=self._in_loop,
|
368
|
+
)
|
369
|
+
return ElseContext(self)
|
370
|
+
|
371
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
372
|
+
if exc_type is not None:
|
373
|
+
# If we're leaving the context manager because an exception was raised, there's nothing
|
374
|
+
# to do except restore the circuit state.
|
375
|
+
self._circuit._pop_scope()
|
376
|
+
return False
|
377
|
+
true_block = self._circuit._pop_scope()
|
378
|
+
if self._in_loop:
|
379
|
+
# It's possible that we don't actually have any placeholder instructions in our scope,
|
380
|
+
# but we still need to emit a placeholder instruction here in case we get an ``else``
|
381
|
+
# attached which _does_ gain them. We emit a placeholder to defer defining the
|
382
|
+
# resources we use until the containing loop concludes, to support ``break``.
|
383
|
+
operation = IfElsePlaceholder(self._condition, true_block, label=self._label)
|
384
|
+
resources = operation.placeholder_resources()
|
385
|
+
self._appended_instructions = self._circuit.append(
|
386
|
+
operation, resources.qubits, resources.clbits
|
387
|
+
)
|
388
|
+
else:
|
389
|
+
# If we're not in a loop, we don't need to be worried about passing in any outer-scope
|
390
|
+
# resources because there can't be anything that will consume them.
|
391
|
+
true_body = true_block.build(true_block.qubits(), true_block.clbits())
|
392
|
+
self._appended_instructions = self._circuit.append(
|
393
|
+
IfElseOp(self._condition, true_body=true_body, false_body=None, label=self._label),
|
394
|
+
tuple(true_body.qubits),
|
395
|
+
tuple(true_body.clbits),
|
396
|
+
)
|
397
|
+
return False
|
398
|
+
|
399
|
+
|
400
|
+
class ElseContext:
|
401
|
+
"""A context manager for building up an ``else`` statements onto circuits in a natural order,
|
402
|
+
without having to construct the statement body first.
|
403
|
+
|
404
|
+
Instances of this context manager should only ever be gained as the output of the
|
405
|
+
:obj:`.IfContext` manager, so they know what they refer to. Instances of this context are
|
406
|
+
"friends" of the circuit that created the :obj:`.IfContext` that in turn created this object.
|
407
|
+
The context will manipulate the circuit's defined scopes when it is entered (by popping the old
|
408
|
+
:obj:`.IfElseOp` if it exists and pushing a new scope onto the stack) and exited (by popping its
|
409
|
+
scope, building it, and appending the resulting :obj:`.IfElseOp`).
|
410
|
+
|
411
|
+
.. warning::
|
412
|
+
|
413
|
+
This is an internal interface and no part of it should be relied upon outside of Qiskit
|
414
|
+
Terra.
|
415
|
+
"""
|
416
|
+
|
417
|
+
__slots__ = ("_if_instruction", "_if_registers", "_if_context", "_used")
|
418
|
+
|
419
|
+
def __init__(self, if_context: IfContext):
|
420
|
+
# We want to avoid doing any processing until we're actually used, because the `if` block
|
421
|
+
# likely isn't finished yet, and we want to have as small a penalty a possible if you don't
|
422
|
+
# use an `else` branch.
|
423
|
+
self._if_instruction = None
|
424
|
+
self._if_registers = None
|
425
|
+
self._if_context = if_context
|
426
|
+
self._used = False
|
427
|
+
|
428
|
+
def __enter__(self):
|
429
|
+
if self._used:
|
430
|
+
raise CircuitError("Cannot re-use an 'else' context.")
|
431
|
+
self._used = True
|
432
|
+
appended_instructions = self._if_context.appended_instructions
|
433
|
+
circuit = self._if_context.circuit
|
434
|
+
if appended_instructions is None:
|
435
|
+
raise CircuitError("Cannot attach an 'else' branch to an incomplete 'if' block.")
|
436
|
+
if len(appended_instructions) != 1:
|
437
|
+
# I'm not even sure how you'd get this to trigger, but just in case...
|
438
|
+
raise CircuitError("Cannot attach an 'else' to a broadcasted 'if' block.")
|
439
|
+
appended = appended_instructions[0]
|
440
|
+
instruction = circuit._peek_previous_instruction_in_scope()
|
441
|
+
if appended.operation is not instruction.operation:
|
442
|
+
raise CircuitError(
|
443
|
+
"The 'if' block is not the most recent instruction in the circuit."
|
444
|
+
f" Expected to find: {appended!r}, but instead found: {instruction!r}."
|
445
|
+
)
|
446
|
+
self._if_instruction = circuit._pop_previous_instruction_in_scope()
|
447
|
+
if isinstance(self._if_instruction.operation, IfElseOp):
|
448
|
+
self._if_registers = set(self._if_instruction.operation.blocks[0].cregs).union(
|
449
|
+
self._if_instruction.operation.blocks[0].qregs
|
450
|
+
)
|
451
|
+
else:
|
452
|
+
self._if_registers = self._if_instruction.operation.registers()
|
453
|
+
circuit._push_scope(
|
454
|
+
self._if_instruction.qubits,
|
455
|
+
self._if_instruction.clbits,
|
456
|
+
registers=self._if_registers,
|
457
|
+
allow_jumps=self._if_context.in_loop,
|
458
|
+
)
|
459
|
+
|
460
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
461
|
+
circuit = self._if_context.circuit
|
462
|
+
if exc_type is not None:
|
463
|
+
# If we're leaving the context manager because an exception was raised, we need to
|
464
|
+
# restore the "if" block we popped off. At that point, it's safe to re-use this context
|
465
|
+
# manager, assuming nothing else untoward happened to the circuit, but that's checked by
|
466
|
+
# the __enter__ method.
|
467
|
+
circuit._pop_scope()
|
468
|
+
circuit._append(self._if_instruction)
|
469
|
+
self._used = False
|
470
|
+
return False
|
471
|
+
|
472
|
+
false_block = circuit._pop_scope()
|
473
|
+
# `if_block` is a placeholder if this context is in a loop, and a concrete instruction if it
|
474
|
+
# is not.
|
475
|
+
if isinstance(self._if_instruction.operation, IfElsePlaceholder):
|
476
|
+
if_operation = self._if_instruction.operation.with_false_block(false_block)
|
477
|
+
resources = if_operation.placeholder_resources()
|
478
|
+
circuit.append(if_operation, resources.qubits, resources.clbits)
|
479
|
+
else:
|
480
|
+
# In this case, we need to update both true_body and false_body to have exactly the same
|
481
|
+
# widths. Passing extra resources to `ControlFlowBuilderBlock.build` doesn't _compel_
|
482
|
+
# the resulting object to use them (because it tries to be minimal), so it's best to
|
483
|
+
# pass it nothing extra (allows some fast path constructions), and add all necessary
|
484
|
+
# bits onto the circuits at the end.
|
485
|
+
true_body = self._if_instruction.operation.blocks[0]
|
486
|
+
false_body = false_block.build(false_block.qubits(), false_block.clbits())
|
487
|
+
true_body, false_body = unify_circuit_resources((true_body, false_body))
|
488
|
+
circuit.append(
|
489
|
+
IfElseOp(
|
490
|
+
self._if_context.condition,
|
491
|
+
true_body,
|
492
|
+
false_body,
|
493
|
+
label=self._if_instruction.operation.label,
|
494
|
+
),
|
495
|
+
tuple(true_body.qubits),
|
496
|
+
tuple(true_body.clbits),
|
497
|
+
)
|
498
|
+
return False
|