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,313 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2021.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""A product formula base for decomposing non-commuting operator exponentials."""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import warnings
|
18
|
+
import itertools
|
19
|
+
from collections.abc import Callable, Sequence
|
20
|
+
from collections import defaultdict
|
21
|
+
from itertools import combinations
|
22
|
+
import typing
|
23
|
+
import numpy as np
|
24
|
+
import rustworkx as rx
|
25
|
+
from qiskit.circuit.parameterexpression import ParameterExpression
|
26
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit, ParameterValueType
|
27
|
+
from qiskit.quantum_info import SparsePauliOp, Pauli, SparseObservable
|
28
|
+
from qiskit._accelerate.circuit_library import pauli_evolution
|
29
|
+
|
30
|
+
from .evolution_synthesis import EvolutionSynthesis
|
31
|
+
|
32
|
+
if typing.TYPE_CHECKING:
|
33
|
+
from qiskit.circuit.library import PauliEvolutionGate
|
34
|
+
|
35
|
+
SparsePauliLabel = typing.Tuple[str, list[int], ParameterValueType]
|
36
|
+
|
37
|
+
|
38
|
+
class ProductFormula(EvolutionSynthesis):
|
39
|
+
"""Product formula base class for the decomposition of non-commuting operator exponentials.
|
40
|
+
|
41
|
+
:obj:`.LieTrotter` and :obj:`.SuzukiTrotter` inherit from this class.
|
42
|
+
"""
|
43
|
+
|
44
|
+
def __init__(
|
45
|
+
self,
|
46
|
+
order: int,
|
47
|
+
reps: int = 1,
|
48
|
+
insert_barriers: bool = False,
|
49
|
+
cx_structure: str = "chain",
|
50
|
+
atomic_evolution: (
|
51
|
+
Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | None
|
52
|
+
) = None,
|
53
|
+
wrap: bool = False,
|
54
|
+
preserve_order: bool = True,
|
55
|
+
*,
|
56
|
+
atomic_evolution_sparse_observable: bool = False,
|
57
|
+
) -> None:
|
58
|
+
r"""
|
59
|
+
Args:
|
60
|
+
order: The order of the product formula.
|
61
|
+
reps: The number of time steps.
|
62
|
+
insert_barriers: Whether to insert barriers between the atomic evolutions.
|
63
|
+
cx_structure: How to arrange the CX gates for the Pauli evolutions, can be
|
64
|
+
``"chain"``, where next neighbor connections are used, or ``"fountain"``,
|
65
|
+
where all qubits are connected to one. This only takes effect when
|
66
|
+
``atomic_evolution is None``.
|
67
|
+
atomic_evolution: A function to apply the evolution of a single :class:`.Pauli`, or
|
68
|
+
:class:`.SparsePauliOp` of only commuting terms, to a circuit. The function takes in
|
69
|
+
three arguments: the circuit to append the evolution to, the Pauli operator to
|
70
|
+
evolve, and the evolution time. By default, a single Pauli evolution is decomposed
|
71
|
+
into a chain of ``CX`` gates and a single ``RZ`` gate.
|
72
|
+
wrap: Whether to wrap the atomic evolutions into custom gate objects. Note that setting
|
73
|
+
this to ``True`` is slower than ``False``. This only takes effect when
|
74
|
+
``atomic_evolution is None``.
|
75
|
+
preserve_order: If ``False``, allows reordering the terms of the operator to
|
76
|
+
potentially yield a shallower evolution circuit. Not relevant
|
77
|
+
when synthesizing operator with a single term.
|
78
|
+
atomic_evolution_sparse_observable: If a custom ``atomic_evolution`` is passed,
|
79
|
+
which does not yet support :class:`.SparseObservable`\ s as input, set this
|
80
|
+
argument to ``False`` to automatically apply a conversion to :class:`.SparsePauliOp`.
|
81
|
+
This argument is supported until Qiskit 2.2, at which point all atomic evolutions
|
82
|
+
are required to support :class:`.SparseObservable`\ s as input.
|
83
|
+
"""
|
84
|
+
super().__init__()
|
85
|
+
self.order = order
|
86
|
+
self.reps = reps
|
87
|
+
self.insert_barriers = insert_barriers
|
88
|
+
self.preserve_order = preserve_order
|
89
|
+
|
90
|
+
# user-provided atomic evolution, stored for serialization
|
91
|
+
self._atomic_evolution = atomic_evolution
|
92
|
+
|
93
|
+
if cx_structure not in ["chain", "fountain"]:
|
94
|
+
raise ValueError(f"Unsupported CX structure: {cx_structure}")
|
95
|
+
|
96
|
+
self._cx_structure = cx_structure
|
97
|
+
self._wrap = wrap
|
98
|
+
|
99
|
+
# if atomic evolution is not provided, set a default
|
100
|
+
if atomic_evolution is None:
|
101
|
+
self.atomic_evolution = None
|
102
|
+
else:
|
103
|
+
self.atomic_evolution = wrap_custom_atomic_evolution(
|
104
|
+
atomic_evolution, atomic_evolution_sparse_observable
|
105
|
+
)
|
106
|
+
|
107
|
+
def expand(
|
108
|
+
self, evolution: PauliEvolutionGate
|
109
|
+
) -> list[tuple[str, tuple[int], ParameterValueType]]:
|
110
|
+
"""Apply the product formula to expand the Hamiltonian in the evolution gate.
|
111
|
+
|
112
|
+
Args:
|
113
|
+
evolution: The :class:`.PauliEvolutionGate`, whose Hamiltonian we expand.
|
114
|
+
|
115
|
+
Returns:
|
116
|
+
A list of Pauli rotations in a sparse format, where each element is
|
117
|
+
``(paulistring, qubits, coefficient)``. For example, the Lie-Trotter expansion
|
118
|
+
of ``H = XI + ZZ`` would return ``[("X", [1], 1), ("ZZ", [0, 1], 1)]``.
|
119
|
+
"""
|
120
|
+
raise NotImplementedError(
|
121
|
+
f"The method ``expand`` is not implemented for {self.__class__}. Implement it to "
|
122
|
+
f"automatically enable the call to {self.__class__}.synthesize."
|
123
|
+
)
|
124
|
+
|
125
|
+
def synthesize(self, evolution: PauliEvolutionGate) -> QuantumCircuit:
|
126
|
+
"""Synthesize a :class:`.PauliEvolutionGate`.
|
127
|
+
|
128
|
+
Args:
|
129
|
+
evolution: The evolution gate to synthesize.
|
130
|
+
|
131
|
+
Returns:
|
132
|
+
QuantumCircuit: A circuit implementing the evolution.
|
133
|
+
"""
|
134
|
+
pauli_rotations = self.expand(evolution)
|
135
|
+
num_qubits = evolution.num_qubits
|
136
|
+
|
137
|
+
if self._wrap or self._atomic_evolution is not None:
|
138
|
+
# this is the slow path, where each Pauli evolution is constructed in Rust
|
139
|
+
# separately and then wrapped into a gate object
|
140
|
+
circuit = self._custom_evolution(num_qubits, pauli_rotations)
|
141
|
+
else:
|
142
|
+
# this is the fast path, where the whole evolution is constructed Rust-side
|
143
|
+
cx_fountain = self._cx_structure == "fountain"
|
144
|
+
data = pauli_evolution(num_qubits, pauli_rotations, self.insert_barriers, cx_fountain)
|
145
|
+
circuit = QuantumCircuit._from_circuit_data(data, add_regs=True)
|
146
|
+
|
147
|
+
return circuit
|
148
|
+
|
149
|
+
@property
|
150
|
+
def settings(self) -> dict[str, typing.Any]:
|
151
|
+
"""Return the settings in a dictionary, which can be used to reconstruct the object.
|
152
|
+
|
153
|
+
Returns:
|
154
|
+
A dictionary containing the settings of this product formula.
|
155
|
+
|
156
|
+
Raises:
|
157
|
+
NotImplementedError: If a custom atomic evolution is set, which cannot be serialized.
|
158
|
+
"""
|
159
|
+
if self._atomic_evolution is not None:
|
160
|
+
raise NotImplementedError(
|
161
|
+
"Cannot serialize a product formula with a custom atomic evolution."
|
162
|
+
)
|
163
|
+
|
164
|
+
return {
|
165
|
+
"order": self.order,
|
166
|
+
"reps": self.reps,
|
167
|
+
"insert_barriers": self.insert_barriers,
|
168
|
+
"cx_structure": self._cx_structure,
|
169
|
+
"wrap": self._wrap,
|
170
|
+
"preserve_order": self.preserve_order,
|
171
|
+
}
|
172
|
+
|
173
|
+
def _custom_evolution(self, num_qubits, pauli_rotations):
|
174
|
+
"""Implement the evolution for the non-standard path.
|
175
|
+
|
176
|
+
This is either because a user-defined atomic evolution is given, or because the evolution
|
177
|
+
of individual Paulis needs to be wrapped in gates.
|
178
|
+
"""
|
179
|
+
circuit = QuantumCircuit(num_qubits)
|
180
|
+
cx_fountain = self._cx_structure == "fountain"
|
181
|
+
|
182
|
+
num_paulis = len(pauli_rotations)
|
183
|
+
for i, pauli_rotation in enumerate(pauli_rotations):
|
184
|
+
if self._atomic_evolution is not None:
|
185
|
+
# use the user-provided evolution with a global operator
|
186
|
+
operator = SparseObservable.from_sparse_list([pauli_rotation], num_qubits)
|
187
|
+
self.atomic_evolution(circuit, operator, time=1) # time is inside the Pauli coeff
|
188
|
+
|
189
|
+
else: # this means self._wrap is True
|
190
|
+
# we create a local sparse Pauli representation such that the operator
|
191
|
+
# does not span over all qubits of the circuit
|
192
|
+
pauli_string, qubits, coeff = pauli_rotation
|
193
|
+
local_pauli = (pauli_string, list(range(len(qubits))), coeff)
|
194
|
+
|
195
|
+
# build the circuit Rust-side
|
196
|
+
data = pauli_evolution(
|
197
|
+
len(qubits),
|
198
|
+
[local_pauli],
|
199
|
+
False,
|
200
|
+
cx_fountain,
|
201
|
+
)
|
202
|
+
evo = QuantumCircuit._from_circuit_data(data)
|
203
|
+
|
204
|
+
# and append it to the circuit with the correct label
|
205
|
+
gate = evo.to_gate(label=f"exp(it {pauli_string})")
|
206
|
+
circuit.append(gate, qubits)
|
207
|
+
|
208
|
+
if self.insert_barriers and i < num_paulis - 1:
|
209
|
+
circuit.barrier()
|
210
|
+
|
211
|
+
return circuit
|
212
|
+
|
213
|
+
|
214
|
+
def real_or_fail(value, tol=100):
|
215
|
+
"""Return real if close, otherwise fail. Unbound parameters are left unchanged.
|
216
|
+
|
217
|
+
Based on NumPy's ``real_if_close``, i.e. ``tol`` is in terms of machine precision for float.
|
218
|
+
"""
|
219
|
+
if isinstance(value, ParameterExpression):
|
220
|
+
return value
|
221
|
+
|
222
|
+
abstol = tol * np.finfo(float).eps
|
223
|
+
if abs(np.imag(value)) < abstol:
|
224
|
+
return np.real(value)
|
225
|
+
|
226
|
+
raise ValueError(f"Encountered complex value {value}, but expected real.")
|
227
|
+
|
228
|
+
|
229
|
+
def reorder_paulis(
|
230
|
+
paulis: Sequence[SparsePauliLabel],
|
231
|
+
strategy: rx.ColoringStrategy = rx.ColoringStrategy.Saturation,
|
232
|
+
) -> list[SparsePauliLabel]:
|
233
|
+
r"""
|
234
|
+
Creates an equivalent operator by reordering terms in order to yield a
|
235
|
+
shallower circuit after evolution synthesis. The original operator remains
|
236
|
+
unchanged.
|
237
|
+
|
238
|
+
This method works in three steps. First, a graph is constructed, where the
|
239
|
+
nodes are the terms of the operator and where two nodes are connected if
|
240
|
+
their terms act on the same qubit (for example, the terms :math:`IXX` and
|
241
|
+
:math:`IYI` would be connected, but not :math:`IXX` and :math:`YII`). Then,
|
242
|
+
the graph is colored. Two terms with the same color thus do not act on the
|
243
|
+
same qubit, and in particular, their evolution subcircuits can be run in
|
244
|
+
parallel in the greater evolution circuit of ``paulis``.
|
245
|
+
|
246
|
+
This method is deterministic and invariant under permutation of the Pauli
|
247
|
+
term in ``paulis``.
|
248
|
+
|
249
|
+
Args:
|
250
|
+
paulis: The operator whose terms to reorder.
|
251
|
+
strategy: The coloring heuristic to use, see ``ColoringStrategy`` [#].
|
252
|
+
Default is ``ColoringStrategy.Saturation``.
|
253
|
+
|
254
|
+
.. [#] https://www.rustworkx.org/apiref/rustworkx.ColoringStrategy.html#coloringstrategy
|
255
|
+
|
256
|
+
"""
|
257
|
+
|
258
|
+
def _term_sort_key(term: SparsePauliLabel) -> typing.Any:
|
259
|
+
# sort by index, then by pauli
|
260
|
+
return (term[1], term[0])
|
261
|
+
|
262
|
+
# Do nothing in trivial cases
|
263
|
+
if len(paulis) <= 1:
|
264
|
+
return paulis
|
265
|
+
|
266
|
+
terms = sorted(paulis, key=_term_sort_key)
|
267
|
+
graph = rx.PyGraph()
|
268
|
+
graph.add_nodes_from(terms)
|
269
|
+
indexed_nodes = list(enumerate(graph.nodes()))
|
270
|
+
for (idx1, (_, ind1, _)), (idx2, (_, ind2, _)) in combinations(indexed_nodes, 2):
|
271
|
+
# Add an edge between two terms if they touch the same qubit
|
272
|
+
if len(set(ind1).intersection(ind2)) > 0:
|
273
|
+
graph.add_edge(idx1, idx2, None)
|
274
|
+
|
275
|
+
# rx.graph_greedy_color is supposed to be deterministic
|
276
|
+
coloring = rx.graph_greedy_color(graph, strategy=strategy)
|
277
|
+
terms_by_color = defaultdict(list)
|
278
|
+
|
279
|
+
for term_idx, color in sorted(coloring.items()):
|
280
|
+
term = graph.nodes()[term_idx]
|
281
|
+
terms_by_color[color].append(term)
|
282
|
+
|
283
|
+
terms = list(itertools.chain(*terms_by_color.values()))
|
284
|
+
return terms
|
285
|
+
|
286
|
+
|
287
|
+
def wrap_custom_atomic_evolution(atomic_evolution, support_sparse_observable):
|
288
|
+
r"""Wrap a custom atomic evolution into compatible format for the product formula.
|
289
|
+
|
290
|
+
This includes an inplace action, i.e. the signature is (circuit, operator, time) and
|
291
|
+
ensuring that ``SparseObservable``\ s are supported.
|
292
|
+
"""
|
293
|
+
# next, enable backward compatible use of atomic evolutions, that did not support
|
294
|
+
# SparseObservable inputs
|
295
|
+
if support_sparse_observable is False:
|
296
|
+
warnings.warn(
|
297
|
+
"The atomic_evolution should support SparseObservables as operator input. "
|
298
|
+
"Until Qiskit 2.2, an automatic conversion to SparsePauliOp is done, which can "
|
299
|
+
"be turned off by passing the argument atomic_evolution_sparse_observable=True.",
|
300
|
+
category=PendingDeprecationWarning,
|
301
|
+
stacklevel=2,
|
302
|
+
)
|
303
|
+
|
304
|
+
def sparseobs_atomic_evolution(output, operator, time):
|
305
|
+
if isinstance(operator, SparseObservable):
|
306
|
+
operator = SparsePauliOp.from_sparse_observable(operator)
|
307
|
+
|
308
|
+
atomic_evolution(output, operator, time)
|
309
|
+
|
310
|
+
else:
|
311
|
+
sparseobs_atomic_evolution = atomic_evolution
|
312
|
+
|
313
|
+
return sparseobs_atomic_evolution
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2021.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""QDrift Class"""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import math
|
18
|
+
import typing
|
19
|
+
from itertools import chain
|
20
|
+
from collections.abc import Callable
|
21
|
+
import numpy as np
|
22
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
23
|
+
from qiskit.quantum_info.operators import SparsePauliOp, Pauli
|
24
|
+
from qiskit.exceptions import QiskitError
|
25
|
+
|
26
|
+
from .product_formula import ProductFormula, reorder_paulis
|
27
|
+
|
28
|
+
if typing.TYPE_CHECKING:
|
29
|
+
from qiskit.circuit.library import PauliEvolutionGate
|
30
|
+
|
31
|
+
|
32
|
+
class QDrift(ProductFormula):
|
33
|
+
r"""The QDrift Trotterization method, which selects each term in the
|
34
|
+
Trotterization randomly, with a probability proportional to its weight. Based on the work
|
35
|
+
of Earl Campbell in Ref. [1].
|
36
|
+
|
37
|
+
References:
|
38
|
+
[1]: E. Campbell, "A random compiler for fast Hamiltonian simulation" (2018).
|
39
|
+
`arXiv:quant-ph/1811.08017 <https://arxiv.org/abs/1811.08017>`_
|
40
|
+
"""
|
41
|
+
|
42
|
+
def __init__(
|
43
|
+
self,
|
44
|
+
reps: int = 1,
|
45
|
+
insert_barriers: bool = False,
|
46
|
+
cx_structure: str = "chain",
|
47
|
+
atomic_evolution: (
|
48
|
+
Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | None
|
49
|
+
) = None,
|
50
|
+
seed: int | None = None,
|
51
|
+
wrap: bool = False,
|
52
|
+
preserve_order: bool = True,
|
53
|
+
*,
|
54
|
+
atomic_evolution_sparse_observable: bool = False,
|
55
|
+
) -> None:
|
56
|
+
r"""
|
57
|
+
Args:
|
58
|
+
reps: The number of times to repeat the Trotterization circuit.
|
59
|
+
insert_barriers: Whether to insert barriers between the atomic evolutions.
|
60
|
+
cx_structure: How to arrange the CX gates for the Pauli evolutions, can be
|
61
|
+
``"chain"``, where next neighbor connections are used, or ``"fountain"``, where all
|
62
|
+
qubits are connected to one. This only takes effect when
|
63
|
+
``atomic_evolution is None``.
|
64
|
+
atomic_evolution: A function to apply the evolution of a single :class:`.Pauli`, or
|
65
|
+
:class:`.SparsePauliOp` of only commuting terms, to a circuit. The function takes in
|
66
|
+
three arguments: the circuit to append the evolution to, the Pauli operator to
|
67
|
+
evolve, and the evolution time. By default, a single Pauli evolution is decomposed
|
68
|
+
into a chain of ``CX`` gates and a single ``RZ`` gate.
|
69
|
+
seed: An optional seed for reproducibility of the random sampling process.
|
70
|
+
wrap: Whether to wrap the atomic evolutions into custom gate objects. This only takes
|
71
|
+
effect when ``atomic_evolution is None``.
|
72
|
+
preserve_order: If ``False``, allows reordering the terms of the operator to
|
73
|
+
potentially yield a shallower evolution circuit. Not relevant
|
74
|
+
when synthesizing operator with a single term.
|
75
|
+
atomic_evolution_sparse_observable: If a custom ``atomic_evolution`` is passed,
|
76
|
+
which does not yet support :class:`.SparseObservable`\ s as input, set this
|
77
|
+
argument to ``False`` to automatically apply a conversion to :class:`.SparsePauliOp`.
|
78
|
+
This argument is supported until Qiskit 2.2, at which point all atomic evolutions
|
79
|
+
are required to support :class:`.SparseObservable`\ s as input.
|
80
|
+
"""
|
81
|
+
super().__init__(
|
82
|
+
1,
|
83
|
+
reps,
|
84
|
+
insert_barriers,
|
85
|
+
cx_structure,
|
86
|
+
atomic_evolution,
|
87
|
+
wrap,
|
88
|
+
preserve_order,
|
89
|
+
atomic_evolution_sparse_observable=atomic_evolution_sparse_observable,
|
90
|
+
)
|
91
|
+
self.sampled_ops = None
|
92
|
+
self.rng = np.random.default_rng(seed)
|
93
|
+
|
94
|
+
def expand(self, evolution: PauliEvolutionGate) -> list[tuple[str, tuple[int], float]]:
|
95
|
+
operators = evolution.operator
|
96
|
+
time = evolution.time # used to determine the number of gates
|
97
|
+
|
98
|
+
# QDrift is based on first-order Lie-Trotter, hence we can just concatenate all
|
99
|
+
# Pauli terms and ignore commutations
|
100
|
+
if isinstance(operators, list):
|
101
|
+
paulis = list(chain.from_iterable([op.to_sparse_list() for op in operators]))
|
102
|
+
else:
|
103
|
+
paulis = operators.to_sparse_list()
|
104
|
+
|
105
|
+
try:
|
106
|
+
coeffs = [float(np.real_if_close(coeff)) for _, _, coeff in paulis]
|
107
|
+
except TypeError as exc:
|
108
|
+
raise QiskitError("QDrift requires bound, real coefficients.") from exc
|
109
|
+
|
110
|
+
# We artificially make the weights positive
|
111
|
+
weights = np.abs(coeffs)
|
112
|
+
lambd = np.sum(weights)
|
113
|
+
|
114
|
+
num_gates = math.ceil(2 * (lambd**2) * (time**2) * self.reps)
|
115
|
+
|
116
|
+
# The protocol calls for the removal of the individual coefficients,
|
117
|
+
# and multiplication by a constant evolution time.
|
118
|
+
sampled = self.rng.choice(
|
119
|
+
np.array(paulis, dtype=object), size=(num_gates,), p=weights / lambd
|
120
|
+
)
|
121
|
+
|
122
|
+
rescaled_time = 2 * lambd / num_gates * time
|
123
|
+
sampled_paulis = [
|
124
|
+
(pauli[0], pauli[1], np.real(np.sign(pauli[2])) * rescaled_time) for pauli in sampled
|
125
|
+
]
|
126
|
+
|
127
|
+
if not self.preserve_order:
|
128
|
+
sampled_paulis = reorder_paulis(sampled_paulis)
|
129
|
+
|
130
|
+
return sampled_paulis
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2021.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""The Suzuki-Trotter product formula."""
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import typing
|
18
|
+
from collections.abc import Callable
|
19
|
+
from itertools import chain
|
20
|
+
import numpy as np
|
21
|
+
|
22
|
+
from qiskit.circuit.parameterexpression import ParameterExpression
|
23
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
24
|
+
from qiskit.quantum_info import SparsePauliOp, Pauli
|
25
|
+
|
26
|
+
from .product_formula import ProductFormula, reorder_paulis
|
27
|
+
|
28
|
+
if typing.TYPE_CHECKING:
|
29
|
+
from qiskit.circuit.quantumcircuit import ParameterValueType
|
30
|
+
from qiskit.circuit.library.pauli_evolution import PauliEvolutionGate
|
31
|
+
|
32
|
+
|
33
|
+
class SuzukiTrotter(ProductFormula):
|
34
|
+
r"""The (higher order) Suzuki-Trotter product formula.
|
35
|
+
|
36
|
+
The Suzuki-Trotter formulas improve the error of the Lie-Trotter approximation.
|
37
|
+
For example, the second order decomposition is
|
38
|
+
|
39
|
+
.. math::
|
40
|
+
|
41
|
+
e^{A + B} \approx e^{B/2} e^{A} e^{B/2}.
|
42
|
+
|
43
|
+
Higher order decompositions are based on recursions, see Ref. [1] for more details.
|
44
|
+
|
45
|
+
In this implementation, the operators are provided as sum terms of a Pauli operator.
|
46
|
+
For example, in the second order Suzuki-Trotter decomposition we approximate
|
47
|
+
|
48
|
+
.. math::
|
49
|
+
|
50
|
+
e^{-it(XI + ZZ)} = e^{-it/2 XI}e^{-it ZZ}e^{-it/2 XI} + \mathcal{O}(t^3).
|
51
|
+
|
52
|
+
References:
|
53
|
+
[1]: D. Berry, G. Ahokas, R. Cleve and B. Sanders,
|
54
|
+
"Efficient quantum algorithms for simulating sparse Hamiltonians" (2006).
|
55
|
+
`arXiv:quant-ph/0508139 <https://arxiv.org/abs/quant-ph/0508139>`_
|
56
|
+
[2]: N. Hatano and M. Suzuki,
|
57
|
+
"Finding Exponential Product Formulas of Higher Orders" (2005).
|
58
|
+
`arXiv:math-ph/0506007 <https://arxiv.org/pdf/math-ph/0506007.pdf>`_
|
59
|
+
"""
|
60
|
+
|
61
|
+
def __init__(
|
62
|
+
self,
|
63
|
+
order: int = 2,
|
64
|
+
reps: int = 1,
|
65
|
+
insert_barriers: bool = False,
|
66
|
+
cx_structure: str = "chain",
|
67
|
+
atomic_evolution: (
|
68
|
+
Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None] | None
|
69
|
+
) = None,
|
70
|
+
wrap: bool = False,
|
71
|
+
preserve_order: bool = True,
|
72
|
+
*,
|
73
|
+
atomic_evolution_sparse_observable: bool = False,
|
74
|
+
) -> None:
|
75
|
+
r"""
|
76
|
+
Args:
|
77
|
+
order: The order of the product formula.
|
78
|
+
reps: The number of time steps.
|
79
|
+
insert_barriers: Whether to insert barriers between the atomic evolutions.
|
80
|
+
cx_structure: How to arrange the CX gates for the Pauli evolutions, can be ``"chain"``,
|
81
|
+
where next neighbor connections are used, or ``"fountain"``, where all qubits are
|
82
|
+
connected to one. This only takes effect when ``atomic_evolution is None``.
|
83
|
+
atomic_evolution: A function to apply the evolution of a single :class:`.Pauli`, or
|
84
|
+
:class:`.SparsePauliOp` of only commuting terms, to a circuit. The function takes in
|
85
|
+
three arguments: the circuit to append the evolution to, the Pauli operator to
|
86
|
+
evolve, and the evolution time. By default, a single Pauli evolution is decomposed
|
87
|
+
into a chain of ``CX`` gates and a single ``RZ`` gate.
|
88
|
+
wrap: Whether to wrap the atomic evolutions into custom gate objects. This only takes
|
89
|
+
effect when ``atomic_evolution is None``.
|
90
|
+
preserve_order: If ``False``, allows reordering the terms of the operator to
|
91
|
+
potentially yield a shallower evolution circuit. Not relevant
|
92
|
+
when synthesizing operator with a single term.
|
93
|
+
atomic_evolution_sparse_observable: If a custom ``atomic_evolution`` is passed,
|
94
|
+
which does not yet support :class:`.SparseObservable`\ s as input, set this
|
95
|
+
argument to ``False`` to automatically apply a conversion to :class:`.SparsePauliOp`.
|
96
|
+
This argument is supported until Qiskit 2.2, at which point all atomic evolutions
|
97
|
+
are required to support :class:`.SparseObservable`\ s as input.
|
98
|
+
|
99
|
+
Raises:
|
100
|
+
ValueError: If order is not even
|
101
|
+
"""
|
102
|
+
if order > 1 and order % 2 == 1:
|
103
|
+
raise ValueError(
|
104
|
+
"Suzuki product formulae are symmetric and therefore only defined "
|
105
|
+
f"for when the order is 1 or even, not {order}."
|
106
|
+
)
|
107
|
+
|
108
|
+
super().__init__(
|
109
|
+
order,
|
110
|
+
reps,
|
111
|
+
insert_barriers,
|
112
|
+
cx_structure,
|
113
|
+
atomic_evolution,
|
114
|
+
wrap,
|
115
|
+
preserve_order=preserve_order,
|
116
|
+
atomic_evolution_sparse_observable=atomic_evolution_sparse_observable,
|
117
|
+
)
|
118
|
+
|
119
|
+
def expand(
|
120
|
+
self, evolution: PauliEvolutionGate
|
121
|
+
) -> list[tuple[str, list[int], ParameterValueType]]:
|
122
|
+
"""Expand the Hamiltonian into a Suzuki-Trotter sequence of sparse gates.
|
123
|
+
|
124
|
+
For example, the Hamiltonian ``H = IX + ZZ`` for an evolution time ``t`` and
|
125
|
+
1 repetition for an order 2 formula would get decomposed into a list of 3-tuples
|
126
|
+
containing ``(pauli, indices, rz_rotation_angle)``, that is:
|
127
|
+
|
128
|
+
.. code-block:: text
|
129
|
+
|
130
|
+
("X", [0], t), ("ZZ", [0, 1], 2t), ("X", [0], t)
|
131
|
+
|
132
|
+
Note that the rotation angle contains a factor of 2, such that that evolution
|
133
|
+
of a Pauli :math:`P` over time :math:`t`, which is :math:`e^{itP}`, is represented
|
134
|
+
by ``(P, indices, 2 * t)``.
|
135
|
+
|
136
|
+
For ``N`` repetitions, this sequence would be repeated ``N`` times and the coefficients
|
137
|
+
divided by ``N``.
|
138
|
+
|
139
|
+
Args:
|
140
|
+
evolution: The evolution gate to expand.
|
141
|
+
|
142
|
+
Returns:
|
143
|
+
The Pauli network implementing the Trotter expansion.
|
144
|
+
"""
|
145
|
+
operators = evolution.operator
|
146
|
+
time = evolution.time
|
147
|
+
|
148
|
+
def to_sparse_list(operator):
|
149
|
+
sparse_list = (
|
150
|
+
operator.to_sparse_list()
|
151
|
+
if isinstance(operator, SparsePauliOp)
|
152
|
+
else operator.to_sparse_list()
|
153
|
+
)
|
154
|
+
paulis = [
|
155
|
+
(pauli, indices, real_or_fail(coeff) * time * 2 / self.reps)
|
156
|
+
for pauli, indices, coeff in sparse_list
|
157
|
+
]
|
158
|
+
if not self.preserve_order:
|
159
|
+
return reorder_paulis(paulis)
|
160
|
+
|
161
|
+
return paulis
|
162
|
+
|
163
|
+
# construct the evolution circuit
|
164
|
+
if isinstance(operators, list): # already sorted into commuting bits
|
165
|
+
non_commuting = [to_sparse_list(operator) for operator in operators]
|
166
|
+
else:
|
167
|
+
# Assume no commutativity here. If we were to group commuting Paulis,
|
168
|
+
# here would be the location to do so.
|
169
|
+
non_commuting = [[op] for op in to_sparse_list(operators)]
|
170
|
+
|
171
|
+
# we're already done here since Lie Trotter does not do any operator repetition
|
172
|
+
product_formula = self._recurse(self.order, non_commuting)
|
173
|
+
flattened = self.reps * list(chain.from_iterable(product_formula))
|
174
|
+
|
175
|
+
return flattened
|
176
|
+
|
177
|
+
@staticmethod
|
178
|
+
def _recurse(order, grouped_paulis):
|
179
|
+
if order == 1:
|
180
|
+
return grouped_paulis
|
181
|
+
|
182
|
+
elif order == 2:
|
183
|
+
halves = [
|
184
|
+
[(label, qubits, coeff / 2) for label, qubits, coeff in paulis]
|
185
|
+
for paulis in grouped_paulis[:-1]
|
186
|
+
]
|
187
|
+
full = [grouped_paulis[-1]]
|
188
|
+
return halves + full + list(reversed(halves))
|
189
|
+
|
190
|
+
else:
|
191
|
+
reduction = 1 / (4 - 4 ** (1 / (order - 1)))
|
192
|
+
outer = 2 * SuzukiTrotter._recurse(
|
193
|
+
order - 2,
|
194
|
+
[
|
195
|
+
[(label, qubits, coeff * reduction) for label, qubits, coeff in paulis]
|
196
|
+
for paulis in grouped_paulis
|
197
|
+
],
|
198
|
+
)
|
199
|
+
inner = SuzukiTrotter._recurse(
|
200
|
+
order - 2,
|
201
|
+
[
|
202
|
+
[
|
203
|
+
(label, qubits, coeff * (1 - 4 * reduction))
|
204
|
+
for label, qubits, coeff in paulis
|
205
|
+
]
|
206
|
+
for paulis in grouped_paulis
|
207
|
+
],
|
208
|
+
)
|
209
|
+
return outer + inner + outer
|
210
|
+
|
211
|
+
|
212
|
+
def real_or_fail(value, tol=100):
|
213
|
+
"""Return real if close, otherwise fail. Unbound parameters are left unchanged.
|
214
|
+
|
215
|
+
Based on NumPy's ``real_if_close``, i.e. ``tol`` is in terms of machine precision for float.
|
216
|
+
"""
|
217
|
+
if isinstance(value, ParameterExpression):
|
218
|
+
return value
|
219
|
+
|
220
|
+
abstol = tol * np.finfo(float).eps
|
221
|
+
if abs(np.imag(value)) < abstol:
|
222
|
+
return np.real(value)
|
223
|
+
|
224
|
+
raise ValueError(f"Encountered complex value {value}, but expected real.")
|
@@ -0,0 +1,26 @@
|
|
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
|
+
"""Module containing cnot circuits"""
|
14
|
+
|
15
|
+
from .cnot_synth import synth_cnot_count_full_pmh
|
16
|
+
from .linear_depth_lnn import synth_cnot_depth_line_kms
|
17
|
+
from .linear_matrix_utils import (
|
18
|
+
random_invertible_binary_matrix,
|
19
|
+
calc_inverse_matrix,
|
20
|
+
check_invertible_binary_matrix,
|
21
|
+
binary_matmul,
|
22
|
+
)
|
23
|
+
|
24
|
+
# This is re-import is kept for compatibility with Terra 0.23. Eligible for deprecation in 0.25+.
|
25
|
+
# pylint: disable=cyclic-import,wrong-import-order
|
26
|
+
from qiskit.synthesis.linear_phase import synth_cnot_phase_aam as graysynth
|