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,250 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2023.
|
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
|
+
"""Optimize chains of single-qubit gates using Euler 1q decomposer"""
|
14
|
+
|
15
|
+
import logging
|
16
|
+
import math
|
17
|
+
|
18
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
19
|
+
from qiskit.transpiler.passes.utils import control_flow
|
20
|
+
from qiskit.synthesis.one_qubit import one_qubit_decompose
|
21
|
+
from qiskit._accelerate import euler_one_qubit_decomposer
|
22
|
+
from qiskit.circuit.library.standard_gates import (
|
23
|
+
UGate,
|
24
|
+
PhaseGate,
|
25
|
+
U3Gate,
|
26
|
+
U2Gate,
|
27
|
+
U1Gate,
|
28
|
+
RXGate,
|
29
|
+
RYGate,
|
30
|
+
RZGate,
|
31
|
+
RGate,
|
32
|
+
SXGate,
|
33
|
+
XGate,
|
34
|
+
)
|
35
|
+
from qiskit.circuit import Qubit
|
36
|
+
from qiskit.circuit.quantumcircuitdata import CircuitInstruction
|
37
|
+
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
38
|
+
|
39
|
+
|
40
|
+
logger = logging.getLogger(__name__)
|
41
|
+
|
42
|
+
# When expanding the list of supported gates this needs to updated in
|
43
|
+
# lockstep with the VALID_BASES constant in src/euler_one_qubit_decomposer.rs
|
44
|
+
# and the global variables in one_qubit_decompose.py
|
45
|
+
NAME_MAP = {
|
46
|
+
"u": UGate,
|
47
|
+
"u1": U1Gate,
|
48
|
+
"u2": U2Gate,
|
49
|
+
"u3": U3Gate,
|
50
|
+
"p": PhaseGate,
|
51
|
+
"rx": RXGate,
|
52
|
+
"ry": RYGate,
|
53
|
+
"rz": RZGate,
|
54
|
+
"r": RGate,
|
55
|
+
"sx": SXGate,
|
56
|
+
"x": XGate,
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
class Optimize1qGatesDecomposition(TransformationPass):
|
61
|
+
"""Optimize chains of single-qubit gates by combining them into a single gate.
|
62
|
+
|
63
|
+
The decision to replace the original chain with a new re-synthesis depends on:
|
64
|
+
- whether the original chain was out of basis: replace
|
65
|
+
- whether the original chain was in basis but re-synthesis is lower error: replace
|
66
|
+
- whether the original chain amounts to identity: replace with null
|
67
|
+
|
68
|
+
Error is computed as a multiplication of the errors of individual gates on that qubit.
|
69
|
+
"""
|
70
|
+
|
71
|
+
def __init__(self, basis=None, target=None):
|
72
|
+
"""Optimize1qGatesDecomposition initializer.
|
73
|
+
|
74
|
+
Args:
|
75
|
+
basis (list[str]): Basis gates to consider, e.g. `['u3', 'cx']`. For the effects
|
76
|
+
of this pass, the basis is the set intersection between the `basis` parameter
|
77
|
+
and the Euler basis. Ignored if ``target`` is also specified.
|
78
|
+
target (Optional[Target]): The :class:`~.Target` object corresponding to the compilation
|
79
|
+
target. When specified, any argument specified for ``basis_gates`` is ignored.
|
80
|
+
"""
|
81
|
+
super().__init__()
|
82
|
+
|
83
|
+
if basis and len(basis) > 0:
|
84
|
+
self._basis_gates = set(basis)
|
85
|
+
else:
|
86
|
+
self._basis_gates = None
|
87
|
+
# Bypass target if it doesn't contain any basis gates (i.e. it's a _FakeTarget), as this
|
88
|
+
# not part of the official target model.
|
89
|
+
self._target = target if target is not None and len(target.operation_names) > 0 else None
|
90
|
+
self._global_decomposers = None
|
91
|
+
self._local_decomposers_cache = {}
|
92
|
+
|
93
|
+
if self._basis_gates:
|
94
|
+
self._global_decomposers = _possible_decomposers(set(basis))
|
95
|
+
elif target is None or len(target.operation_names) == 0:
|
96
|
+
self._global_decomposers = _possible_decomposers(None)
|
97
|
+
self._basis_gates = None
|
98
|
+
|
99
|
+
self.error_map = self._build_error_map()
|
100
|
+
|
101
|
+
def _build_error_map(self):
|
102
|
+
# include path for when target exists but target.num_qubits is None (BasicSimulator)
|
103
|
+
if self._target is not None and self._target.num_qubits is not None:
|
104
|
+
error_map = euler_one_qubit_decomposer.OneQubitGateErrorMap(self._target.num_qubits)
|
105
|
+
for qubit in range(self._target.num_qubits):
|
106
|
+
gate_error = {}
|
107
|
+
for gate, gate_props in self._target.items():
|
108
|
+
if gate_props is not None:
|
109
|
+
props = gate_props.get((qubit,), None)
|
110
|
+
if props is not None and props.error is not None:
|
111
|
+
gate_error[gate] = props.error
|
112
|
+
error_map.add_qubit(gate_error)
|
113
|
+
return error_map
|
114
|
+
else:
|
115
|
+
return None
|
116
|
+
|
117
|
+
def _get_decomposer(self, qubit=None):
|
118
|
+
# include path for when target exists but target.num_qubits is None (BasicSimulator)
|
119
|
+
if (
|
120
|
+
self._target is not None
|
121
|
+
and self._target.num_qubits is not None
|
122
|
+
and len(self._target.operation_names) > 0
|
123
|
+
):
|
124
|
+
if qubit is not None:
|
125
|
+
qubits_tuple = (qubit,)
|
126
|
+
else:
|
127
|
+
qubits_tuple = None
|
128
|
+
if qubits_tuple in self._local_decomposers_cache:
|
129
|
+
decomposers = self._local_decomposers_cache[qubits_tuple]
|
130
|
+
else:
|
131
|
+
available_1q_basis = set(self._target.operation_names_for_qargs(qubits_tuple))
|
132
|
+
decomposers = _possible_decomposers(available_1q_basis)
|
133
|
+
else:
|
134
|
+
decomposers = self._global_decomposers
|
135
|
+
return decomposers
|
136
|
+
|
137
|
+
def _resynthesize_run(self, matrix, qubit=None):
|
138
|
+
"""
|
139
|
+
Re-synthesizes one 2x2 `matrix`, typically extracted via `dag.collect_1q_runs`.
|
140
|
+
|
141
|
+
Returns the newly synthesized circuit in the indicated basis, or None
|
142
|
+
if no synthesis routine applied.
|
143
|
+
|
144
|
+
When multiple synthesis options are available, it prefers the one with the lowest
|
145
|
+
error when the circuit is applied to `qubit`.
|
146
|
+
"""
|
147
|
+
decomposers = self._get_decomposer(qubit)
|
148
|
+
|
149
|
+
best_synth_circuit = euler_one_qubit_decomposer.unitary_to_gate_sequence(
|
150
|
+
matrix,
|
151
|
+
decomposers,
|
152
|
+
qubit,
|
153
|
+
self.error_map,
|
154
|
+
)
|
155
|
+
return best_synth_circuit
|
156
|
+
|
157
|
+
def _gate_sequence_to_dag(self, best_synth_circuit):
|
158
|
+
qubits = (Qubit(),)
|
159
|
+
out_dag = DAGCircuit()
|
160
|
+
out_dag.add_qubits(qubits)
|
161
|
+
out_dag.global_phase = best_synth_circuit.global_phase
|
162
|
+
|
163
|
+
for gate_name, angles in best_synth_circuit:
|
164
|
+
op = CircuitInstruction.from_standard(gate_name, qubits, angles)
|
165
|
+
out_dag.apply_operation_back(op.operation, qubits, check=False)
|
166
|
+
return out_dag
|
167
|
+
|
168
|
+
def _substitution_checks(self, old_run, new_circ, basis, qubit, old_error=None, new_error=None):
|
169
|
+
"""
|
170
|
+
Returns `True` when it is recommended to replace `old_run` with `new_circ` over `basis`.
|
171
|
+
"""
|
172
|
+
if new_circ is None:
|
173
|
+
return False
|
174
|
+
|
175
|
+
# does this run have gates not in the image of ._decomposers?
|
176
|
+
if basis is not None:
|
177
|
+
not_basis_p = any(g.name not in basis for g in old_run)
|
178
|
+
else:
|
179
|
+
# If no basis is specified then we're always in the basis
|
180
|
+
not_basis_p = False
|
181
|
+
|
182
|
+
# if we're outside of the basis set, we're obligated to logically decompose.
|
183
|
+
# if we're outside of the set of gates for which we have physical definitions,
|
184
|
+
# then we _try_ to decompose, using the results if we see improvement.
|
185
|
+
if not not_basis_p:
|
186
|
+
if new_error is None:
|
187
|
+
new_error = self._error(new_circ, qubit)
|
188
|
+
if old_error is None:
|
189
|
+
old_error = self._error(old_run, qubit)
|
190
|
+
else:
|
191
|
+
new_error = 0.0
|
192
|
+
old_error = 0.0
|
193
|
+
|
194
|
+
return (
|
195
|
+
not_basis_p
|
196
|
+
or (True and new_error < old_error)
|
197
|
+
or (math.isclose(new_error[0], 0) and not math.isclose(old_error[0], 0))
|
198
|
+
)
|
199
|
+
|
200
|
+
@control_flow.trivial_recurse
|
201
|
+
def run(self, dag):
|
202
|
+
"""Run the Optimize1qGatesDecomposition pass on `dag`.
|
203
|
+
|
204
|
+
Args:
|
205
|
+
dag (DAGCircuit): the DAG to be optimized.
|
206
|
+
|
207
|
+
Returns:
|
208
|
+
DAGCircuit: the optimized DAG.
|
209
|
+
"""
|
210
|
+
euler_one_qubit_decomposer.optimize_1q_gates_decomposition(
|
211
|
+
dag,
|
212
|
+
target=self._target,
|
213
|
+
global_decomposers=self._global_decomposers,
|
214
|
+
basis_gates=self._basis_gates,
|
215
|
+
)
|
216
|
+
return dag
|
217
|
+
|
218
|
+
def _error(self, circuit, qubit):
|
219
|
+
"""
|
220
|
+
Calculate a rough error for a `circuit` that runs on a specific
|
221
|
+
`qubit` of `target` (`circuit` is a list of DAGOPNodes).
|
222
|
+
|
223
|
+
Use basis errors from target if available, otherwise use length
|
224
|
+
of circuit as a weak proxy for error.
|
225
|
+
"""
|
226
|
+
return euler_one_qubit_decomposer.compute_error_list(circuit, qubit, self.error_map)
|
227
|
+
|
228
|
+
|
229
|
+
def _possible_decomposers(basis_set):
|
230
|
+
decomposers = []
|
231
|
+
if basis_set is None:
|
232
|
+
decomposers = list(one_qubit_decompose.ONE_QUBIT_EULER_BASIS_GATES)
|
233
|
+
else:
|
234
|
+
euler_basis_gates = one_qubit_decompose.ONE_QUBIT_EULER_BASIS_GATES
|
235
|
+
for euler_basis_name, gates in euler_basis_gates.items():
|
236
|
+
if set(gates).issubset(basis_set):
|
237
|
+
decomposers.append(euler_basis_name)
|
238
|
+
# If both U3 and U321 are in decomposer list only run U321 because
|
239
|
+
# in worst case it will produce the same U3 output, but in the general
|
240
|
+
# case it will use U2 and U1 which will be more efficient.
|
241
|
+
if "U3" in decomposers and "U321" in decomposers:
|
242
|
+
decomposers.remove("U3")
|
243
|
+
# If both ZSX and ZSXX are in decomposer list only run ZSXX because
|
244
|
+
# in the worst case it will produce the same output, but in the general
|
245
|
+
# case it will simplify X rotations to use X gate instead of multiple
|
246
|
+
# SX gates and be more efficient. Running multiple decomposers in this
|
247
|
+
# case will just waste time.
|
248
|
+
if "ZSX" in decomposers and "ZSXX" in decomposers:
|
249
|
+
decomposers.remove("ZSX")
|
250
|
+
return decomposers
|
@@ -0,0 +1,384 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2018.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""Optimize chains of single-qubit u1, u2, u3 gates by combining them into a single gate."""
|
14
|
+
|
15
|
+
from itertools import groupby
|
16
|
+
|
17
|
+
import numpy as np
|
18
|
+
|
19
|
+
from qiskit.transpiler.exceptions import TranspilerError
|
20
|
+
from qiskit.circuit.library.standard_gates.p import PhaseGate
|
21
|
+
from qiskit.circuit.library.standard_gates.u import UGate
|
22
|
+
from qiskit.circuit.library.standard_gates.u1 import U1Gate
|
23
|
+
from qiskit.circuit.library.standard_gates.u2 import U2Gate
|
24
|
+
from qiskit.circuit.library.standard_gates.u3 import U3Gate
|
25
|
+
from qiskit.circuit import ParameterExpression
|
26
|
+
from qiskit.circuit.gate import Gate
|
27
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
28
|
+
from qiskit.quantum_info.quaternion import Quaternion
|
29
|
+
from qiskit._accelerate.optimize_1q_gates import compose_u3_rust
|
30
|
+
|
31
|
+
_CHOP_THRESHOLD = 1e-15
|
32
|
+
|
33
|
+
|
34
|
+
class Optimize1qGates(TransformationPass):
|
35
|
+
"""Optimize chains of single-qubit u1, u2, u3 gates by combining them into a single gate."""
|
36
|
+
|
37
|
+
def __init__(self, basis=None, eps=1e-15, target=None):
|
38
|
+
"""Optimize1qGates initializer.
|
39
|
+
|
40
|
+
Args:
|
41
|
+
basis (list[str]): Basis gates to consider, e.g. `['u3', 'cx']`. For the effects
|
42
|
+
of this pass, the basis is the set intersection between the `basis` parameter and
|
43
|
+
the set `{'u1','u2','u3', 'u', 'p'}`.
|
44
|
+
eps (float): EPS to check against
|
45
|
+
target (Target): The :class:`~.Target` representing the target backend, if both
|
46
|
+
``basis`` and ``target`` are specified then this argument will take
|
47
|
+
precedence and ``basis`` will be ignored.
|
48
|
+
"""
|
49
|
+
super().__init__()
|
50
|
+
self.basis = set(basis) if basis else {"u1", "u2", "u3"}
|
51
|
+
self.eps = eps
|
52
|
+
self.target = target
|
53
|
+
|
54
|
+
def run(self, dag):
|
55
|
+
"""Run the Optimize1qGates pass on `dag`.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
dag (DAGCircuit): the DAG to be optimized.
|
59
|
+
|
60
|
+
Returns:
|
61
|
+
DAGCircuit: the optimized DAG.
|
62
|
+
|
63
|
+
Raises:
|
64
|
+
TranspilerError: if ``YZY`` and ``ZYZ`` angles do not give same rotation matrix.
|
65
|
+
"""
|
66
|
+
use_u = "u" in self.basis
|
67
|
+
use_p = "p" in self.basis
|
68
|
+
runs = dag.collect_runs(["u1", "u2", "u3", "u", "p"])
|
69
|
+
runs = _split_runs_on_parameters(runs)
|
70
|
+
for run in runs:
|
71
|
+
run_qubits = None
|
72
|
+
if self.target is not None:
|
73
|
+
run_qubits = tuple(dag.find_bit(x).index for x in run[0].qargs)
|
74
|
+
|
75
|
+
if self.target.instruction_supported("p", run_qubits):
|
76
|
+
right_name = "p"
|
77
|
+
else:
|
78
|
+
right_name = "u1"
|
79
|
+
else:
|
80
|
+
if use_p:
|
81
|
+
right_name = "p"
|
82
|
+
else:
|
83
|
+
right_name = "u1"
|
84
|
+
right_parameters = (0, 0, 0) # (theta, phi, lambda)
|
85
|
+
right_global_phase = 0
|
86
|
+
for current_node in run:
|
87
|
+
left_name = current_node.name
|
88
|
+
if (
|
89
|
+
getattr(current_node, "condition", None) is not None
|
90
|
+
or len(current_node.qargs) != 1
|
91
|
+
or left_name not in ["p", "u1", "u2", "u3", "u", "id"]
|
92
|
+
):
|
93
|
+
raise TranspilerError("internal error")
|
94
|
+
if left_name in ("u1", "p"):
|
95
|
+
left_parameters = (0, 0, current_node.op.params[0])
|
96
|
+
elif left_name == "u2":
|
97
|
+
left_parameters = (
|
98
|
+
np.pi / 2,
|
99
|
+
current_node.op.params[0],
|
100
|
+
current_node.op.params[1],
|
101
|
+
)
|
102
|
+
elif left_name in ("u3", "u"):
|
103
|
+
left_parameters = tuple(current_node.op.params)
|
104
|
+
else:
|
105
|
+
if use_p:
|
106
|
+
left_name = "p"
|
107
|
+
else:
|
108
|
+
left_name = "u1" # replace id with u1
|
109
|
+
left_parameters = (0, 0, 0)
|
110
|
+
if (
|
111
|
+
current_node.op.definition is not None
|
112
|
+
and current_node.op.definition.global_phase
|
113
|
+
):
|
114
|
+
right_global_phase += current_node.op.definition.global_phase
|
115
|
+
|
116
|
+
# If there are any sympy objects coming from the gate convert
|
117
|
+
# to numpy.
|
118
|
+
try:
|
119
|
+
left_parameters = tuple(float(x) for x in left_parameters)
|
120
|
+
except TypeError:
|
121
|
+
# If left_parameters contained any unbound Parameters
|
122
|
+
pass
|
123
|
+
|
124
|
+
# Compose gates
|
125
|
+
name_tuple = (left_name, right_name)
|
126
|
+
if name_tuple in (("u1", "u1"), ("p", "p")):
|
127
|
+
# u1(lambda1) * u1(lambda2) = u1(lambda1 + lambda2)
|
128
|
+
right_parameters = (0, 0, right_parameters[2] + left_parameters[2])
|
129
|
+
elif name_tuple in (("u1", "u2"), ("p", "u2")):
|
130
|
+
# u1(lambda1) * u2(phi2, lambda2) = u2(phi2 + lambda1, lambda2)
|
131
|
+
right_parameters = (
|
132
|
+
np.pi / 2,
|
133
|
+
right_parameters[1] + left_parameters[2],
|
134
|
+
right_parameters[2],
|
135
|
+
)
|
136
|
+
elif name_tuple in (("u2", "u1"), ("u2", "p")):
|
137
|
+
# u2(phi1, lambda1) * u1(lambda2) = u2(phi1, lambda1 + lambda2)
|
138
|
+
right_name = "u2"
|
139
|
+
right_parameters = (
|
140
|
+
np.pi / 2,
|
141
|
+
left_parameters[1],
|
142
|
+
right_parameters[2] + left_parameters[2],
|
143
|
+
)
|
144
|
+
elif name_tuple in (("u1", "u3"), ("u1", "u"), ("p", "u3"), ("p", "u")):
|
145
|
+
# u1(lambda1) * u3(theta2, phi2, lambda2) =
|
146
|
+
# u3(theta2, phi2 + lambda1, lambda2)
|
147
|
+
right_parameters = (
|
148
|
+
right_parameters[0],
|
149
|
+
right_parameters[1] + left_parameters[2],
|
150
|
+
right_parameters[2],
|
151
|
+
)
|
152
|
+
elif name_tuple in (("u3", "u1"), ("u", "u1"), ("u3", "p"), ("u", "p")):
|
153
|
+
# u3(theta1, phi1, lambda1) * u1(lambda2) =
|
154
|
+
# u3(theta1, phi1, lambda1 + lambda2)
|
155
|
+
if use_u:
|
156
|
+
right_name = "u"
|
157
|
+
else:
|
158
|
+
right_name = "u3"
|
159
|
+
right_parameters = (
|
160
|
+
left_parameters[0],
|
161
|
+
left_parameters[1],
|
162
|
+
right_parameters[2] + left_parameters[2],
|
163
|
+
)
|
164
|
+
elif name_tuple == ("u2", "u2"):
|
165
|
+
# Using Ry(pi/2).Rz(2*lambda).Ry(pi/2) =
|
166
|
+
# Rz(pi/2).Ry(pi-2*lambda).Rz(pi/2),
|
167
|
+
# u2(phi1, lambda1) * u2(phi2, lambda2) =
|
168
|
+
# u3(pi - lambda1 - phi2, phi1 + pi/2, lambda2 + pi/2)
|
169
|
+
if use_u:
|
170
|
+
right_name = "u"
|
171
|
+
else:
|
172
|
+
right_name = "u3"
|
173
|
+
right_parameters = (
|
174
|
+
np.pi - left_parameters[2] - right_parameters[1],
|
175
|
+
left_parameters[1] + np.pi / 2,
|
176
|
+
right_parameters[2] + np.pi / 2,
|
177
|
+
)
|
178
|
+
elif name_tuple[1] == "nop":
|
179
|
+
right_name = left_name
|
180
|
+
right_parameters = left_parameters
|
181
|
+
else:
|
182
|
+
# For composing u3's or u2's with u3's, use
|
183
|
+
# u2(phi, lambda) = u3(pi/2, phi, lambda)
|
184
|
+
# together with the qiskit.mapper.compose_u3 method.
|
185
|
+
if use_u:
|
186
|
+
right_name = "u"
|
187
|
+
else:
|
188
|
+
right_name = "u3"
|
189
|
+
# Evaluate the symbolic expressions for efficiency
|
190
|
+
right_parameters = Optimize1qGates.compose_u3(
|
191
|
+
left_parameters[0],
|
192
|
+
left_parameters[1],
|
193
|
+
left_parameters[2],
|
194
|
+
right_parameters[0],
|
195
|
+
right_parameters[1],
|
196
|
+
right_parameters[2],
|
197
|
+
)
|
198
|
+
# Why evalf()? This program:
|
199
|
+
# OPENQASM 2.0;
|
200
|
+
# include "qelib1.inc";
|
201
|
+
# qreg q[2];
|
202
|
+
# creg c[2];
|
203
|
+
# u3(0.518016983430947*pi,1.37051598592907*pi,1.36816383603222*pi) q[0];
|
204
|
+
# u3(1.69867232277986*pi,0.371448347747471*pi,0.461117217930936*pi) q[0];
|
205
|
+
# u3(0.294319836336836*pi,0.450325871124225*pi,1.46804720442555*pi) q[0];
|
206
|
+
# measure q -> c;
|
207
|
+
# took >630 seconds (did not complete) to optimize without
|
208
|
+
# calling evalf() at all, 19 seconds to optimize calling
|
209
|
+
# evalf() AFTER compose_u3, and 1 second to optimize
|
210
|
+
# calling evalf() BEFORE compose_u3.
|
211
|
+
# 1. Here down, when we simplify, we add f(theta) to lambda to
|
212
|
+
# correct the global phase when f(theta) is 2*pi. This isn't
|
213
|
+
# necessary but the other steps preserve the global phase, so
|
214
|
+
# we continue in that manner.
|
215
|
+
# 2. The final step will remove Z rotations by 2*pi.
|
216
|
+
# 3. Note that is_zero is true only if the expression is exactly
|
217
|
+
# zero. If the input expressions have already been evaluated
|
218
|
+
# then these final simplifications will not occur.
|
219
|
+
# TODO After we refactor, we should have separate passes for
|
220
|
+
# exact and approximate rewriting.
|
221
|
+
|
222
|
+
# Y rotation is 0 mod 2*pi, so the gate is a u1
|
223
|
+
if (
|
224
|
+
not isinstance(right_parameters[0], ParameterExpression)
|
225
|
+
and abs(np.mod(right_parameters[0], (2 * np.pi))) < self.eps
|
226
|
+
and right_name != "u1"
|
227
|
+
and right_name != "p"
|
228
|
+
):
|
229
|
+
if use_p:
|
230
|
+
right_name = "p"
|
231
|
+
else:
|
232
|
+
right_name = "u1"
|
233
|
+
right_parameters = (
|
234
|
+
0,
|
235
|
+
0,
|
236
|
+
right_parameters[1] + right_parameters[2] + right_parameters[0],
|
237
|
+
)
|
238
|
+
# Y rotation is pi/2 or -pi/2 mod 2*pi, so the gate is a u2
|
239
|
+
if right_name in ("u3", "u"):
|
240
|
+
if not isinstance(right_parameters[0], ParameterExpression):
|
241
|
+
# theta = pi/2 + 2*k*pi
|
242
|
+
right_angle = right_parameters[0] - np.pi / 2
|
243
|
+
if abs(right_angle) < self.eps:
|
244
|
+
right_angle = 0
|
245
|
+
if abs(np.mod((right_angle), 2 * np.pi)) < self.eps:
|
246
|
+
right_name = "u2"
|
247
|
+
right_parameters = (
|
248
|
+
np.pi / 2,
|
249
|
+
right_parameters[1],
|
250
|
+
right_parameters[2] + (right_parameters[0] - np.pi / 2),
|
251
|
+
)
|
252
|
+
# theta = -pi/2 + 2*k*pi
|
253
|
+
right_angle = right_parameters[0] + np.pi / 2
|
254
|
+
if abs(right_angle) < self.eps:
|
255
|
+
right_angle = 0
|
256
|
+
if abs(np.mod(right_angle, 2 * np.pi)) < self.eps:
|
257
|
+
right_name = "u2"
|
258
|
+
right_parameters = (
|
259
|
+
np.pi / 2,
|
260
|
+
right_parameters[1] + np.pi,
|
261
|
+
right_parameters[2] - np.pi + (right_parameters[0] + np.pi / 2),
|
262
|
+
)
|
263
|
+
|
264
|
+
# u1 and lambda is 0 mod 2*pi so gate is nop (up to a global phase)
|
265
|
+
if (
|
266
|
+
not isinstance(right_parameters[2], ParameterExpression)
|
267
|
+
and right_name in ("u1", "p")
|
268
|
+
and abs(np.mod(right_parameters[2], 2 * np.pi)) < self.eps
|
269
|
+
):
|
270
|
+
right_name = "nop"
|
271
|
+
|
272
|
+
if self.target is not None:
|
273
|
+
if right_name == "u2" and not self.target.instruction_supported("u2", run_qubits):
|
274
|
+
if self.target.instruction_supported("u", run_qubits):
|
275
|
+
right_name = "u"
|
276
|
+
else:
|
277
|
+
right_name = "u3"
|
278
|
+
if right_name in ("u1", "p") and not self.target.instruction_supported(
|
279
|
+
right_name, run_qubits
|
280
|
+
):
|
281
|
+
if self.target.instruction_supported("u", run_qubits):
|
282
|
+
right_name = "u"
|
283
|
+
else:
|
284
|
+
right_name = "u3"
|
285
|
+
else:
|
286
|
+
if right_name == "u2" and "u2" not in self.basis:
|
287
|
+
if use_u:
|
288
|
+
right_name = "u"
|
289
|
+
else:
|
290
|
+
right_name = "u3"
|
291
|
+
if right_name in ("u1", "p") and right_name not in self.basis:
|
292
|
+
if use_u:
|
293
|
+
right_name = "u"
|
294
|
+
else:
|
295
|
+
right_name = "u3"
|
296
|
+
|
297
|
+
new_op = Gate(name="", num_qubits=1, params=[])
|
298
|
+
if right_name == "u1":
|
299
|
+
new_op = U1Gate(right_parameters[2])
|
300
|
+
if right_name == "p":
|
301
|
+
new_op = PhaseGate(right_parameters[2])
|
302
|
+
if right_name == "u2":
|
303
|
+
new_op = U2Gate(right_parameters[1], right_parameters[2])
|
304
|
+
if right_name == "u":
|
305
|
+
if "u" in self.basis:
|
306
|
+
new_op = UGate(*right_parameters)
|
307
|
+
if right_name == "u3":
|
308
|
+
if "u3" in self.basis:
|
309
|
+
new_op = U3Gate(*right_parameters)
|
310
|
+
else:
|
311
|
+
raise TranspilerError(f"It was not possible to use the basis {self.basis}")
|
312
|
+
|
313
|
+
dag.global_phase += right_global_phase
|
314
|
+
|
315
|
+
if right_name != "nop":
|
316
|
+
dag.substitute_node(run[0], new_op, inplace=True)
|
317
|
+
|
318
|
+
# Delete the other nodes in the run
|
319
|
+
for current_node in run[1:]:
|
320
|
+
dag.remove_op_node(current_node)
|
321
|
+
if right_name == "nop":
|
322
|
+
dag.remove_op_node(run[0])
|
323
|
+
|
324
|
+
return dag
|
325
|
+
|
326
|
+
@staticmethod
|
327
|
+
def compose_u3(theta1, phi1, lambda1, theta2, phi2, lambda2):
|
328
|
+
"""Return a triple theta, phi, lambda for the product.
|
329
|
+
|
330
|
+
u3(theta, phi, lambda)
|
331
|
+
= u3(theta1, phi1, lambda1).u3(theta2, phi2, lambda2)
|
332
|
+
= Rz(phi1).Ry(theta1).Rz(lambda1+phi2).Ry(theta2).Rz(lambda2)
|
333
|
+
= Rz(phi1).Rz(phi').Ry(theta').Rz(lambda').Rz(lambda2)
|
334
|
+
= u3(theta', phi1 + phi', lambda2 + lambda')
|
335
|
+
|
336
|
+
Return theta, phi, lambda.
|
337
|
+
"""
|
338
|
+
(theta, phi, lamb) = compose_u3_rust(theta1, phi1, lambda1, theta2, phi2, lambda2)
|
339
|
+
return (theta, phi, lamb)
|
340
|
+
|
341
|
+
@staticmethod
|
342
|
+
def yzy_to_zyz(xi, theta1, theta2, eps=1e-9): # pylint: disable=invalid-name
|
343
|
+
"""Express a Y.Z.Y single qubit gate as a Z.Y.Z gate.
|
344
|
+
|
345
|
+
Solve the equation
|
346
|
+
|
347
|
+
.. math::
|
348
|
+
|
349
|
+
Ry(theta1).Rz(xi).Ry(theta2) = Rz(phi).Ry(theta).Rz(lambda)
|
350
|
+
|
351
|
+
for theta, phi, and lambda.
|
352
|
+
|
353
|
+
Return a solution theta, phi, and lambda.
|
354
|
+
"""
|
355
|
+
quaternion_yzy = Quaternion.from_euler([theta1, xi, theta2], "yzy")
|
356
|
+
euler = quaternion_yzy.to_zyz()
|
357
|
+
quaternion_zyz = Quaternion.from_euler(euler, "zyz")
|
358
|
+
# output order different than rotation order
|
359
|
+
out_angles = (euler[1], euler[0], euler[2])
|
360
|
+
abs_inner = abs(quaternion_zyz.data.dot(quaternion_yzy.data))
|
361
|
+
if not np.allclose(abs_inner, 1, eps):
|
362
|
+
raise TranspilerError("YZY and ZYZ angles do not give same rotation matrix.")
|
363
|
+
out_angles = tuple(0 if np.abs(angle) < _CHOP_THRESHOLD else angle for angle in out_angles)
|
364
|
+
return out_angles
|
365
|
+
|
366
|
+
|
367
|
+
def _split_runs_on_parameters(runs):
|
368
|
+
"""Finds runs containing parameterized gates and splits them into sequential
|
369
|
+
runs excluding the parameterized gates.
|
370
|
+
"""
|
371
|
+
|
372
|
+
out = []
|
373
|
+
for run in runs:
|
374
|
+
# We exclude only u3 and u gate because for u1 and u2 we can really straightforward
|
375
|
+
# merge two gate with parameters.
|
376
|
+
# It would be great to combine all gate with parameters but this requires
|
377
|
+
# support parameters in qiskit.quantum_info.Quaternion.
|
378
|
+
groups = groupby(run, lambda x: x.op.is_parameterized() and x.op.name in ("u3", "u"))
|
379
|
+
|
380
|
+
for group_is_parameterized, gates in groups:
|
381
|
+
if not group_is_parameterized:
|
382
|
+
out.append(list(gates))
|
383
|
+
|
384
|
+
return out
|