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,869 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2019.
|
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
|
+
Matrix Operator class.
|
15
|
+
"""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
import cmath
|
20
|
+
import copy as _copy
|
21
|
+
import re
|
22
|
+
from numbers import Number
|
23
|
+
from typing import TYPE_CHECKING
|
24
|
+
|
25
|
+
import numpy as np
|
26
|
+
|
27
|
+
from qiskit import _numpy_compat
|
28
|
+
from qiskit.circuit.instruction import Instruction
|
29
|
+
from qiskit.circuit.library.standard_gates import HGate, IGate, SGate, TGate, XGate, YGate, ZGate
|
30
|
+
from qiskit.circuit.operation import Operation
|
31
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
32
|
+
from qiskit.exceptions import QiskitError
|
33
|
+
from qiskit.quantum_info.operators.base_operator import BaseOperator
|
34
|
+
from qiskit.quantum_info.operators.linear_op import LinearOp
|
35
|
+
from qiskit.quantum_info.operators.mixins import generate_apidocs
|
36
|
+
from qiskit.quantum_info.operators.predicates import is_unitary_matrix, matrix_equal
|
37
|
+
|
38
|
+
if TYPE_CHECKING:
|
39
|
+
from qiskit.transpiler.layout import Layout
|
40
|
+
|
41
|
+
|
42
|
+
class Operator(LinearOp):
|
43
|
+
r"""Matrix operator class
|
44
|
+
|
45
|
+
This represents a matrix operator :math:`M` that will
|
46
|
+
:meth:`~Statevector.evolve` a :class:`Statevector` :math:`|\psi\rangle`
|
47
|
+
by matrix-vector multiplication
|
48
|
+
|
49
|
+
.. math::
|
50
|
+
|
51
|
+
|\psi\rangle \mapsto M|\psi\rangle,
|
52
|
+
|
53
|
+
and will :meth:`~DensityMatrix.evolve` a :class:`DensityMatrix` :math:`\rho`
|
54
|
+
by left and right multiplication
|
55
|
+
|
56
|
+
.. math::
|
57
|
+
|
58
|
+
\rho \mapsto M \rho M^\dagger.
|
59
|
+
|
60
|
+
For example, the following operator :math:`M = X` applied to the zero state
|
61
|
+
:math:`|\psi\rangle=|0\rangle (\rho = |0\rangle\langle 0|)` changes it to the
|
62
|
+
one state :math:`|\psi\rangle=|1\rangle (\rho = |1\rangle\langle 1|)`:
|
63
|
+
|
64
|
+
.. plot::
|
65
|
+
:include-source:
|
66
|
+
:nofigs:
|
67
|
+
|
68
|
+
>>> import numpy as np
|
69
|
+
>>> from qiskit.quantum_info import Operator
|
70
|
+
>>> op = Operator(np.array([[0.0, 1.0], [1.0, 0.0]])) # Represents Pauli X operator
|
71
|
+
|
72
|
+
>>> from qiskit.quantum_info import Statevector
|
73
|
+
>>> sv = Statevector(np.array([1.0, 0.0]))
|
74
|
+
>>> sv.evolve(op)
|
75
|
+
Statevector([0.+0.j, 1.+0.j],
|
76
|
+
dims=(2,))
|
77
|
+
|
78
|
+
>>> from qiskit.quantum_info import DensityMatrix
|
79
|
+
>>> dm = DensityMatrix(np.array([[1.0, 0.0], [0.0, 0.0]]))
|
80
|
+
>>> dm.evolve(op)
|
81
|
+
DensityMatrix([[0.+0.j, 0.+0.j],
|
82
|
+
[0.+0.j, 1.+0.j]],
|
83
|
+
dims=(2,))
|
84
|
+
|
85
|
+
"""
|
86
|
+
|
87
|
+
def __init__(
|
88
|
+
self,
|
89
|
+
data: QuantumCircuit | Operation | BaseOperator | np.ndarray,
|
90
|
+
input_dims: tuple | None = None,
|
91
|
+
output_dims: tuple | None = None,
|
92
|
+
):
|
93
|
+
"""Initialize an operator object.
|
94
|
+
|
95
|
+
Args:
|
96
|
+
data (QuantumCircuit or Operation or BaseOperator or matrix):
|
97
|
+
data to initialize operator.
|
98
|
+
input_dims (tuple): the input subsystem dimensions.
|
99
|
+
[Default: None]
|
100
|
+
output_dims (tuple): the output subsystem dimensions.
|
101
|
+
[Default: None]
|
102
|
+
|
103
|
+
Raises:
|
104
|
+
QiskitError: if input data cannot be initialized as an operator.
|
105
|
+
|
106
|
+
Additional Information:
|
107
|
+
If the input or output dimensions are None, they will be
|
108
|
+
automatically determined from the input data. If the input data is
|
109
|
+
a Numpy array of shape (2**N, 2**N) qubit systems will be used. If
|
110
|
+
the input operator is not an N-qubit operator, it will assign a
|
111
|
+
single subsystem with dimension specified by the shape of the input.
|
112
|
+
Note that two operators initialized via this method are only considered equivalent if they
|
113
|
+
match up to their canonical qubit order (or: permutation). See :meth:`.Operator.from_circuit`
|
114
|
+
to specify a different qubit permutation.
|
115
|
+
"""
|
116
|
+
op_shape = None
|
117
|
+
if isinstance(data, (list, np.ndarray)):
|
118
|
+
# Default initialization from list or numpy array matrix
|
119
|
+
self._data = np.asarray(data, dtype=complex)
|
120
|
+
elif isinstance(data, (QuantumCircuit, Operation)):
|
121
|
+
# If the input is a Terra QuantumCircuit or Operation we
|
122
|
+
# perform a simulation to construct the unitary operator.
|
123
|
+
# This will only work if the circuit or instruction can be
|
124
|
+
# defined in terms of unitary gate instructions which have a
|
125
|
+
# 'to_matrix' method defined. Any other instructions such as
|
126
|
+
# conditional gates, measure, or reset will cause an
|
127
|
+
# exception to be raised.
|
128
|
+
self._data = self._init_instruction(data).data
|
129
|
+
elif hasattr(data, "to_operator"):
|
130
|
+
# If the data object has a 'to_operator' attribute this is given
|
131
|
+
# higher preference than the 'to_matrix' method for initializing
|
132
|
+
# an Operator object.
|
133
|
+
data = data.to_operator()
|
134
|
+
self._data = data.data
|
135
|
+
op_shape = data._op_shape
|
136
|
+
elif hasattr(data, "to_matrix"):
|
137
|
+
# If no 'to_operator' attribute exists we next look for a
|
138
|
+
# 'to_matrix' attribute to a matrix that will be cast into
|
139
|
+
# a complex numpy matrix.
|
140
|
+
self._data = np.asarray(data.to_matrix(), dtype=complex)
|
141
|
+
else:
|
142
|
+
raise QiskitError("Invalid input data format for Operator")
|
143
|
+
|
144
|
+
super().__init__(
|
145
|
+
op_shape=op_shape,
|
146
|
+
input_dims=input_dims,
|
147
|
+
output_dims=output_dims,
|
148
|
+
shape=self._data.shape,
|
149
|
+
)
|
150
|
+
|
151
|
+
def __array__(self, dtype=None, copy=_numpy_compat.COPY_ONLY_IF_NEEDED):
|
152
|
+
dtype = self.data.dtype if dtype is None else dtype
|
153
|
+
return np.array(self.data, dtype=dtype, copy=copy)
|
154
|
+
|
155
|
+
def __repr__(self):
|
156
|
+
prefix = "Operator("
|
157
|
+
pad = len(prefix) * " "
|
158
|
+
return (
|
159
|
+
f"{prefix}{np.array2string(self.data, separator=', ', prefix=prefix)},\n"
|
160
|
+
f"{pad}input_dims={self.input_dims()}, output_dims={self.output_dims()})"
|
161
|
+
)
|
162
|
+
|
163
|
+
def __eq__(self, other):
|
164
|
+
"""Test if two Operators are equal."""
|
165
|
+
if not super().__eq__(other):
|
166
|
+
return False
|
167
|
+
return np.allclose(self.data, other.data, rtol=self.rtol, atol=self.atol)
|
168
|
+
|
169
|
+
@property
|
170
|
+
def data(self):
|
171
|
+
"""The underlying Numpy array."""
|
172
|
+
return self._data
|
173
|
+
|
174
|
+
@property
|
175
|
+
def settings(self):
|
176
|
+
"""Return operator settings."""
|
177
|
+
return {
|
178
|
+
"data": self._data,
|
179
|
+
"input_dims": self.input_dims(),
|
180
|
+
"output_dims": self.output_dims(),
|
181
|
+
}
|
182
|
+
|
183
|
+
def draw(self, output=None, **drawer_args):
|
184
|
+
"""Return a visualization of the Operator.
|
185
|
+
|
186
|
+
**repr**: String of the state's ``__repr__``.
|
187
|
+
|
188
|
+
**text**: ASCII TextMatrix that can be printed in the console.
|
189
|
+
|
190
|
+
**latex**: An IPython Latex object for displaying in Jupyter Notebooks.
|
191
|
+
|
192
|
+
**latex_source**: Raw, uncompiled ASCII source to generate array using LaTeX.
|
193
|
+
|
194
|
+
Args:
|
195
|
+
output (str): Select the output method to use for drawing the
|
196
|
+
state. Valid choices are `repr`, `text`, `latex`, `latex_source`,
|
197
|
+
Default is `repr`.
|
198
|
+
drawer_args: Arguments to be passed directly to the relevant drawing
|
199
|
+
function or constructor (`TextMatrix()`, `array_to_latex()`).
|
200
|
+
See the relevant function under `qiskit.visualization` for that function's
|
201
|
+
documentation.
|
202
|
+
|
203
|
+
Returns:
|
204
|
+
:class:`str` or :class:`TextMatrix` or :class:`IPython.display.Latex`:
|
205
|
+
Drawing of the Operator.
|
206
|
+
|
207
|
+
Raises:
|
208
|
+
ValueError: when an invalid output method is selected.
|
209
|
+
MissingOptionalLibrary: If SymPy isn't installed and ``'latex'`` or
|
210
|
+
``'latex_source'`` is selected for ``output``.
|
211
|
+
|
212
|
+
"""
|
213
|
+
# pylint: disable=cyclic-import
|
214
|
+
from qiskit.visualization import array_to_latex
|
215
|
+
|
216
|
+
default_output = "repr"
|
217
|
+
if output is None:
|
218
|
+
output = default_output
|
219
|
+
|
220
|
+
if output == "repr":
|
221
|
+
return self.__repr__()
|
222
|
+
|
223
|
+
elif output == "text":
|
224
|
+
from qiskit.visualization.state_visualization import TextMatrix
|
225
|
+
|
226
|
+
return TextMatrix(self, **drawer_args)
|
227
|
+
|
228
|
+
elif output == "latex":
|
229
|
+
return array_to_latex(self, **drawer_args)
|
230
|
+
|
231
|
+
elif output == "latex_source":
|
232
|
+
return array_to_latex(self, source=True, **drawer_args)
|
233
|
+
|
234
|
+
else:
|
235
|
+
raise ValueError(
|
236
|
+
f"""'{output}' is not a valid option for drawing {type(self).__name__} objects.
|
237
|
+
Please choose from: 'text', 'latex', or 'latex_source'."""
|
238
|
+
)
|
239
|
+
|
240
|
+
def _ipython_display_(self):
|
241
|
+
out = self.draw()
|
242
|
+
if isinstance(out, str):
|
243
|
+
print(out) # pylint: disable=bad-builtin
|
244
|
+
else:
|
245
|
+
from IPython.display import display
|
246
|
+
|
247
|
+
display(out)
|
248
|
+
|
249
|
+
@classmethod
|
250
|
+
def from_label(cls, label: str) -> Operator:
|
251
|
+
"""Return a tensor product of single-qubit operators.
|
252
|
+
|
253
|
+
Args:
|
254
|
+
label (string): single-qubit operator string.
|
255
|
+
|
256
|
+
Returns:
|
257
|
+
Operator: The N-qubit operator.
|
258
|
+
|
259
|
+
Raises:
|
260
|
+
QiskitError: if the label contains invalid characters, or the
|
261
|
+
length of the label is larger than an explicitly
|
262
|
+
specified num_qubits.
|
263
|
+
|
264
|
+
Additional Information:
|
265
|
+
The labels correspond to the single-qubit matrices:
|
266
|
+
'I': [[1, 0], [0, 1]]
|
267
|
+
'X': [[0, 1], [1, 0]]
|
268
|
+
'Y': [[0, -1j], [1j, 0]]
|
269
|
+
'Z': [[1, 0], [0, -1]]
|
270
|
+
'H': [[1, 1], [1, -1]] / sqrt(2)
|
271
|
+
'S': [[1, 0], [0 , 1j]]
|
272
|
+
'T': [[1, 0], [0, (1+1j) / sqrt(2)]]
|
273
|
+
'0': [[1, 0], [0, 0]]
|
274
|
+
'1': [[0, 0], [0, 1]]
|
275
|
+
'+': [[0.5, 0.5], [0.5 , 0.5]]
|
276
|
+
'-': [[0.5, -0.5], [-0.5 , 0.5]]
|
277
|
+
'r': [[0.5, -0.5j], [0.5j , 0.5]]
|
278
|
+
'l': [[0.5, 0.5j], [-0.5j , 0.5]]
|
279
|
+
"""
|
280
|
+
# Check label is valid
|
281
|
+
label_mats = {
|
282
|
+
"I": IGate().to_matrix(),
|
283
|
+
"X": XGate().to_matrix(),
|
284
|
+
"Y": YGate().to_matrix(),
|
285
|
+
"Z": ZGate().to_matrix(),
|
286
|
+
"H": HGate().to_matrix(),
|
287
|
+
"S": SGate().to_matrix(),
|
288
|
+
"T": TGate().to_matrix(),
|
289
|
+
"0": np.array([[1, 0], [0, 0]], dtype=complex),
|
290
|
+
"1": np.array([[0, 0], [0, 1]], dtype=complex),
|
291
|
+
"+": np.array([[0.5, 0.5], [0.5, 0.5]], dtype=complex),
|
292
|
+
"-": np.array([[0.5, -0.5], [-0.5, 0.5]], dtype=complex),
|
293
|
+
"r": np.array([[0.5, -0.5j], [0.5j, 0.5]], dtype=complex),
|
294
|
+
"l": np.array([[0.5, 0.5j], [-0.5j, 0.5]], dtype=complex),
|
295
|
+
}
|
296
|
+
if re.match(r"^[IXYZHST01rl\-+]+$", label) is None:
|
297
|
+
raise QiskitError("Label contains invalid characters.")
|
298
|
+
# Initialize an identity matrix and apply each gate
|
299
|
+
num_qubits = len(label)
|
300
|
+
op = Operator(np.eye(2**num_qubits, dtype=complex))
|
301
|
+
for qubit, char in enumerate(reversed(label)):
|
302
|
+
if char != "I":
|
303
|
+
op = op.compose(label_mats[char], qargs=[qubit])
|
304
|
+
return op
|
305
|
+
|
306
|
+
def apply_permutation(self, perm: list, front: bool = False) -> Operator:
|
307
|
+
"""Modifies operator's data by composing it with a permutation.
|
308
|
+
|
309
|
+
Args:
|
310
|
+
perm (list): permutation pattern, describing which qubits
|
311
|
+
occupy the positions 0, 1, 2, etc. after applying the permutation.
|
312
|
+
front (bool): When set to ``True`` the permutation is applied before the
|
313
|
+
operator, when set to ``False`` the permutation is applied after the
|
314
|
+
operator.
|
315
|
+
Returns:
|
316
|
+
Operator: The modified operator.
|
317
|
+
|
318
|
+
Raises:
|
319
|
+
QiskitError: if the size of the permutation pattern does not match the
|
320
|
+
dimensions of the operator.
|
321
|
+
"""
|
322
|
+
|
323
|
+
# See https://github.com/Qiskit/qiskit-terra/pull/9403 for the math
|
324
|
+
# behind the following code.
|
325
|
+
|
326
|
+
inv_perm = np.argsort(perm)
|
327
|
+
raw_shape_l = self._op_shape.dims_l()
|
328
|
+
n_dims_l = len(raw_shape_l)
|
329
|
+
raw_shape_r = self._op_shape.dims_r()
|
330
|
+
n_dims_r = len(raw_shape_r)
|
331
|
+
|
332
|
+
if front:
|
333
|
+
# The permutation is applied first, the operator is applied after;
|
334
|
+
# however, in terms of matrices, we compute [O][P].
|
335
|
+
|
336
|
+
if len(perm) != n_dims_r:
|
337
|
+
raise QiskitError(
|
338
|
+
"The size of the permutation pattern does not match dimensions of the operator."
|
339
|
+
)
|
340
|
+
|
341
|
+
# shape: original on left, permuted on right
|
342
|
+
shape_l = self._op_shape.dims_l()
|
343
|
+
shape_r = tuple(raw_shape_r[n_dims_r - n - 1] for n in reversed(perm))
|
344
|
+
|
345
|
+
# axes order: id on left, inv-permuted on right
|
346
|
+
axes_l = tuple(x for x in range(self._op_shape._num_qargs_l))
|
347
|
+
axes_r = tuple(self._op_shape._num_qargs_l + x for x in (np.argsort(perm[::-1]))[::-1])
|
348
|
+
|
349
|
+
# updated shape: original on left, permuted on right
|
350
|
+
new_shape_l = self._op_shape.dims_l()
|
351
|
+
new_shape_r = tuple(raw_shape_r[n_dims_r - n - 1] for n in reversed(inv_perm))
|
352
|
+
|
353
|
+
else:
|
354
|
+
# The operator is applied first, the permutation is applied after;
|
355
|
+
# however, in terms of matrices, we compute [P][O].
|
356
|
+
|
357
|
+
if len(perm) != n_dims_l:
|
358
|
+
raise QiskitError(
|
359
|
+
"The size of the permutation pattern does not match dimensions of the operator."
|
360
|
+
)
|
361
|
+
|
362
|
+
# shape: inv-permuted on left, original on right
|
363
|
+
shape_l = tuple(raw_shape_l[n_dims_l - n - 1] for n in reversed(inv_perm))
|
364
|
+
shape_r = self._op_shape.dims_r()
|
365
|
+
|
366
|
+
# axes order: permuted on left, id on right
|
367
|
+
axes_l = tuple((np.argsort(inv_perm[::-1]))[::-1])
|
368
|
+
axes_r = tuple(
|
369
|
+
self._op_shape._num_qargs_l + x for x in range(self._op_shape._num_qargs_r)
|
370
|
+
)
|
371
|
+
|
372
|
+
# updated shape: permuted on left, original on right
|
373
|
+
new_shape_l = tuple(raw_shape_l[n_dims_l - n - 1] for n in reversed(perm))
|
374
|
+
new_shape_r = self._op_shape.dims_r()
|
375
|
+
|
376
|
+
# Computing the new operator
|
377
|
+
split_shape = shape_l + shape_r
|
378
|
+
axes_order = axes_l + axes_r
|
379
|
+
new_mat = (
|
380
|
+
self._data.reshape(split_shape).transpose(axes_order).reshape(self._op_shape.shape)
|
381
|
+
)
|
382
|
+
new_op = Operator(new_mat, input_dims=new_shape_r, output_dims=new_shape_l)
|
383
|
+
return new_op
|
384
|
+
|
385
|
+
@classmethod
|
386
|
+
def from_circuit(
|
387
|
+
cls,
|
388
|
+
circuit: QuantumCircuit,
|
389
|
+
ignore_set_layout: bool = False,
|
390
|
+
layout: Layout | None = None,
|
391
|
+
final_layout: Layout | None = None,
|
392
|
+
) -> Operator:
|
393
|
+
"""Create a new Operator object from a :class:`.QuantumCircuit`
|
394
|
+
|
395
|
+
While a :class:`~.QuantumCircuit` object can passed directly as ``data``
|
396
|
+
to the class constructor this provides no options on how the circuit
|
397
|
+
is used to create an :class:`.Operator`. This constructor method lets
|
398
|
+
you control how the :class:`.Operator` is created so it can be adjusted
|
399
|
+
for a particular use case.
|
400
|
+
|
401
|
+
By default this constructor method will permute the qubits based on a
|
402
|
+
configured initial layout (i.e. after it was transpiled). It also
|
403
|
+
provides an option to manually provide a :class:`.Layout` object
|
404
|
+
directly.
|
405
|
+
|
406
|
+
Args:
|
407
|
+
circuit (QuantumCircuit): The :class:`.QuantumCircuit` to create an Operator
|
408
|
+
object from.
|
409
|
+
ignore_set_layout (bool): When set to ``True`` if the input ``circuit``
|
410
|
+
has a layout set it will be ignored
|
411
|
+
layout (Layout): If specified this kwarg can be used to specify a
|
412
|
+
particular layout to use to permute the qubits in the created
|
413
|
+
:class:`.Operator`. If this is specified it will be used instead
|
414
|
+
of a layout contained in the ``circuit`` input. If specified
|
415
|
+
the virtual bits in the :class:`~.Layout` must be present in the
|
416
|
+
``circuit`` input.
|
417
|
+
final_layout (Layout): If specified this kwarg can be used to represent the
|
418
|
+
output permutation caused by swap insertions during the routing stage
|
419
|
+
of the transpiler.
|
420
|
+
Returns:
|
421
|
+
Operator: An operator representing the input circuit
|
422
|
+
"""
|
423
|
+
|
424
|
+
if layout is None:
|
425
|
+
if not ignore_set_layout:
|
426
|
+
layout = getattr(circuit, "_layout", None)
|
427
|
+
else:
|
428
|
+
from qiskit.transpiler.layout import TranspileLayout # pylint: disable=cyclic-import
|
429
|
+
|
430
|
+
layout = TranspileLayout(
|
431
|
+
initial_layout=layout,
|
432
|
+
input_qubit_mapping={qubit: index for index, qubit in enumerate(circuit.qubits)},
|
433
|
+
)
|
434
|
+
|
435
|
+
initial_layout = layout.initial_layout if layout is not None else None
|
436
|
+
|
437
|
+
if final_layout is None:
|
438
|
+
if not ignore_set_layout and layout is not None:
|
439
|
+
final_layout = getattr(layout, "final_layout", None)
|
440
|
+
|
441
|
+
from qiskit.synthesis.permutation.permutation_utils import _inverse_pattern
|
442
|
+
|
443
|
+
op = Operator(circuit)
|
444
|
+
|
445
|
+
if initial_layout is not None:
|
446
|
+
input_qubits = [None] * len(layout.input_qubit_mapping)
|
447
|
+
for q, p in layout.input_qubit_mapping.items():
|
448
|
+
input_qubits[p] = q
|
449
|
+
|
450
|
+
initial_permutation = initial_layout.to_permutation(input_qubits)
|
451
|
+
initial_permutation_inverse = _inverse_pattern(initial_permutation)
|
452
|
+
op = op.apply_permutation(initial_permutation, True)
|
453
|
+
|
454
|
+
if final_layout is not None:
|
455
|
+
final_permutation = final_layout.to_permutation(circuit.qubits)
|
456
|
+
final_permutation_inverse = _inverse_pattern(final_permutation)
|
457
|
+
op = op.apply_permutation(final_permutation_inverse, False)
|
458
|
+
op = op.apply_permutation(initial_permutation_inverse, False)
|
459
|
+
elif final_layout is not None:
|
460
|
+
final_permutation = final_layout.to_permutation(circuit.qubits)
|
461
|
+
final_permutation_inverse = _inverse_pattern(final_permutation)
|
462
|
+
op = op.apply_permutation(final_permutation_inverse, False)
|
463
|
+
|
464
|
+
return op
|
465
|
+
|
466
|
+
def is_unitary(self, atol=None, rtol=None):
|
467
|
+
"""Return True if operator is a unitary matrix."""
|
468
|
+
if atol is None:
|
469
|
+
atol = self.atol
|
470
|
+
if rtol is None:
|
471
|
+
rtol = self.rtol
|
472
|
+
return is_unitary_matrix(self._data, rtol=rtol, atol=atol)
|
473
|
+
|
474
|
+
def to_operator(self) -> Operator:
|
475
|
+
"""Convert operator to matrix operator class"""
|
476
|
+
return self
|
477
|
+
|
478
|
+
def to_instruction(self):
|
479
|
+
"""Convert to a UnitaryGate instruction."""
|
480
|
+
# pylint: disable=cyclic-import
|
481
|
+
from qiskit.circuit.library.generalized_gates.unitary import UnitaryGate
|
482
|
+
|
483
|
+
return UnitaryGate(self.data)
|
484
|
+
|
485
|
+
def conjugate(self):
|
486
|
+
# Make a shallow copy and update array
|
487
|
+
ret = _copy.copy(self)
|
488
|
+
ret._data = np.conj(self._data)
|
489
|
+
return ret
|
490
|
+
|
491
|
+
def transpose(self):
|
492
|
+
# Make a shallow copy and update array
|
493
|
+
ret = _copy.copy(self)
|
494
|
+
ret._data = np.transpose(self._data)
|
495
|
+
ret._op_shape = self._op_shape.transpose()
|
496
|
+
return ret
|
497
|
+
|
498
|
+
def compose(self, other: Operator, qargs: list | None = None, front: bool = False) -> Operator:
|
499
|
+
if qargs is None:
|
500
|
+
qargs = getattr(other, "qargs", None)
|
501
|
+
if not isinstance(other, Operator):
|
502
|
+
other = Operator(other)
|
503
|
+
|
504
|
+
# Validate dimensions are compatible and return the composed
|
505
|
+
# operator dimensions
|
506
|
+
new_shape = self._op_shape.compose(other._op_shape, qargs, front)
|
507
|
+
input_dims = new_shape.dims_r()
|
508
|
+
output_dims = new_shape.dims_l()
|
509
|
+
|
510
|
+
# Full composition of operators
|
511
|
+
if qargs is None:
|
512
|
+
if front:
|
513
|
+
# Composition self * other
|
514
|
+
data = np.dot(self._data, other.data)
|
515
|
+
else:
|
516
|
+
# Composition other * self
|
517
|
+
data = np.dot(other.data, self._data)
|
518
|
+
ret = Operator(data, input_dims, output_dims)
|
519
|
+
ret._op_shape = new_shape
|
520
|
+
return ret
|
521
|
+
|
522
|
+
# Compose with other on subsystem
|
523
|
+
num_qargs_l, num_qargs_r = self._op_shape.num_qargs
|
524
|
+
if front:
|
525
|
+
num_indices = num_qargs_r
|
526
|
+
shift = num_qargs_l
|
527
|
+
right_mul = True
|
528
|
+
else:
|
529
|
+
num_indices = num_qargs_l
|
530
|
+
shift = 0
|
531
|
+
right_mul = False
|
532
|
+
|
533
|
+
# Reshape current matrix
|
534
|
+
# Note that we must reverse the subsystem dimension order as
|
535
|
+
# qubit 0 corresponds to the right-most position in the tensor
|
536
|
+
# product, which is the last tensor wire index.
|
537
|
+
tensor = np.reshape(self.data, self._op_shape.tensor_shape)
|
538
|
+
mat = np.reshape(other.data, other._op_shape.tensor_shape)
|
539
|
+
indices = [num_indices - 1 - qubit for qubit in qargs]
|
540
|
+
final_shape = [int(np.prod(output_dims)), int(np.prod(input_dims))]
|
541
|
+
data = np.reshape(
|
542
|
+
Operator._einsum_matmul(tensor, mat, indices, shift, right_mul), final_shape
|
543
|
+
)
|
544
|
+
ret = Operator(data, input_dims, output_dims)
|
545
|
+
ret._op_shape = new_shape
|
546
|
+
return ret
|
547
|
+
|
548
|
+
def power(
|
549
|
+
self, n: float, branch_cut_rotation=cmath.pi * 1e-12, assume_unitary=False
|
550
|
+
) -> Operator:
|
551
|
+
"""Return the matrix power of the operator.
|
552
|
+
|
553
|
+
Non-integer powers of operators with an eigenvalue whose complex phase is :math:`\\pi` have
|
554
|
+
a branch cut in the complex plane, which makes the calculation of the principal root around
|
555
|
+
this cut subject to precision / differences in BLAS implementation. For example, the square
|
556
|
+
root of Pauli Y can return the :math:`\\pi/2` or :math:`-\\pi/2` Y rotation depending on
|
557
|
+
whether the -1 eigenvalue is found as ``complex(-1, tiny)`` or ``complex(-1, -tiny)``. Such
|
558
|
+
eigenvalues are really common in quantum information, so this function first phase-rotates
|
559
|
+
the input matrix to shift the branch cut to a far less common point. The underlying
|
560
|
+
numerical precision issues around the branch-cut point remain, if an operator has an
|
561
|
+
eigenvalue close to this phase. The magnitude of this rotation can be controlled with the
|
562
|
+
``branch_cut_rotation`` parameter.
|
563
|
+
|
564
|
+
The choice of ``branch_cut_rotation`` affects the principal root that is found. For
|
565
|
+
example, the square root of :class:`.ZGate` will be calculated as either :class:`.SGate` or
|
566
|
+
:class:`.SdgGate` depending on which way the rotation is done::
|
567
|
+
|
568
|
+
from qiskit.circuit import library
|
569
|
+
from qiskit.quantum_info import Operator
|
570
|
+
|
571
|
+
z_op = Operator(library.ZGate())
|
572
|
+
assert z_op.power(0.5, branch_cut_rotation=1e-3) == Operator(library.SGate())
|
573
|
+
assert z_op.power(0.5, branch_cut_rotation=-1e-3) == Operator(library.SdgGate())
|
574
|
+
|
575
|
+
Args:
|
576
|
+
n (float): the power to raise the matrix to.
|
577
|
+
branch_cut_rotation (float): The rotation angle to apply to the branch cut in the
|
578
|
+
complex plane. This shifts the branch cut away from the common point of :math:`-1`,
|
579
|
+
but can cause a different root to be selected as the principal root. The rotation
|
580
|
+
is anticlockwise, following the standard convention for complex phase.
|
581
|
+
assume_unitary (bool): if ``True``, the operator is assumed to be unitary. In this case,
|
582
|
+
for fractional powers we employ a faster implementation based on Schur's decomposition.
|
583
|
+
|
584
|
+
Returns:
|
585
|
+
Operator: the resulting operator ``O ** n``.
|
586
|
+
|
587
|
+
Raises:
|
588
|
+
QiskitError: if the input and output dimensions of the operator
|
589
|
+
are not equal.
|
590
|
+
|
591
|
+
.. note::
|
592
|
+
It is only safe to set the argument ``assume_unitary`` to ``True`` when the operator
|
593
|
+
is unitary (or, more generally, normal). Otherwise, the function will return an
|
594
|
+
incorrect output.
|
595
|
+
"""
|
596
|
+
if self.input_dims() != self.output_dims():
|
597
|
+
raise QiskitError("Can only power with input_dims = output_dims.")
|
598
|
+
ret = _copy.copy(self)
|
599
|
+
if isinstance(n, int):
|
600
|
+
ret._data = np.linalg.matrix_power(self.data, n)
|
601
|
+
else:
|
602
|
+
import scipy.linalg
|
603
|
+
|
604
|
+
if assume_unitary:
|
605
|
+
# Experimentally, for fractional powers this seems to be 3x faster than
|
606
|
+
# calling scipy.linalg.fractional_matrix_power(self.data, exponent)
|
607
|
+
decomposition, unitary = scipy.linalg.schur(
|
608
|
+
cmath.rect(1, -branch_cut_rotation) * self.data, output="complex"
|
609
|
+
)
|
610
|
+
decomposition_diagonal = decomposition.diagonal()
|
611
|
+
decomposition_power = [pow(element, n) for element in decomposition_diagonal]
|
612
|
+
unitary_power = unitary @ np.diag(decomposition_power) @ unitary.conj().T
|
613
|
+
ret._data = cmath.rect(1, branch_cut_rotation * n) * unitary_power
|
614
|
+
else:
|
615
|
+
ret._data = cmath.rect(
|
616
|
+
1, branch_cut_rotation * n
|
617
|
+
) * scipy.linalg.fractional_matrix_power(
|
618
|
+
cmath.rect(1, -branch_cut_rotation) * self.data, n
|
619
|
+
)
|
620
|
+
|
621
|
+
return ret
|
622
|
+
|
623
|
+
def tensor(self, other: Operator) -> Operator:
|
624
|
+
if not isinstance(other, Operator):
|
625
|
+
other = Operator(other)
|
626
|
+
return self._tensor(self, other)
|
627
|
+
|
628
|
+
def expand(self, other: Operator) -> Operator:
|
629
|
+
if not isinstance(other, Operator):
|
630
|
+
other = Operator(other)
|
631
|
+
return self._tensor(other, self)
|
632
|
+
|
633
|
+
@classmethod
|
634
|
+
def _tensor(cls, a, b):
|
635
|
+
ret = _copy.copy(a)
|
636
|
+
ret._op_shape = a._op_shape.tensor(b._op_shape)
|
637
|
+
ret._data = np.kron(a.data, b.data)
|
638
|
+
return ret
|
639
|
+
|
640
|
+
def _add(self, other, qargs=None):
|
641
|
+
"""Return the operator self + other.
|
642
|
+
|
643
|
+
If ``qargs`` are specified the other operator will be added
|
644
|
+
assuming it is identity on all other subsystems.
|
645
|
+
|
646
|
+
Args:
|
647
|
+
other (Operator): an operator object.
|
648
|
+
qargs (None or list): optional subsystems to add on
|
649
|
+
(Default: None)
|
650
|
+
|
651
|
+
Returns:
|
652
|
+
Operator: the operator self + other.
|
653
|
+
|
654
|
+
Raises:
|
655
|
+
QiskitError: if other is not an operator, or has incompatible
|
656
|
+
dimensions.
|
657
|
+
"""
|
658
|
+
# pylint: disable=cyclic-import
|
659
|
+
from qiskit.quantum_info.operators.scalar_op import ScalarOp
|
660
|
+
|
661
|
+
if qargs is None:
|
662
|
+
qargs = getattr(other, "qargs", None)
|
663
|
+
|
664
|
+
if not isinstance(other, Operator):
|
665
|
+
other = Operator(other)
|
666
|
+
|
667
|
+
self._op_shape._validate_add(other._op_shape, qargs)
|
668
|
+
other = ScalarOp._pad_with_identity(self, other, qargs)
|
669
|
+
|
670
|
+
ret = _copy.copy(self)
|
671
|
+
ret._data = self.data + other.data
|
672
|
+
return ret
|
673
|
+
|
674
|
+
def _multiply(self, other):
|
675
|
+
"""Return the operator self * other.
|
676
|
+
|
677
|
+
Args:
|
678
|
+
other (complex): a complex number.
|
679
|
+
|
680
|
+
Returns:
|
681
|
+
Operator: the operator other * self.
|
682
|
+
|
683
|
+
Raises:
|
684
|
+
QiskitError: if other is not a valid complex number.
|
685
|
+
"""
|
686
|
+
if not isinstance(other, Number):
|
687
|
+
raise QiskitError("other is not a number")
|
688
|
+
ret = _copy.copy(self)
|
689
|
+
ret._data = other * self._data
|
690
|
+
return ret
|
691
|
+
|
692
|
+
def equiv(self, other: Operator, rtol: float | None = None, atol: float | None = None) -> bool:
|
693
|
+
"""Return True if operators are equivalent up to global phase.
|
694
|
+
|
695
|
+
Args:
|
696
|
+
other (Operator): an operator object.
|
697
|
+
rtol (float): relative tolerance value for comparison.
|
698
|
+
atol (float): absolute tolerance value for comparison.
|
699
|
+
|
700
|
+
Returns:
|
701
|
+
bool: True if operators are equivalent up to global phase.
|
702
|
+
"""
|
703
|
+
if not isinstance(other, Operator):
|
704
|
+
try:
|
705
|
+
other = Operator(other)
|
706
|
+
except QiskitError:
|
707
|
+
return False
|
708
|
+
if self.dim != other.dim:
|
709
|
+
return False
|
710
|
+
if atol is None:
|
711
|
+
atol = self.atol
|
712
|
+
if rtol is None:
|
713
|
+
rtol = self.rtol
|
714
|
+
return matrix_equal(self.data, other.data, ignore_phase=True, rtol=rtol, atol=atol)
|
715
|
+
|
716
|
+
def reverse_qargs(self) -> Operator:
|
717
|
+
r"""Return an Operator with reversed subsystem ordering.
|
718
|
+
|
719
|
+
For a tensor product operator this is equivalent to reversing
|
720
|
+
the order of tensor product subsystems. For an operator
|
721
|
+
:math:`A = A_{n-1} \otimes ... \otimes A_0`
|
722
|
+
the returned operator will be
|
723
|
+
:math:`A_0 \otimes ... \otimes A_{n-1}`.
|
724
|
+
|
725
|
+
Returns:
|
726
|
+
Operator: the operator with reversed subsystem order.
|
727
|
+
"""
|
728
|
+
ret = _copy.copy(self)
|
729
|
+
axes = tuple(range(self._op_shape._num_qargs_l - 1, -1, -1))
|
730
|
+
axes = axes + tuple(len(axes) + i for i in axes)
|
731
|
+
ret._data = np.reshape(
|
732
|
+
np.transpose(np.reshape(self.data, self._op_shape.tensor_shape), axes),
|
733
|
+
self._op_shape.shape,
|
734
|
+
)
|
735
|
+
ret._op_shape = self._op_shape.reverse()
|
736
|
+
return ret
|
737
|
+
|
738
|
+
def to_matrix(self):
|
739
|
+
"""Convert operator to NumPy matrix."""
|
740
|
+
return self.data
|
741
|
+
|
742
|
+
@classmethod
|
743
|
+
def _einsum_matmul(cls, tensor, mat, indices, shift=0, right_mul=False):
|
744
|
+
"""Perform a contraction using Numpy.einsum
|
745
|
+
|
746
|
+
Args:
|
747
|
+
tensor (np.array): a vector or matrix reshaped to a rank-N tensor.
|
748
|
+
mat (np.array): a matrix reshaped to a rank-2M tensor.
|
749
|
+
indices (list): tensor indices to contract with mat.
|
750
|
+
shift (int): shift for indices of tensor to contract [Default: 0].
|
751
|
+
right_mul (bool): if True right multiply tensor by mat
|
752
|
+
(else left multiply) [Default: False].
|
753
|
+
|
754
|
+
Returns:
|
755
|
+
Numpy.ndarray: the matrix multiplied rank-N tensor.
|
756
|
+
|
757
|
+
Raises:
|
758
|
+
QiskitError: if mat is not an even rank tensor.
|
759
|
+
"""
|
760
|
+
rank = tensor.ndim
|
761
|
+
rank_mat = mat.ndim
|
762
|
+
if rank_mat % 2 != 0:
|
763
|
+
raise QiskitError("Contracted matrix must have an even number of indices.")
|
764
|
+
# Get einsum indices for tensor
|
765
|
+
indices_tensor = list(range(rank))
|
766
|
+
for j, index in enumerate(indices):
|
767
|
+
indices_tensor[index + shift] = rank + j
|
768
|
+
# Get einsum indices for mat
|
769
|
+
mat_contract = list(reversed(range(rank, rank + len(indices))))
|
770
|
+
mat_free = [index + shift for index in reversed(indices)]
|
771
|
+
if right_mul:
|
772
|
+
indices_mat = mat_contract + mat_free
|
773
|
+
else:
|
774
|
+
indices_mat = mat_free + mat_contract
|
775
|
+
return np.einsum(tensor, indices_tensor, mat, indices_mat)
|
776
|
+
|
777
|
+
@classmethod
|
778
|
+
def _init_instruction(cls, instruction):
|
779
|
+
"""Convert a QuantumCircuit or Operation to an Operator."""
|
780
|
+
# Initialize an identity operator of the correct size of the circuit
|
781
|
+
if hasattr(instruction, "__array__"):
|
782
|
+
return Operator(np.array(instruction, dtype=complex))
|
783
|
+
|
784
|
+
dimension = 2**instruction.num_qubits
|
785
|
+
op = Operator(np.eye(dimension))
|
786
|
+
# Convert circuit to an instruction
|
787
|
+
if isinstance(instruction, QuantumCircuit):
|
788
|
+
instruction = instruction.to_instruction()
|
789
|
+
op._append_instruction(instruction)
|
790
|
+
return op
|
791
|
+
|
792
|
+
@classmethod
|
793
|
+
def _instruction_to_matrix(cls, obj):
|
794
|
+
"""Return Operator for instruction if defined or None otherwise."""
|
795
|
+
# Note: to_matrix() is not a required method for Operations, so for now
|
796
|
+
# we do not allow constructing matrices for general Operations.
|
797
|
+
# However, for backward compatibility we need to support constructing matrices
|
798
|
+
# for Cliffords, which happen to have a to_matrix() method.
|
799
|
+
|
800
|
+
# pylint: disable=cyclic-import
|
801
|
+
from qiskit.quantum_info import Clifford
|
802
|
+
from qiskit.circuit.annotated_operation import AnnotatedOperation
|
803
|
+
|
804
|
+
if not isinstance(obj, (Instruction, Clifford, AnnotatedOperation)):
|
805
|
+
raise QiskitError("Input is neither Instruction, Clifford or AnnotatedOperation.")
|
806
|
+
mat = None
|
807
|
+
if hasattr(obj, "to_matrix"):
|
808
|
+
# If instruction is a gate first we see if it has a
|
809
|
+
# `to_matrix` definition and if so use that.
|
810
|
+
try:
|
811
|
+
mat = obj.to_matrix()
|
812
|
+
except QiskitError:
|
813
|
+
pass
|
814
|
+
return mat
|
815
|
+
|
816
|
+
def _append_instruction(self, obj, qargs=None):
|
817
|
+
"""Update the current Operator by apply an instruction."""
|
818
|
+
from qiskit.circuit.barrier import Barrier
|
819
|
+
from .scalar_op import ScalarOp
|
820
|
+
|
821
|
+
mat = self._instruction_to_matrix(obj)
|
822
|
+
if mat is not None:
|
823
|
+
# Perform the composition and inplace update the current state
|
824
|
+
# of the operator
|
825
|
+
op = self.compose(mat, qargs=qargs)
|
826
|
+
self._data = op.data
|
827
|
+
elif isinstance(obj, Barrier):
|
828
|
+
return
|
829
|
+
else:
|
830
|
+
# If the instruction doesn't have a matrix defined we use its
|
831
|
+
# circuit decomposition definition if it exists, otherwise we
|
832
|
+
# cannot compose this gate and raise an error.
|
833
|
+
if obj.definition is None:
|
834
|
+
raise QiskitError(f"Cannot apply Operation: {obj.name}")
|
835
|
+
if not isinstance(obj.definition, QuantumCircuit):
|
836
|
+
raise QiskitError(
|
837
|
+
f'Operation "{obj.name}" '
|
838
|
+
f"definition is {type(obj.definition)} but expected QuantumCircuit."
|
839
|
+
)
|
840
|
+
if obj.definition.global_phase:
|
841
|
+
dimension = 2**obj.num_qubits
|
842
|
+
op = self.compose(
|
843
|
+
ScalarOp(dimension, np.exp(1j * float(obj.definition.global_phase))),
|
844
|
+
qargs=qargs,
|
845
|
+
)
|
846
|
+
self._data = op.data
|
847
|
+
flat_instr = obj.definition
|
848
|
+
bit_indices = {
|
849
|
+
bit: index
|
850
|
+
for bits in [flat_instr.qubits, flat_instr.clbits]
|
851
|
+
for index, bit in enumerate(bits)
|
852
|
+
}
|
853
|
+
|
854
|
+
for instruction in flat_instr:
|
855
|
+
if instruction.clbits:
|
856
|
+
raise QiskitError(
|
857
|
+
"Cannot apply operation with classical bits:"
|
858
|
+
f" {instruction.operation.name}"
|
859
|
+
)
|
860
|
+
# Get the integer position of the flat register
|
861
|
+
if qargs is None:
|
862
|
+
new_qargs = [bit_indices[tup] for tup in instruction.qubits]
|
863
|
+
else:
|
864
|
+
new_qargs = [qargs[bit_indices[tup]] for tup in instruction.qubits]
|
865
|
+
self._append_instruction(instruction.operation, qargs=new_qargs)
|
866
|
+
|
867
|
+
|
868
|
+
# Update docstrings for API docs
|
869
|
+
generate_apidocs(Operator)
|