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,639 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2020.
|
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
|
+
"""
|
14
|
+
Template matching substitution, given a list of maximal matches it substitutes
|
15
|
+
them in circuit and creates a new optimized dag version of the circuit.
|
16
|
+
"""
|
17
|
+
import collections
|
18
|
+
import copy
|
19
|
+
import itertools
|
20
|
+
|
21
|
+
from qiskit.circuit import Parameter, ParameterExpression
|
22
|
+
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
23
|
+
from qiskit.dagcircuit.dagdependency import DAGDependency
|
24
|
+
from qiskit.converters.dagdependency_to_dag import dagdependency_to_dag
|
25
|
+
from qiskit.utils import optionals as _optionals
|
26
|
+
|
27
|
+
|
28
|
+
class SubstitutionConfig:
|
29
|
+
"""
|
30
|
+
Class to store the configuration of a given match substitution, which circuit
|
31
|
+
gates, template gates, qubits, and clbits and predecessors of the match
|
32
|
+
in the circuit.
|
33
|
+
"""
|
34
|
+
|
35
|
+
def __init__(
|
36
|
+
self,
|
37
|
+
circuit_config,
|
38
|
+
template_config,
|
39
|
+
pred_block,
|
40
|
+
qubit_config,
|
41
|
+
template_dag_dep,
|
42
|
+
clbit_config=None,
|
43
|
+
):
|
44
|
+
self.template_dag_dep = template_dag_dep
|
45
|
+
self.circuit_config = circuit_config
|
46
|
+
self.template_config = template_config
|
47
|
+
self.qubit_config = qubit_config
|
48
|
+
self.clbit_config = clbit_config if clbit_config is not None else []
|
49
|
+
self.pred_block = pred_block
|
50
|
+
|
51
|
+
def has_parameters(self):
|
52
|
+
"""Ensure that the template does not have parameters."""
|
53
|
+
for node in self.template_dag_dep.get_nodes():
|
54
|
+
for param in node.op.params:
|
55
|
+
if isinstance(param, ParameterExpression):
|
56
|
+
return True
|
57
|
+
|
58
|
+
return False
|
59
|
+
|
60
|
+
|
61
|
+
class TemplateSubstitution:
|
62
|
+
"""
|
63
|
+
Class to run the substitution algorithm from the list of maximal matches.
|
64
|
+
"""
|
65
|
+
|
66
|
+
def __init__(self, max_matches, circuit_dag_dep, template_dag_dep, user_cost_dict=None):
|
67
|
+
"""
|
68
|
+
Initialize TemplateSubstitution with necessary arguments.
|
69
|
+
Args:
|
70
|
+
max_matches (list): list of maximal matches obtained from the running
|
71
|
+
the template matching algorithm.
|
72
|
+
circuit_dag_dep (DAGDependency): circuit in the dag dependency form.
|
73
|
+
template_dag_dep (DAGDependency): template in the dag dependency form.
|
74
|
+
user_cost_dict (Optional[dict]): user provided cost dictionary that will override
|
75
|
+
the default cost dictionary.
|
76
|
+
"""
|
77
|
+
|
78
|
+
self.match_stack = max_matches
|
79
|
+
self.circuit_dag_dep = circuit_dag_dep
|
80
|
+
self.template_dag_dep = template_dag_dep
|
81
|
+
|
82
|
+
self.substitution_list = []
|
83
|
+
self.unmatched_list = []
|
84
|
+
self.dag_dep_optimized = DAGDependency()
|
85
|
+
self.dag_optimized = DAGCircuit()
|
86
|
+
|
87
|
+
if user_cost_dict is not None:
|
88
|
+
self.cost_dict = dict(user_cost_dict)
|
89
|
+
else:
|
90
|
+
self.cost_dict = {
|
91
|
+
"id": 0,
|
92
|
+
"x": 1,
|
93
|
+
"y": 1,
|
94
|
+
"z": 1,
|
95
|
+
"h": 1,
|
96
|
+
"t": 1,
|
97
|
+
"tdg": 1,
|
98
|
+
"s": 1,
|
99
|
+
"sdg": 1,
|
100
|
+
"u1": 1,
|
101
|
+
"u2": 2,
|
102
|
+
"u3": 2,
|
103
|
+
"rx": 1,
|
104
|
+
"ry": 1,
|
105
|
+
"rz": 1,
|
106
|
+
"r": 2,
|
107
|
+
"cx": 2,
|
108
|
+
"cy": 4,
|
109
|
+
"cz": 4,
|
110
|
+
"ch": 8,
|
111
|
+
"swap": 6,
|
112
|
+
"iswap": 8,
|
113
|
+
"rxx": 9,
|
114
|
+
"ryy": 9,
|
115
|
+
"rzz": 5,
|
116
|
+
"rzx": 7,
|
117
|
+
"ms": 9,
|
118
|
+
"cu3": 10,
|
119
|
+
"crx": 10,
|
120
|
+
"cry": 10,
|
121
|
+
"crz": 10,
|
122
|
+
"ccx": 21,
|
123
|
+
"rccx": 12,
|
124
|
+
"c3x": 96,
|
125
|
+
"rc3x": 24,
|
126
|
+
"c4x": 312,
|
127
|
+
"p": 1,
|
128
|
+
}
|
129
|
+
|
130
|
+
def _pred_block(self, circuit_sublist, index):
|
131
|
+
"""
|
132
|
+
It returns the predecessors of a given part of the circuit.
|
133
|
+
Args:
|
134
|
+
circuit_sublist (list): list of the gates matched in the circuit.
|
135
|
+
index (int): Index of the group of matches.
|
136
|
+
Returns:
|
137
|
+
list: List of predecessors of the current match circuit configuration.
|
138
|
+
"""
|
139
|
+
predecessors = set()
|
140
|
+
for node_id in circuit_sublist:
|
141
|
+
predecessors = predecessors | set(self.circuit_dag_dep.get_node(node_id).predecessors)
|
142
|
+
|
143
|
+
exclude = set()
|
144
|
+
for elem in self.substitution_list[:index]:
|
145
|
+
exclude = exclude | set(elem.circuit_config) | set(elem.pred_block)
|
146
|
+
|
147
|
+
pred = list(predecessors - set(circuit_sublist) - exclude)
|
148
|
+
pred.sort()
|
149
|
+
|
150
|
+
return pred
|
151
|
+
|
152
|
+
def _quantum_cost(self, left, right):
|
153
|
+
"""
|
154
|
+
Compare the two parts of the template and returns True if the quantum cost is reduced.
|
155
|
+
Args:
|
156
|
+
left (list): list of matched nodes in the template.
|
157
|
+
right (list): list of nodes to be replaced.
|
158
|
+
Returns:
|
159
|
+
bool: True if the quantum cost is reduced
|
160
|
+
"""
|
161
|
+
cost_left = 0
|
162
|
+
for i in left:
|
163
|
+
cost_left += self.cost_dict[self.template_dag_dep.get_node(i).name]
|
164
|
+
|
165
|
+
cost_right = 0
|
166
|
+
for j in right:
|
167
|
+
cost_right += self.cost_dict[self.template_dag_dep.get_node(j).name]
|
168
|
+
|
169
|
+
return cost_left > cost_right
|
170
|
+
|
171
|
+
def _rules(self, circuit_sublist, template_sublist, template_complement):
|
172
|
+
"""
|
173
|
+
Set of rules to decide whether the match is to be substitute or not.
|
174
|
+
Args:
|
175
|
+
circuit_sublist (list): list of the gates matched in the circuit.
|
176
|
+
template_sublist (list): list of matched nodes in the template.
|
177
|
+
template_complement (list): list of gates not matched in the template.
|
178
|
+
Returns:
|
179
|
+
bool: True if the match respects the given rule for replacement, False otherwise.
|
180
|
+
"""
|
181
|
+
if self._quantum_cost(template_sublist, template_complement):
|
182
|
+
for elem in circuit_sublist:
|
183
|
+
for config in self.substitution_list:
|
184
|
+
if any(elem == x for x in config.circuit_config):
|
185
|
+
return False
|
186
|
+
return True
|
187
|
+
else:
|
188
|
+
return False
|
189
|
+
|
190
|
+
def _template_inverse(self, template_list, template_sublist, template_complement):
|
191
|
+
"""
|
192
|
+
The template circuit realizes the identity operator, then given the list of
|
193
|
+
matches in the template, it returns the inverse part of the template that
|
194
|
+
will be replaced.
|
195
|
+
Args:
|
196
|
+
template_list (list): list of all gates in the template.
|
197
|
+
template_sublist (list): list of the gates matched in the circuit.
|
198
|
+
template_complement (list): list of gates not matched in the template.
|
199
|
+
Returns:
|
200
|
+
list: the template inverse part that will substitute the circuit match.
|
201
|
+
"""
|
202
|
+
inverse = template_complement
|
203
|
+
left = []
|
204
|
+
right = []
|
205
|
+
|
206
|
+
pred = set()
|
207
|
+
for index in template_sublist:
|
208
|
+
pred = pred | set(self.template_dag_dep.get_node(index).predecessors)
|
209
|
+
pred = list(pred - set(template_sublist))
|
210
|
+
|
211
|
+
succ = set()
|
212
|
+
for index in template_sublist:
|
213
|
+
succ = succ | set(self.template_dag_dep.get_node(index).successors)
|
214
|
+
succ = list(succ - set(template_sublist))
|
215
|
+
|
216
|
+
comm = list(set(template_list) - set(pred) - set(succ))
|
217
|
+
|
218
|
+
for elem in inverse:
|
219
|
+
if elem in pred:
|
220
|
+
left.append(elem)
|
221
|
+
elif elem in succ:
|
222
|
+
right.append(elem)
|
223
|
+
elif elem in comm:
|
224
|
+
right.append(elem)
|
225
|
+
|
226
|
+
left.sort()
|
227
|
+
right.sort()
|
228
|
+
|
229
|
+
left.reverse()
|
230
|
+
right.reverse()
|
231
|
+
|
232
|
+
total = left + right
|
233
|
+
return total
|
234
|
+
|
235
|
+
def _substitution_sort(self):
|
236
|
+
"""
|
237
|
+
Sort the substitution list.
|
238
|
+
"""
|
239
|
+
ordered = False
|
240
|
+
while not ordered:
|
241
|
+
ordered = self._permutation()
|
242
|
+
|
243
|
+
def _permutation(self):
|
244
|
+
"""
|
245
|
+
Permute two groups of matches if first one has predecessors in the second one.
|
246
|
+
Returns:
|
247
|
+
bool: True if the matches groups are in the right order, False otherwise.
|
248
|
+
"""
|
249
|
+
for scenario in self.substitution_list:
|
250
|
+
predecessors = set()
|
251
|
+
for match in scenario.circuit_config:
|
252
|
+
predecessors = predecessors | set(self.circuit_dag_dep.get_node(match).predecessors)
|
253
|
+
predecessors = predecessors - set(scenario.circuit_config)
|
254
|
+
index = self.substitution_list.index(scenario)
|
255
|
+
for scenario_b in self.substitution_list[index::]:
|
256
|
+
if set(scenario_b.circuit_config) & predecessors:
|
257
|
+
|
258
|
+
index1 = self.substitution_list.index(scenario)
|
259
|
+
index2 = self.substitution_list.index(scenario_b)
|
260
|
+
|
261
|
+
scenario_pop = self.substitution_list.pop(index2)
|
262
|
+
self.substitution_list.insert(index1, scenario_pop)
|
263
|
+
return False
|
264
|
+
return True
|
265
|
+
|
266
|
+
def _remove_impossible(self):
|
267
|
+
"""
|
268
|
+
Remove matched groups if they both have predecessors in the other one, they are not
|
269
|
+
compatible.
|
270
|
+
"""
|
271
|
+
list_predecessors = []
|
272
|
+
remove_list = []
|
273
|
+
|
274
|
+
# Initialize predecessors for each group of matches.
|
275
|
+
for scenario in self.substitution_list:
|
276
|
+
predecessors = set()
|
277
|
+
for index in scenario.circuit_config:
|
278
|
+
predecessors = predecessors | set(self.circuit_dag_dep.get_node(index).predecessors)
|
279
|
+
list_predecessors.append(predecessors)
|
280
|
+
|
281
|
+
# Check if two groups of matches are incompatible.
|
282
|
+
for scenario_a in self.substitution_list:
|
283
|
+
if scenario_a in remove_list:
|
284
|
+
continue
|
285
|
+
index_a = self.substitution_list.index(scenario_a)
|
286
|
+
circuit_a = scenario_a.circuit_config
|
287
|
+
for scenario_b in self.substitution_list[index_a + 1 : :]:
|
288
|
+
if scenario_b in remove_list:
|
289
|
+
continue
|
290
|
+
index_b = self.substitution_list.index(scenario_b)
|
291
|
+
circuit_b = scenario_b.circuit_config
|
292
|
+
if (set(circuit_a) & list_predecessors[index_b]) and (
|
293
|
+
set(circuit_b) & list_predecessors[index_a]
|
294
|
+
):
|
295
|
+
remove_list.append(scenario_b)
|
296
|
+
|
297
|
+
# Remove the incompatible groups from the list.
|
298
|
+
if remove_list:
|
299
|
+
self.substitution_list = [
|
300
|
+
scenario for scenario in self.substitution_list if scenario not in remove_list
|
301
|
+
]
|
302
|
+
|
303
|
+
def _substitution(self):
|
304
|
+
"""
|
305
|
+
From the list of maximal matches, it chooses which one will be used and gives the necessary
|
306
|
+
details for each substitution(template inverse, predecessors of the match).
|
307
|
+
"""
|
308
|
+
|
309
|
+
while self.match_stack:
|
310
|
+
|
311
|
+
# Get the first match scenario of the list
|
312
|
+
current = self.match_stack.pop(0)
|
313
|
+
|
314
|
+
current_match = current.match
|
315
|
+
current_qubit = current.qubit
|
316
|
+
current_clbit = current.clbit
|
317
|
+
|
318
|
+
template_sublist = [x[0] for x in current_match]
|
319
|
+
circuit_sublist = [x[1] for x in current_match]
|
320
|
+
circuit_sublist.sort()
|
321
|
+
|
322
|
+
# Fake bind any parameters in the template
|
323
|
+
template = self._attempt_bind(template_sublist, circuit_sublist)
|
324
|
+
if template is None or self._incr_num_parameters(template):
|
325
|
+
continue
|
326
|
+
|
327
|
+
template_list = range(0, self.template_dag_dep.size())
|
328
|
+
template_complement = list(set(template_list) - set(template_sublist))
|
329
|
+
|
330
|
+
# If the match obey the rule then it is added to the list.
|
331
|
+
if self._rules(circuit_sublist, template_sublist, template_complement):
|
332
|
+
template_sublist_inverse = self._template_inverse(
|
333
|
+
template_list, template_sublist, template_complement
|
334
|
+
)
|
335
|
+
|
336
|
+
config = SubstitutionConfig(
|
337
|
+
circuit_sublist,
|
338
|
+
template_sublist_inverse,
|
339
|
+
[],
|
340
|
+
current_qubit,
|
341
|
+
template,
|
342
|
+
current_clbit,
|
343
|
+
)
|
344
|
+
self.substitution_list.append(config)
|
345
|
+
|
346
|
+
# Remove incompatible matches.
|
347
|
+
self._remove_impossible()
|
348
|
+
|
349
|
+
# First sort the matches according to the smallest index in the matches (circuit).
|
350
|
+
self.substitution_list.sort(key=lambda x: x.circuit_config[0])
|
351
|
+
|
352
|
+
# Change position of the groups due to predecessors of other groups.
|
353
|
+
self._substitution_sort()
|
354
|
+
|
355
|
+
for scenario in self.substitution_list:
|
356
|
+
index = self.substitution_list.index(scenario)
|
357
|
+
scenario.pred_block = self._pred_block(scenario.circuit_config, index)
|
358
|
+
|
359
|
+
circuit_list = []
|
360
|
+
for elem in self.substitution_list:
|
361
|
+
circuit_list = circuit_list + elem.circuit_config + elem.pred_block
|
362
|
+
|
363
|
+
# Unmatched gates that are not predecessors of any group of matches.
|
364
|
+
self.unmatched_list = sorted(set(range(0, self.circuit_dag_dep.size())) - set(circuit_list))
|
365
|
+
|
366
|
+
def run_dag_opt(self):
|
367
|
+
"""
|
368
|
+
It runs the substitution algorithm and creates the optimized DAGCircuit().
|
369
|
+
"""
|
370
|
+
self._substitution()
|
371
|
+
|
372
|
+
dag_dep_opt = DAGDependency()
|
373
|
+
|
374
|
+
dag_dep_opt.name = self.circuit_dag_dep.name
|
375
|
+
|
376
|
+
qregs = list(self.circuit_dag_dep.qregs.values())
|
377
|
+
cregs = list(self.circuit_dag_dep.cregs.values())
|
378
|
+
|
379
|
+
for register in qregs:
|
380
|
+
dag_dep_opt.add_qreg(register)
|
381
|
+
|
382
|
+
for register in cregs:
|
383
|
+
dag_dep_opt.add_creg(register)
|
384
|
+
|
385
|
+
already_sub = []
|
386
|
+
|
387
|
+
if self.substitution_list:
|
388
|
+
# Loop over the different matches.
|
389
|
+
for group in self.substitution_list:
|
390
|
+
|
391
|
+
circuit_sub = group.circuit_config
|
392
|
+
template_inverse = group.template_config
|
393
|
+
|
394
|
+
pred = group.pred_block
|
395
|
+
|
396
|
+
qubit = group.qubit_config[0]
|
397
|
+
|
398
|
+
if group.clbit_config:
|
399
|
+
clbit = group.clbit_config[0]
|
400
|
+
else:
|
401
|
+
clbit = []
|
402
|
+
|
403
|
+
# First add all the predecessors of the given match.
|
404
|
+
for elem in pred:
|
405
|
+
node = self.circuit_dag_dep.get_node(elem)
|
406
|
+
inst = node.op.copy()
|
407
|
+
dag_dep_opt.add_op_node(inst, node.qargs, node.cargs)
|
408
|
+
already_sub.append(elem)
|
409
|
+
|
410
|
+
already_sub = already_sub + circuit_sub
|
411
|
+
|
412
|
+
# Then add the inverse of the template.
|
413
|
+
for index in template_inverse:
|
414
|
+
all_qubits = self.circuit_dag_dep.qubits
|
415
|
+
qarg_t = group.template_dag_dep.get_node(index).qindices
|
416
|
+
qarg_c = [qubit[x] for x in qarg_t]
|
417
|
+
qargs = [all_qubits[x] for x in qarg_c]
|
418
|
+
|
419
|
+
all_clbits = self.circuit_dag_dep.clbits
|
420
|
+
carg_t = group.template_dag_dep.get_node(index).cindices
|
421
|
+
|
422
|
+
if all_clbits and clbit:
|
423
|
+
carg_c = [clbit[x] for x in carg_t]
|
424
|
+
cargs = [all_clbits[x] for x in carg_c]
|
425
|
+
else:
|
426
|
+
cargs = []
|
427
|
+
node = group.template_dag_dep.get_node(index)
|
428
|
+
inst = node.op.copy()
|
429
|
+
dag_dep_opt.add_op_node(inst.inverse(), qargs, cargs)
|
430
|
+
|
431
|
+
# Add the unmatched gates.
|
432
|
+
for node_id in self.unmatched_list:
|
433
|
+
node = self.circuit_dag_dep.get_node(node_id)
|
434
|
+
inst = node.op.copy()
|
435
|
+
dag_dep_opt.add_op_node(inst, node.qargs, node.cargs)
|
436
|
+
|
437
|
+
dag_dep_opt._add_predecessors()
|
438
|
+
dag_dep_opt._add_successors()
|
439
|
+
# If there is no valid match, it returns the original dag.
|
440
|
+
else:
|
441
|
+
dag_dep_opt = self.circuit_dag_dep
|
442
|
+
|
443
|
+
self.dag_dep_optimized = dag_dep_opt
|
444
|
+
self.dag_optimized = dagdependency_to_dag(dag_dep_opt)
|
445
|
+
|
446
|
+
@_optionals.HAS_SYMPY.require_in_call("Bind parameters in templates")
|
447
|
+
def _attempt_bind(self, template_sublist, circuit_sublist):
|
448
|
+
"""
|
449
|
+
Copies the template and attempts to bind any parameters,
|
450
|
+
i.e. attempts to solve for a valid parameter assignment.
|
451
|
+
template_sublist and circuit_sublist match up to the
|
452
|
+
assignment of the parameters. For example the template
|
453
|
+
|
454
|
+
.. code-block:: text
|
455
|
+
|
456
|
+
┌───────────┐ ┌────────┐
|
457
|
+
q_0: ┤ P(-1.0*β) ├──■────────────■──┤0 ├
|
458
|
+
├───────────┤┌─┴─┐┌──────┐┌─┴─┐│ CZ(β) │
|
459
|
+
q_1: ┤ P(-1.0*β) ├┤ X ├┤ P(β) ├┤ X ├┤1 ├
|
460
|
+
└───────────┘└───┘└──────┘└───┘└────────┘
|
461
|
+
|
462
|
+
should only maximally match once in the circuit
|
463
|
+
|
464
|
+
.. code-block:: text
|
465
|
+
|
466
|
+
┌───────┐
|
467
|
+
q_0: ┤ P(-2) ├──■────────────■────────────────────────────
|
468
|
+
├───────┤┌─┴─┐┌──────┐┌─┴─┐┌──────┐
|
469
|
+
q_1: ┤ P(-2) ├┤ X ├┤ P(2) ├┤ X ├┤ P(3) ├──■────────────■──
|
470
|
+
└┬──────┤└───┘└──────┘└───┘└──────┘┌─┴─┐┌──────┐┌─┴─┐
|
471
|
+
q_2: ─┤ P(3) ├──────────────────────────┤ X ├┤ P(3) ├┤ X ├
|
472
|
+
└──────┘ └───┘└──────┘└───┘
|
473
|
+
|
474
|
+
However, up until attempt bind is called, the soft matching
|
475
|
+
will have found two matches due to the parameters.
|
476
|
+
The first match can be satisfied with β=2. However, the
|
477
|
+
second match would imply both β=3 and β=-3 which is impossible.
|
478
|
+
Attempt bind detects inconsistencies by solving a system of equations
|
479
|
+
given by the parameter expressions in the sub-template and the
|
480
|
+
value of the parameters in the gates of the sub-circuit. If a
|
481
|
+
solution is found then the match is valid and the parameters
|
482
|
+
are assigned. If not, None is returned.
|
483
|
+
|
484
|
+
In order to resolve the conflict of the same parameter names in the
|
485
|
+
circuit and template, each variable in the template sublist is
|
486
|
+
re-assigned to a new dummy parameter with a completely separate name
|
487
|
+
if it clashes with one that exists in an input circuit.
|
488
|
+
|
489
|
+
Args:
|
490
|
+
template_sublist (list): part of the matched template.
|
491
|
+
circuit_sublist (list): part of the matched circuit.
|
492
|
+
|
493
|
+
Returns:
|
494
|
+
DAGDependency: A deep copy of the template with
|
495
|
+
the parameters bound. If no binding satisfies the
|
496
|
+
parameter constraints, returns None.
|
497
|
+
"""
|
498
|
+
import sympy as sym
|
499
|
+
|
500
|
+
if _optionals.HAS_SYMENGINE:
|
501
|
+
import symengine
|
502
|
+
|
503
|
+
# Converts Sympy expressions to Symengine ones.
|
504
|
+
to_native_symbolic = symengine.sympify
|
505
|
+
else:
|
506
|
+
# Our native form is sympy, so we don't need to do anything.
|
507
|
+
to_native_symbolic = lambda x: x
|
508
|
+
|
509
|
+
circuit_params, template_params = [], []
|
510
|
+
# Set of all parameter names that are present in the circuits to be optimized.
|
511
|
+
circuit_params_set = set()
|
512
|
+
|
513
|
+
template_dag_dep = copy.deepcopy(self.template_dag_dep)
|
514
|
+
|
515
|
+
# add parameters from circuit to circuit_params
|
516
|
+
for idx, _ in enumerate(template_sublist):
|
517
|
+
qc_idx = circuit_sublist[idx]
|
518
|
+
parameters = self.circuit_dag_dep.get_node(qc_idx).op.params
|
519
|
+
circuit_params += parameters
|
520
|
+
for parameter in parameters:
|
521
|
+
if isinstance(parameter, ParameterExpression):
|
522
|
+
circuit_params_set.update(x.name for x in parameter.parameters)
|
523
|
+
|
524
|
+
_dummy_counter = itertools.count()
|
525
|
+
|
526
|
+
def dummy_parameter():
|
527
|
+
# Strictly not _guaranteed_ to avoid naming clashes, but if someone's calling their
|
528
|
+
# parameters this then that's their own fault.
|
529
|
+
return Parameter(f"_qiskit_template_dummy_{next(_dummy_counter)}")
|
530
|
+
|
531
|
+
# Substitutions for parameters that have clashing names between the input circuits and the
|
532
|
+
# defined templates.
|
533
|
+
template_clash_substitutions = collections.defaultdict(dummy_parameter)
|
534
|
+
|
535
|
+
# add parameters from template to template_params, replacing parameters with names that
|
536
|
+
# clash with those in the circuit.
|
537
|
+
for t_idx in template_sublist:
|
538
|
+
node = template_dag_dep.get_node(t_idx)
|
539
|
+
sub_node_params = []
|
540
|
+
for t_param_exp in node.op.params:
|
541
|
+
if isinstance(t_param_exp, ParameterExpression):
|
542
|
+
for t_param in t_param_exp.parameters:
|
543
|
+
if t_param.name in circuit_params_set:
|
544
|
+
new_param = template_clash_substitutions[t_param.name]
|
545
|
+
t_param_exp = t_param_exp.assign(t_param, new_param)
|
546
|
+
sub_node_params.append(t_param_exp)
|
547
|
+
template_params.append(t_param_exp)
|
548
|
+
if not node.op.mutable:
|
549
|
+
node.op = node.op.to_mutable()
|
550
|
+
node.op.params = sub_node_params
|
551
|
+
|
552
|
+
for node in template_dag_dep.get_nodes():
|
553
|
+
sub_node_params = []
|
554
|
+
for param_exp in node.op.params:
|
555
|
+
if isinstance(param_exp, ParameterExpression):
|
556
|
+
for param in param_exp.parameters:
|
557
|
+
if param.name in template_clash_substitutions:
|
558
|
+
param_exp = param_exp.assign(
|
559
|
+
param, template_clash_substitutions[param.name]
|
560
|
+
)
|
561
|
+
sub_node_params.append(param_exp)
|
562
|
+
|
563
|
+
if not node.op.mutable:
|
564
|
+
node.op = node.op.to_mutable()
|
565
|
+
node.op.params = sub_node_params
|
566
|
+
|
567
|
+
# Create the fake binding dict and check
|
568
|
+
equations, circ_dict, temp_symbols = [], {}, {}
|
569
|
+
for circuit_param, template_param in zip(circuit_params, template_params):
|
570
|
+
if isinstance(template_param, ParameterExpression):
|
571
|
+
if isinstance(circuit_param, ParameterExpression):
|
572
|
+
circ_param_sym = circuit_param.sympify()
|
573
|
+
else:
|
574
|
+
# if it's not a ParameterExpression we're a float
|
575
|
+
circ_param_sym = sym.Float(circuit_param)
|
576
|
+
equations.append(sym.Eq(template_param.sympify(), circ_param_sym))
|
577
|
+
|
578
|
+
for param in template_param.parameters:
|
579
|
+
temp_symbols[param] = param.sympify()
|
580
|
+
|
581
|
+
if isinstance(circuit_param, ParameterExpression):
|
582
|
+
for param in circuit_param.parameters:
|
583
|
+
circ_dict[param] = param.sympify()
|
584
|
+
elif template_param != circuit_param:
|
585
|
+
# Both are numeric parameters, but aren't equal.
|
586
|
+
return None
|
587
|
+
|
588
|
+
if not temp_symbols:
|
589
|
+
return template_dag_dep
|
590
|
+
|
591
|
+
# Check compatibility by solving the resulting equation. `dict=True` (surprisingly) forces
|
592
|
+
# the output to always be a list, even if there's exactly one solution.
|
593
|
+
sym_sol = sym.solve(equations, set(temp_symbols.values()), dict=True)
|
594
|
+
if not sym_sol:
|
595
|
+
# No solutions.
|
596
|
+
return None
|
597
|
+
# If there's multiple solutions, arbitrarily pick the first one.
|
598
|
+
sol = {
|
599
|
+
param.name: ParameterExpression(circ_dict, to_native_symbolic(expr))
|
600
|
+
for param, expr in sym_sol[0].items()
|
601
|
+
}
|
602
|
+
fake_bind = {key: sol[key.name] for key in temp_symbols}
|
603
|
+
|
604
|
+
for node in template_dag_dep.get_nodes():
|
605
|
+
bound_params = []
|
606
|
+
for param_exp in node.op.params:
|
607
|
+
if isinstance(param_exp, ParameterExpression):
|
608
|
+
for param in param_exp.parameters:
|
609
|
+
if param in fake_bind:
|
610
|
+
if fake_bind[param] not in bound_params:
|
611
|
+
param_exp = param_exp.assign(param, fake_bind[param])
|
612
|
+
else:
|
613
|
+
param_exp = float(param_exp)
|
614
|
+
bound_params.append(param_exp)
|
615
|
+
|
616
|
+
if not node.op.mutable:
|
617
|
+
node.op = node.op.to_mutable()
|
618
|
+
node.op.params = bound_params
|
619
|
+
|
620
|
+
return template_dag_dep
|
621
|
+
|
622
|
+
def _incr_num_parameters(self, template):
|
623
|
+
"""
|
624
|
+
Checks if template substitution would increase the number of
|
625
|
+
parameters in the circuit.
|
626
|
+
"""
|
627
|
+
template_params = set()
|
628
|
+
for param_list in (node.op.params for node in template.get_nodes()):
|
629
|
+
for param_exp in param_list:
|
630
|
+
if isinstance(param_exp, ParameterExpression):
|
631
|
+
template_params.update(param_exp.parameters)
|
632
|
+
|
633
|
+
circuit_params = set()
|
634
|
+
for param_list in (node.op.params for node in self.circuit_dag_dep.get_nodes()):
|
635
|
+
for param_exp in param_list:
|
636
|
+
if isinstance(param_exp, ParameterExpression):
|
637
|
+
circuit_params.update(param_exp.parameters)
|
638
|
+
|
639
|
+
return len(template_params) > len(circuit_params)
|