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,805 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 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
|
+
"""
|
14
|
+
Stabilizer state class.
|
15
|
+
"""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
from collections.abc import Collection
|
20
|
+
from typing import TYPE_CHECKING
|
21
|
+
|
22
|
+
import numpy as np
|
23
|
+
|
24
|
+
from qiskit.exceptions import QiskitError
|
25
|
+
from qiskit.quantum_info.operators.op_shape import OpShape
|
26
|
+
from qiskit.quantum_info.operators.operator import Operator
|
27
|
+
from qiskit.quantum_info.operators.symplectic import Clifford, Pauli, PauliList, SparsePauliOp
|
28
|
+
from qiskit.quantum_info.operators.symplectic.clifford_circuits import _append_x
|
29
|
+
from qiskit.quantum_info.states.quantum_state import QuantumState
|
30
|
+
from qiskit.circuit import QuantumCircuit, Instruction
|
31
|
+
|
32
|
+
if TYPE_CHECKING:
|
33
|
+
from qiskit import circuit
|
34
|
+
|
35
|
+
|
36
|
+
class StabilizerState(QuantumState):
|
37
|
+
"""StabilizerState class.
|
38
|
+
Stabilizer simulator using the convention from reference [1].
|
39
|
+
Based on the internal class :class:`~qiskit.quantum_info.Clifford`.
|
40
|
+
|
41
|
+
.. plot::
|
42
|
+
:include-source:
|
43
|
+
:nofigs:
|
44
|
+
|
45
|
+
from qiskit import QuantumCircuit
|
46
|
+
from qiskit.quantum_info import StabilizerState, Pauli
|
47
|
+
|
48
|
+
# Bell state generation circuit
|
49
|
+
qc = QuantumCircuit(2)
|
50
|
+
qc.h(0)
|
51
|
+
qc.cx(0, 1)
|
52
|
+
stab = StabilizerState(qc)
|
53
|
+
|
54
|
+
# Print the StabilizerState
|
55
|
+
print(stab)
|
56
|
+
|
57
|
+
# Calculate the StabilizerState measurement probabilities dictionary
|
58
|
+
print (stab.probabilities_dict())
|
59
|
+
|
60
|
+
# Calculate expectation value of the StabilizerState
|
61
|
+
print (stab.expectation_value(Pauli('ZZ')))
|
62
|
+
|
63
|
+
.. code-block:: text
|
64
|
+
|
65
|
+
StabilizerState(StabilizerTable: ['+XX', '+ZZ'])
|
66
|
+
{'00': 0.5, '11': 0.5}
|
67
|
+
1
|
68
|
+
|
69
|
+
Given a list of stabilizers, :meth:`qiskit.quantum_info.StabilizerState.from_stabilizer_list`
|
70
|
+
returns a state stabilized by the list
|
71
|
+
|
72
|
+
.. plot::
|
73
|
+
:include-source:
|
74
|
+
:nofigs:
|
75
|
+
|
76
|
+
from qiskit.quantum_info import StabilizerState
|
77
|
+
|
78
|
+
stabilizer_list = ["ZXX", "-XYX", "+ZYY"]
|
79
|
+
stab = StabilizerState.from_stabilizer_list(stabilizer_list)
|
80
|
+
|
81
|
+
|
82
|
+
References:
|
83
|
+
1. S. Aaronson, D. Gottesman, *Improved Simulation of Stabilizer Circuits*,
|
84
|
+
Phys. Rev. A 70, 052328 (2004).
|
85
|
+
`arXiv:quant-ph/0406196 <https://arxiv.org/abs/quant-ph/0406196>`_
|
86
|
+
"""
|
87
|
+
|
88
|
+
def __init__(
|
89
|
+
self,
|
90
|
+
data: StabilizerState | Clifford | Pauli | QuantumCircuit | circuit.instruction.Instruction,
|
91
|
+
validate: bool = True,
|
92
|
+
):
|
93
|
+
"""Initialize a StabilizerState object.
|
94
|
+
|
95
|
+
Args:
|
96
|
+
data: Data from which the stabilizer state can be constructed.
|
97
|
+
validate: validate that the stabilizer state data is a valid Clifford.
|
98
|
+
"""
|
99
|
+
|
100
|
+
# Initialize from another StabilizerState
|
101
|
+
if isinstance(data, StabilizerState):
|
102
|
+
self._data = data._data
|
103
|
+
# Initialize from a Pauli
|
104
|
+
elif isinstance(data, Pauli):
|
105
|
+
self._data = Clifford(data.to_instruction())
|
106
|
+
# Initialize from a Clifford, QuantumCircuit or Instruction
|
107
|
+
else:
|
108
|
+
self._data = Clifford(data, validate)
|
109
|
+
|
110
|
+
# Initialize
|
111
|
+
super().__init__(op_shape=OpShape.auto(num_qubits_r=self._data.num_qubits, num_qubits_l=0))
|
112
|
+
|
113
|
+
@classmethod
|
114
|
+
def from_stabilizer_list(
|
115
|
+
cls,
|
116
|
+
stabilizers: Collection[str],
|
117
|
+
allow_redundant: bool = False,
|
118
|
+
allow_underconstrained: bool = False,
|
119
|
+
) -> StabilizerState:
|
120
|
+
"""Create a stabilizer state from the collection of stabilizers.
|
121
|
+
|
122
|
+
Args:
|
123
|
+
stabilizers (Collection[str]): list of stabilizer strings
|
124
|
+
allow_redundant (bool): allow redundant stabilizers (i.e., some stabilizers
|
125
|
+
can be products of the others)
|
126
|
+
allow_underconstrained (bool): allow underconstrained set of stabilizers (i.e.,
|
127
|
+
the stabilizers do not specify a unique state)
|
128
|
+
|
129
|
+
Return:
|
130
|
+
StabilizerState: a state stabilized by stabilizers.
|
131
|
+
"""
|
132
|
+
|
133
|
+
# pylint: disable=cyclic-import
|
134
|
+
from qiskit.synthesis.stabilizer import synth_circuit_from_stabilizers
|
135
|
+
|
136
|
+
circuit = synth_circuit_from_stabilizers(
|
137
|
+
stabilizers,
|
138
|
+
allow_redundant=allow_redundant,
|
139
|
+
allow_underconstrained=allow_underconstrained,
|
140
|
+
)
|
141
|
+
return cls(circuit)
|
142
|
+
|
143
|
+
def __eq__(self, other):
|
144
|
+
return (self._data.stab == other._data.stab).all()
|
145
|
+
|
146
|
+
def __repr__(self):
|
147
|
+
return f"StabilizerState({self._data.to_labels(mode='S')})"
|
148
|
+
|
149
|
+
@property
|
150
|
+
def clifford(self):
|
151
|
+
"""Return StabilizerState Clifford data"""
|
152
|
+
return self._data
|
153
|
+
|
154
|
+
def is_valid(self, atol=None, rtol=None):
|
155
|
+
"""Return True if a valid StabilizerState."""
|
156
|
+
return self._data.is_unitary()
|
157
|
+
|
158
|
+
def _add(self, other):
|
159
|
+
raise NotImplementedError(f"{type(self)} does not support addition")
|
160
|
+
|
161
|
+
def _multiply(self, other):
|
162
|
+
raise NotImplementedError(f"{type(self)} does not support scalar multiplication")
|
163
|
+
|
164
|
+
def trace(self) -> float:
|
165
|
+
"""Return the trace of the stabilizer state as a density matrix,
|
166
|
+
which equals to 1, since it is always a pure state.
|
167
|
+
|
168
|
+
Returns:
|
169
|
+
float: the trace (should equal 1).
|
170
|
+
|
171
|
+
Raises:
|
172
|
+
QiskitError: if input is not a StabilizerState.
|
173
|
+
"""
|
174
|
+
if not self.is_valid():
|
175
|
+
raise QiskitError("StabilizerState is not a valid quantum state.")
|
176
|
+
return 1.0
|
177
|
+
|
178
|
+
def purity(self) -> float:
|
179
|
+
"""Return the purity of the quantum state,
|
180
|
+
which equals to 1, since it is always a pure state.
|
181
|
+
|
182
|
+
Returns:
|
183
|
+
float: the purity (should equal 1).
|
184
|
+
|
185
|
+
Raises:
|
186
|
+
QiskitError: if input is not a StabilizerState.
|
187
|
+
"""
|
188
|
+
if not self.is_valid():
|
189
|
+
raise QiskitError("StabilizerState is not a valid quantum state.")
|
190
|
+
return 1.0
|
191
|
+
|
192
|
+
def to_operator(self) -> Operator:
|
193
|
+
"""Convert state to matrix operator class"""
|
194
|
+
return Clifford(self.clifford).to_operator()
|
195
|
+
|
196
|
+
def conjugate(self):
|
197
|
+
"""Return the conjugate of the operator."""
|
198
|
+
ret = self.copy()
|
199
|
+
ret._data = ret._data.conjugate()
|
200
|
+
return ret
|
201
|
+
|
202
|
+
def tensor(self, other: StabilizerState) -> StabilizerState:
|
203
|
+
"""Return the tensor product stabilizer state self ⊗ other.
|
204
|
+
|
205
|
+
Args:
|
206
|
+
other (StabilizerState): a stabilizer state object.
|
207
|
+
|
208
|
+
Returns:
|
209
|
+
StabilizerState: the tensor product operator self ⊗ other.
|
210
|
+
|
211
|
+
Raises:
|
212
|
+
QiskitError: if other is not a StabilizerState.
|
213
|
+
"""
|
214
|
+
if not isinstance(other, StabilizerState):
|
215
|
+
other = StabilizerState(other)
|
216
|
+
ret = self.copy()
|
217
|
+
ret._data = self.clifford.tensor(other.clifford)
|
218
|
+
return ret
|
219
|
+
|
220
|
+
def expand(self, other: StabilizerState) -> StabilizerState:
|
221
|
+
"""Return the tensor product stabilizer state other ⊗ self.
|
222
|
+
|
223
|
+
Args:
|
224
|
+
other (StabilizerState): a stabilizer state object.
|
225
|
+
|
226
|
+
Returns:
|
227
|
+
StabilizerState: the tensor product operator other ⊗ self.
|
228
|
+
|
229
|
+
Raises:
|
230
|
+
QiskitError: if other is not a StabilizerState.
|
231
|
+
"""
|
232
|
+
if not isinstance(other, StabilizerState):
|
233
|
+
other = StabilizerState(other)
|
234
|
+
ret = self.copy()
|
235
|
+
ret._data = self.clifford.expand(other.clifford)
|
236
|
+
return ret
|
237
|
+
|
238
|
+
def evolve(
|
239
|
+
self, other: Clifford | QuantumCircuit | Instruction, qargs: list | None = None
|
240
|
+
) -> StabilizerState:
|
241
|
+
"""Evolve a stabilizer state by a Clifford operator.
|
242
|
+
|
243
|
+
Args:
|
244
|
+
other (Clifford or QuantumCircuit or qiskit.circuit.Instruction):
|
245
|
+
The Clifford operator to evolve by.
|
246
|
+
qargs (list): a list of stabilizer subsystem positions to apply the operator on.
|
247
|
+
|
248
|
+
Returns:
|
249
|
+
StabilizerState: the output stabilizer state.
|
250
|
+
|
251
|
+
Raises:
|
252
|
+
QiskitError: if other is not a StabilizerState.
|
253
|
+
QiskitError: if the operator dimension does not match the
|
254
|
+
specified StabilizerState subsystem dimensions.
|
255
|
+
"""
|
256
|
+
if not isinstance(other, StabilizerState):
|
257
|
+
other = StabilizerState(other)
|
258
|
+
ret = self.copy()
|
259
|
+
ret._data = self.clifford.compose(other.clifford, qargs=qargs)
|
260
|
+
return ret
|
261
|
+
|
262
|
+
def expectation_value(self, oper: Pauli | SparsePauliOp, qargs: None | list = None) -> complex:
|
263
|
+
"""Compute the expectation value of a Pauli or SparsePauliOp operator.
|
264
|
+
|
265
|
+
Args:
|
266
|
+
oper: A Pauli or SparsePauliOp operator to evaluate the expectation value.
|
267
|
+
qargs: Subsystems to apply the operator on.
|
268
|
+
|
269
|
+
Returns:
|
270
|
+
The expectation value.
|
271
|
+
|
272
|
+
Raises:
|
273
|
+
QiskitError: if oper is not a Pauli or SparsePauliOp operator.
|
274
|
+
"""
|
275
|
+
if isinstance(oper, Pauli):
|
276
|
+
return self._expectation_value_pauli(oper, qargs)
|
277
|
+
|
278
|
+
if isinstance(oper, SparsePauliOp):
|
279
|
+
return sum(
|
280
|
+
coeff * self._expectation_value_pauli(Pauli((z, x)), qargs)
|
281
|
+
for z, x, coeff in zip(oper.paulis.z, oper.paulis.x, oper.coeffs)
|
282
|
+
)
|
283
|
+
|
284
|
+
raise QiskitError(
|
285
|
+
"Operator for expectation value is not a Pauli or SparsePauliOp operator, "
|
286
|
+
f"but {type(oper)}."
|
287
|
+
)
|
288
|
+
|
289
|
+
def _expectation_value_pauli(self, oper: Pauli, qargs: None | list = None) -> complex:
|
290
|
+
"""Compute the expectation value of a Pauli operator.
|
291
|
+
|
292
|
+
Args:
|
293
|
+
oper (Pauli): a Pauli operator to evaluate expval.
|
294
|
+
qargs (None or list): subsystems to apply the operator on.
|
295
|
+
|
296
|
+
Returns:
|
297
|
+
complex: the expectation value (only 0 or 1 or -1 or i or -i).
|
298
|
+
|
299
|
+
Raises:
|
300
|
+
QiskitError: if oper is not a Pauli operator.
|
301
|
+
"""
|
302
|
+
if not isinstance(oper, Pauli):
|
303
|
+
raise QiskitError("Operator for expectation value is not a Pauli operator.")
|
304
|
+
|
305
|
+
num_qubits = self.clifford.num_qubits
|
306
|
+
if qargs is None:
|
307
|
+
qubits = range(num_qubits)
|
308
|
+
else:
|
309
|
+
qubits = qargs
|
310
|
+
|
311
|
+
# Construct Pauli on num_qubits
|
312
|
+
pauli = Pauli(num_qubits * "I")
|
313
|
+
phase = 0
|
314
|
+
pauli_phase = (-1j) ** oper.phase if oper.phase else 1
|
315
|
+
|
316
|
+
for pos, qubit in enumerate(qubits):
|
317
|
+
pauli.x[qubit] = oper.x[pos]
|
318
|
+
pauli.z[qubit] = oper.z[pos]
|
319
|
+
phase += pauli.x[qubit] & pauli.z[qubit]
|
320
|
+
|
321
|
+
# Check if there is a stabilizer that anti-commutes with an odd number of qubits
|
322
|
+
# If so the expectation value is 0
|
323
|
+
for p in range(num_qubits):
|
324
|
+
num_anti = 0
|
325
|
+
num_anti += np.count_nonzero(pauli.z & self.clifford.stab_x[p])
|
326
|
+
num_anti += np.count_nonzero(pauli.x & self.clifford.stab_z[p])
|
327
|
+
if num_anti % 2 == 1:
|
328
|
+
return 0
|
329
|
+
|
330
|
+
# Otherwise pauli is (-1)^a prod_j S_j^b_j for Clifford stabilizers
|
331
|
+
# If pauli anti-commutes with D_j then b_j = 1.
|
332
|
+
# Multiply pauli by stabilizers with anti-commuting destabilisers
|
333
|
+
pauli_z = (pauli.z).copy() # Make a copy of pauli.z
|
334
|
+
for p in range(num_qubits):
|
335
|
+
# Check if destabilizer anti-commutes
|
336
|
+
num_anti = 0
|
337
|
+
num_anti += np.count_nonzero(pauli.z & self.clifford.destab_x[p])
|
338
|
+
num_anti += np.count_nonzero(pauli.x & self.clifford.destab_z[p])
|
339
|
+
if num_anti % 2 == 0:
|
340
|
+
continue
|
341
|
+
|
342
|
+
# If anti-commutes multiply Pauli by stabilizer
|
343
|
+
phase += 2 * self.clifford.stab_phase[p]
|
344
|
+
phase += np.count_nonzero(self.clifford.stab_z[p] & self.clifford.stab_x[p])
|
345
|
+
phase += 2 * np.count_nonzero(pauli_z & self.clifford.stab_x[p])
|
346
|
+
pauli_z = pauli_z ^ self.clifford.stab_z[p]
|
347
|
+
|
348
|
+
# For valid stabilizers, `phase` can only be 0 (= 1) or 2 (= -1) at this point.
|
349
|
+
if phase % 4 != 0:
|
350
|
+
return -pauli_phase
|
351
|
+
|
352
|
+
return pauli_phase
|
353
|
+
|
354
|
+
def equiv(self, other: StabilizerState) -> bool:
|
355
|
+
"""Return True if the two generating sets generate the same stabilizer group.
|
356
|
+
|
357
|
+
Args:
|
358
|
+
other (StabilizerState): another StabilizerState.
|
359
|
+
|
360
|
+
Returns:
|
361
|
+
bool: True if other has a generating set that generates the same StabilizerState.
|
362
|
+
"""
|
363
|
+
if not isinstance(other, StabilizerState):
|
364
|
+
try:
|
365
|
+
other = StabilizerState(other)
|
366
|
+
except QiskitError:
|
367
|
+
return False
|
368
|
+
|
369
|
+
num_qubits = self.num_qubits
|
370
|
+
if other.num_qubits != num_qubits:
|
371
|
+
return False
|
372
|
+
|
373
|
+
pauli_orig = PauliList.from_symplectic(
|
374
|
+
self._data.stab_z, self._data.stab_x, 2 * self._data.stab_phase
|
375
|
+
)
|
376
|
+
pauli_other = PauliList.from_symplectic(
|
377
|
+
other._data.stab_z, other._data.stab_x, 2 * other._data.stab_phase
|
378
|
+
)
|
379
|
+
|
380
|
+
# Check that each stabilizer from the original set commutes with each stabilizer
|
381
|
+
# from the other set
|
382
|
+
if not np.all([pauli.commutes(pauli_other) for pauli in pauli_orig]):
|
383
|
+
return False
|
384
|
+
|
385
|
+
# Compute the expected value of each stabilizer from the original set on the stabilizer state
|
386
|
+
# determined by the other set. The two stabilizer states coincide if and only if the
|
387
|
+
# expected value is +1 for each stabilizer
|
388
|
+
for i in range(num_qubits):
|
389
|
+
exp_val = self.expectation_value(pauli_other[i])
|
390
|
+
if exp_val != 1:
|
391
|
+
return False
|
392
|
+
|
393
|
+
return True
|
394
|
+
|
395
|
+
def probabilities(self, qargs: None | list = None, decimals: None | int = None) -> np.ndarray:
|
396
|
+
"""Return the subsystem measurement probability vector.
|
397
|
+
|
398
|
+
Measurement probabilities are with respect to measurement in the
|
399
|
+
computation (diagonal) basis.
|
400
|
+
|
401
|
+
Args:
|
402
|
+
qargs (None or list): subsystems to return probabilities for,
|
403
|
+
if None return for all subsystems (Default: None).
|
404
|
+
decimals (None or int): the number of decimal places to round
|
405
|
+
values. If None no rounding is done (Default: None).
|
406
|
+
|
407
|
+
Returns:
|
408
|
+
np.array: The Numpy vector array of probabilities.
|
409
|
+
"""
|
410
|
+
probs_dict = self.probabilities_dict(qargs, decimals)
|
411
|
+
if qargs is None:
|
412
|
+
qargs = range(self.clifford.num_qubits)
|
413
|
+
probs = np.zeros(2 ** len(qargs))
|
414
|
+
|
415
|
+
for key, value in probs_dict.items():
|
416
|
+
place = int(key, 2)
|
417
|
+
probs[place] = value
|
418
|
+
|
419
|
+
return probs
|
420
|
+
|
421
|
+
def probabilities_dict_from_bitstring(
|
422
|
+
self,
|
423
|
+
outcome_bitstring: str,
|
424
|
+
qargs: None | list = None,
|
425
|
+
decimals: None | int = None,
|
426
|
+
) -> dict[str, float]:
|
427
|
+
"""Return the subsystem measurement probability dictionary utilizing
|
428
|
+
a targeted outcome_bitstring to perform the measurement for. This
|
429
|
+
will calculate a probability for only a single targeted
|
430
|
+
outcome_bitstring value, giving a performance boost over calculating
|
431
|
+
all possible outcomes.
|
432
|
+
|
433
|
+
Measurement probabilities are with respect to measurement in the
|
434
|
+
computation (diagonal) basis.
|
435
|
+
|
436
|
+
This dictionary representation uses a Ket-like notation where the
|
437
|
+
dictionary keys are qudit strings for the subsystem basis vectors.
|
438
|
+
If any subsystem has a dimension greater than 10 comma delimiters are
|
439
|
+
inserted between integers so that subsystems can be distinguished.
|
440
|
+
|
441
|
+
Args:
|
442
|
+
outcome_bitstring (None or str): targeted outcome bitstring
|
443
|
+
to perform a measurement calculation for, this will significantly
|
444
|
+
reduce the number of calculation performed (Default: None)
|
445
|
+
qargs (None or list): subsystems to return probabilities for,
|
446
|
+
if None return for all subsystems (Default: None).
|
447
|
+
decimals (None or int): the number of decimal places to round
|
448
|
+
values. If None no rounding is done (Default: None)
|
449
|
+
|
450
|
+
Returns:
|
451
|
+
dict[str, float]: The measurement probabilities in dict (ket) form.
|
452
|
+
"""
|
453
|
+
return self._get_probabilities_dict(
|
454
|
+
outcome_bitstring=outcome_bitstring, qargs=qargs, decimals=decimals
|
455
|
+
)
|
456
|
+
|
457
|
+
def probabilities_dict(
|
458
|
+
self, qargs: None | list = None, decimals: None | int = None
|
459
|
+
) -> dict[str, float]:
|
460
|
+
"""Return the subsystem measurement probability dictionary.
|
461
|
+
|
462
|
+
Measurement probabilities are with respect to measurement in the
|
463
|
+
computation (diagonal) basis.
|
464
|
+
|
465
|
+
This dictionary representation uses a Ket-like notation where the
|
466
|
+
dictionary keys are qudit strings for the subsystem basis vectors.
|
467
|
+
If any subsystem has a dimension greater than 10 comma delimiters are
|
468
|
+
inserted between integers so that subsystems can be distinguished.
|
469
|
+
|
470
|
+
Args:
|
471
|
+
qargs (None or list): subsystems to return probabilities for,
|
472
|
+
if None return for all subsystems (Default: None).
|
473
|
+
decimals (None or int): the number of decimal places to round
|
474
|
+
values. If None no rounding is done (Default: None).
|
475
|
+
|
476
|
+
Returns:
|
477
|
+
dict: The measurement probabilities in dict (key) form.
|
478
|
+
"""
|
479
|
+
return self._get_probabilities_dict(outcome_bitstring=None, qargs=qargs, decimals=decimals)
|
480
|
+
|
481
|
+
def reset(self, qargs: list | None = None) -> StabilizerState:
|
482
|
+
"""Reset state or subsystems to the 0-state.
|
483
|
+
|
484
|
+
Args:
|
485
|
+
qargs (list or None): subsystems to reset, if None all
|
486
|
+
subsystems will be reset to their 0-state
|
487
|
+
(Default: None).
|
488
|
+
|
489
|
+
Returns:
|
490
|
+
StabilizerState: the reset state.
|
491
|
+
|
492
|
+
Additional Information:
|
493
|
+
If all subsystems are reset this will return the ground state
|
494
|
+
on all subsystems. If only some subsystems are reset this
|
495
|
+
function will perform a measurement on those subsystems and
|
496
|
+
evolve the subsystems so that the collapsed post-measurement
|
497
|
+
states are rotated to the 0-state. The RNG seed for this
|
498
|
+
sampling can be set using the :meth:`seed` method.
|
499
|
+
"""
|
500
|
+
# Resetting all qubits does not require sampling or RNG
|
501
|
+
if qargs is None:
|
502
|
+
return StabilizerState(Clifford(np.eye(2 * self.clifford.num_qubits)))
|
503
|
+
|
504
|
+
randbits = self._rng.integers(2, size=len(qargs))
|
505
|
+
ret = self.copy()
|
506
|
+
|
507
|
+
for bit, qubit in enumerate(qargs):
|
508
|
+
# Apply measurement and get classical outcome
|
509
|
+
outcome = ret._measure_and_update(qubit, randbits[bit])
|
510
|
+
|
511
|
+
# Use the outcome to apply X gate to any qubits left in the
|
512
|
+
# |1> state after measure, then discard outcome.
|
513
|
+
if outcome == 1:
|
514
|
+
_append_x(ret.clifford, qubit)
|
515
|
+
|
516
|
+
return ret
|
517
|
+
|
518
|
+
def measure(self, qargs: list | None = None) -> tuple:
|
519
|
+
"""Measure subsystems and return outcome and post-measure state.
|
520
|
+
|
521
|
+
Note that this function uses the QuantumStates internal random
|
522
|
+
number generator for sampling the measurement outcome. The RNG
|
523
|
+
seed can be set using the :meth:`seed` method.
|
524
|
+
|
525
|
+
Args:
|
526
|
+
qargs (list or None): subsystems to sample measurements for,
|
527
|
+
if None sample measurement of all
|
528
|
+
subsystems (Default: None).
|
529
|
+
|
530
|
+
Returns:
|
531
|
+
tuple: the pair ``(outcome, state)`` where ``outcome`` is the
|
532
|
+
measurement outcome string label, and ``state`` is the
|
533
|
+
collapsed post-measurement stabilizer state for the
|
534
|
+
corresponding outcome.
|
535
|
+
"""
|
536
|
+
if qargs is None:
|
537
|
+
qargs = range(self.clifford.num_qubits)
|
538
|
+
|
539
|
+
randbits = self._rng.integers(2, size=len(qargs))
|
540
|
+
ret = self.copy()
|
541
|
+
|
542
|
+
outcome = ""
|
543
|
+
for bit, qubit in enumerate(qargs):
|
544
|
+
outcome = str(ret._measure_and_update(qubit, randbits[bit])) + outcome
|
545
|
+
|
546
|
+
return outcome, ret
|
547
|
+
|
548
|
+
def sample_memory(self, shots: int, qargs: None | list = None) -> np.ndarray:
|
549
|
+
"""Sample a list of qubit measurement outcomes in the computational basis.
|
550
|
+
|
551
|
+
Args:
|
552
|
+
shots (int): number of samples to generate.
|
553
|
+
qargs (None or list): subsystems to sample measurements for,
|
554
|
+
if None sample measurement of all
|
555
|
+
subsystems (Default: None).
|
556
|
+
|
557
|
+
Returns:
|
558
|
+
np.array: list of sampled counts if the order sampled.
|
559
|
+
|
560
|
+
Additional Information:
|
561
|
+
|
562
|
+
This function implements the measurement :meth:`measure` method.
|
563
|
+
|
564
|
+
The seed for random number generator used for sampling can be
|
565
|
+
set to a fixed value by using the stats :meth:`seed` method.
|
566
|
+
"""
|
567
|
+
memory = []
|
568
|
+
for _ in range(shots):
|
569
|
+
# copy the StabilizerState since measure updates it
|
570
|
+
stab = self.copy()
|
571
|
+
memory.append(stab.measure(qargs)[0])
|
572
|
+
return memory
|
573
|
+
|
574
|
+
# -----------------------------------------------------------------------
|
575
|
+
# Helper functions for calculating the measurement
|
576
|
+
# -----------------------------------------------------------------------
|
577
|
+
def _measure_and_update(self, qubit, randbit):
|
578
|
+
"""Measure a single qubit and return outcome and post-measure state.
|
579
|
+
|
580
|
+
Note that this function uses the QuantumStates internal random
|
581
|
+
number generator for sampling the measurement outcome. The RNG
|
582
|
+
seed can be set using the :meth:`seed` method.
|
583
|
+
|
584
|
+
Note that stabilizer state measurements only have three probabilities:
|
585
|
+
(p0, p1) = (0.5, 0.5), (1, 0), or (0, 1)
|
586
|
+
The random case happens if there is a row anti-commuting with Z[qubit]
|
587
|
+
"""
|
588
|
+
|
589
|
+
num_qubits = self.clifford.num_qubits
|
590
|
+
clifford = self.clifford
|
591
|
+
stab_x = self.clifford.stab_x
|
592
|
+
|
593
|
+
# Check if there exists stabilizer anticommuting with Z[qubit]
|
594
|
+
# in this case the measurement outcome is random
|
595
|
+
z_anticommuting = np.any(stab_x[:, qubit])
|
596
|
+
|
597
|
+
if z_anticommuting == 0:
|
598
|
+
# Deterministic outcome - measuring it will not change the StabilizerState
|
599
|
+
aux_pauli = Pauli(num_qubits * "I")
|
600
|
+
for i in range(num_qubits):
|
601
|
+
if clifford.x[i][qubit]:
|
602
|
+
aux_pauli = self._rowsum_deterministic(clifford, aux_pauli, i + num_qubits)
|
603
|
+
outcome = aux_pauli.phase
|
604
|
+
return outcome
|
605
|
+
|
606
|
+
else:
|
607
|
+
# Non-deterministic outcome
|
608
|
+
outcome = randbit
|
609
|
+
p_qubit = np.min(np.nonzero(stab_x[:, qubit]))
|
610
|
+
p_qubit += num_qubits
|
611
|
+
|
612
|
+
# Updating the StabilizerState
|
613
|
+
for i in range(2 * num_qubits):
|
614
|
+
# the last condition is not in the AG paper but we seem to need it
|
615
|
+
if (clifford.x[i][qubit]) and (i != p_qubit) and (i != (p_qubit - num_qubits)):
|
616
|
+
self._rowsum_nondeterministic(clifford, i, p_qubit)
|
617
|
+
|
618
|
+
clifford.destab[p_qubit - num_qubits] = clifford.stab[p_qubit - num_qubits].copy()
|
619
|
+
clifford.x[p_qubit] = np.zeros(num_qubits)
|
620
|
+
clifford.z[p_qubit] = np.zeros(num_qubits)
|
621
|
+
clifford.z[p_qubit][qubit] = True
|
622
|
+
clifford.phase[p_qubit] = outcome
|
623
|
+
return outcome
|
624
|
+
|
625
|
+
@staticmethod
|
626
|
+
def _phase_exponent(x1, z1, x2, z2):
|
627
|
+
"""Exponent g of i such that Pauli(x1,z1) * Pauli(x2,z2) = i^g Pauli(x1+x2,z1+z2)"""
|
628
|
+
# pylint: disable=invalid-name
|
629
|
+
|
630
|
+
phase = (x2 * z1 * (1 + 2 * z2 + 2 * x1) - x1 * z2 * (1 + 2 * z1 + 2 * x2)) % 4
|
631
|
+
if phase < 0:
|
632
|
+
phase += 4 # now phase in {0, 1, 3}
|
633
|
+
|
634
|
+
if phase == 2:
|
635
|
+
raise QiskitError("Invalid rowsum phase exponent in measurement calculation.")
|
636
|
+
return phase
|
637
|
+
|
638
|
+
@staticmethod
|
639
|
+
def _rowsum(accum_pauli, accum_phase, row_pauli, row_phase):
|
640
|
+
"""Aaronson-Gottesman rowsum helper function"""
|
641
|
+
|
642
|
+
newr = 2 * row_phase + 2 * accum_phase
|
643
|
+
|
644
|
+
for qubit in range(row_pauli.num_qubits):
|
645
|
+
newr += StabilizerState._phase_exponent(
|
646
|
+
row_pauli.x[qubit], row_pauli.z[qubit], accum_pauli.x[qubit], accum_pauli.z[qubit]
|
647
|
+
)
|
648
|
+
newr %= 4
|
649
|
+
if (newr != 0) & (newr != 2):
|
650
|
+
raise QiskitError("Invalid rowsum in measurement calculation.")
|
651
|
+
|
652
|
+
accum_phase = int(newr == 2)
|
653
|
+
accum_pauli.x ^= row_pauli.x
|
654
|
+
accum_pauli.z ^= row_pauli.z
|
655
|
+
return accum_pauli, accum_phase
|
656
|
+
|
657
|
+
@staticmethod
|
658
|
+
def _rowsum_nondeterministic(clifford, accum, row):
|
659
|
+
"""Updating StabilizerState Clifford in the
|
660
|
+
non-deterministic rowsum calculation.
|
661
|
+
row and accum are rows in the StabilizerState Clifford."""
|
662
|
+
|
663
|
+
row_phase = clifford.phase[row]
|
664
|
+
accum_phase = clifford.phase[accum]
|
665
|
+
|
666
|
+
z = clifford.z
|
667
|
+
x = clifford.x
|
668
|
+
row_pauli = Pauli((z[row], x[row]))
|
669
|
+
accum_pauli = Pauli((z[accum], x[accum]))
|
670
|
+
|
671
|
+
accum_pauli, accum_phase = StabilizerState._rowsum(
|
672
|
+
accum_pauli, accum_phase, row_pauli, row_phase
|
673
|
+
)
|
674
|
+
|
675
|
+
clifford.phase[accum] = accum_phase
|
676
|
+
x[accum] = accum_pauli.x
|
677
|
+
z[accum] = accum_pauli.z
|
678
|
+
|
679
|
+
@staticmethod
|
680
|
+
def _rowsum_deterministic(clifford, aux_pauli, row):
|
681
|
+
"""Updating an auxiliary Pauli aux_pauli in the
|
682
|
+
deterministic rowsum calculation.
|
683
|
+
The StabilizerState itself is not updated."""
|
684
|
+
|
685
|
+
row_phase = clifford.phase[row]
|
686
|
+
accum_phase = aux_pauli.phase
|
687
|
+
|
688
|
+
accum_pauli = aux_pauli
|
689
|
+
row_pauli = Pauli((clifford.z[row], clifford.x[row]))
|
690
|
+
|
691
|
+
accum_pauli, accum_phase = StabilizerState._rowsum(
|
692
|
+
accum_pauli, accum_phase, row_pauli, row_phase
|
693
|
+
)
|
694
|
+
|
695
|
+
aux_pauli = accum_pauli
|
696
|
+
aux_pauli.phase = accum_phase
|
697
|
+
return aux_pauli
|
698
|
+
|
699
|
+
# -----------------------------------------------------------------------
|
700
|
+
# Helper functions for calculating the probabilities
|
701
|
+
# -----------------------------------------------------------------------
|
702
|
+
def _get_probabilities(
|
703
|
+
self,
|
704
|
+
qubits: range,
|
705
|
+
outcome: list[str],
|
706
|
+
outcome_prob: float,
|
707
|
+
probs: dict[str, float],
|
708
|
+
outcome_bitstring: str = None,
|
709
|
+
):
|
710
|
+
"""Recursive helper function for calculating the probabilities
|
711
|
+
|
712
|
+
Args:
|
713
|
+
qubits (range): range of qubits
|
714
|
+
outcome (list[str]): outcome being built
|
715
|
+
outcome_prob (float): probability of the outcome
|
716
|
+
probs (dict[str, float]): holds the outcomes and probability results
|
717
|
+
outcome_bitstring (str): target outcome to measure which reduces measurements, None
|
718
|
+
if not targeting a specific target
|
719
|
+
"""
|
720
|
+
qubit_for_branching: int = -1
|
721
|
+
|
722
|
+
ret: StabilizerState = self.copy()
|
723
|
+
|
724
|
+
# Find outcomes for each qubit
|
725
|
+
for i in range(len(qubits)):
|
726
|
+
if outcome[i] == "X":
|
727
|
+
# Retrieve the qubit for the current measurement
|
728
|
+
qubit = qubits[(len(qubits) - i - 1)]
|
729
|
+
# Determine if the probability is deterministic
|
730
|
+
if not any(ret.clifford.stab_x[:, qubit]):
|
731
|
+
single_qubit_outcome: np.int64 = ret._measure_and_update(qubit, 0)
|
732
|
+
if outcome_bitstring is None or (
|
733
|
+
int(outcome_bitstring[i]) == single_qubit_outcome
|
734
|
+
):
|
735
|
+
# No outcome_bitstring target, or using outcome_bitstring target and
|
736
|
+
# the single_qubit_outcome equals the desired outcome_bitstring target value,
|
737
|
+
# then use current outcome_prob value
|
738
|
+
outcome[i] = str(single_qubit_outcome)
|
739
|
+
else:
|
740
|
+
# If the single_qubit_outcome does not equal the outcome_bitsring target
|
741
|
+
# then we know that the probability will be 0
|
742
|
+
outcome[i] = str(outcome_bitstring[i])
|
743
|
+
outcome_prob = 0
|
744
|
+
else:
|
745
|
+
qubit_for_branching = i
|
746
|
+
|
747
|
+
if qubit_for_branching == -1:
|
748
|
+
str_outcome = "".join(outcome)
|
749
|
+
probs[str_outcome] = outcome_prob
|
750
|
+
return
|
751
|
+
|
752
|
+
for single_qubit_outcome in (
|
753
|
+
range(0, 2)
|
754
|
+
if (outcome_bitstring is None)
|
755
|
+
else [int(outcome_bitstring[qubit_for_branching])]
|
756
|
+
):
|
757
|
+
new_outcome = outcome.copy()
|
758
|
+
new_outcome[qubit_for_branching] = str(single_qubit_outcome)
|
759
|
+
|
760
|
+
stab_cpy = ret.copy()
|
761
|
+
stab_cpy._measure_and_update(
|
762
|
+
qubits[(len(qubits) - qubit_for_branching - 1)], single_qubit_outcome
|
763
|
+
)
|
764
|
+
stab_cpy._get_probabilities(
|
765
|
+
qubits, new_outcome, (0.5 * outcome_prob), probs, outcome_bitstring
|
766
|
+
)
|
767
|
+
|
768
|
+
def _get_probabilities_dict(
|
769
|
+
self,
|
770
|
+
outcome_bitstring: None | str = None,
|
771
|
+
qargs: None | list = None,
|
772
|
+
decimals: None | int = None,
|
773
|
+
) -> dict[str, float]:
|
774
|
+
"""Helper Function for calculating the subsystem measurement probability dictionary.
|
775
|
+
When the targeted outcome_bitstring value is set, then only the single outcome_bitstring
|
776
|
+
probability will be calculated.
|
777
|
+
|
778
|
+
Args:
|
779
|
+
outcome_bitstring (None or str): targeted outcome bitstring
|
780
|
+
to perform a measurement calculation for, this will significantly
|
781
|
+
reduce the number of calculation performed (Default: None)
|
782
|
+
qargs (None or list): subsystems to return probabilities for,
|
783
|
+
if None return for all subsystems (Default: None).
|
784
|
+
decimals (None or int): the number of decimal places to round
|
785
|
+
values. If None no rounding is done (Default: None).
|
786
|
+
|
787
|
+
Returns:
|
788
|
+
dict: The measurement probabilities in dict (key) form.
|
789
|
+
"""
|
790
|
+
if qargs is None:
|
791
|
+
qubits = range(self.clifford.num_qubits)
|
792
|
+
else:
|
793
|
+
qubits = qargs
|
794
|
+
|
795
|
+
outcome = ["X"] * len(qubits)
|
796
|
+
outcome_prob = 1.0
|
797
|
+
probs: dict[str, float] = {} # Probabilities dict to return with the measured values
|
798
|
+
|
799
|
+
self._get_probabilities(qubits, outcome, outcome_prob, probs, outcome_bitstring)
|
800
|
+
|
801
|
+
if decimals is not None:
|
802
|
+
for key, value in probs.items():
|
803
|
+
probs[key] = round(value, decimals)
|
804
|
+
|
805
|
+
return probs
|