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,1481 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017.
|
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
|
+
"""X, CX, CCX and multi-controlled X gates."""
|
14
|
+
from __future__ import annotations
|
15
|
+
from typing import Optional, Union, Type
|
16
|
+
from math import pi
|
17
|
+
import numpy
|
18
|
+
from qiskit.circuit.controlledgate import ControlledGate
|
19
|
+
from qiskit.circuit.singleton import SingletonGate, SingletonControlledGate, stdlib_singleton_key
|
20
|
+
from qiskit.circuit._utils import _ctrl_state_to_int, with_gate_array, with_controlled_gate_array
|
21
|
+
from qiskit._accelerate.circuit import StandardGate
|
22
|
+
from qiskit.utils.deprecation import deprecate_func
|
23
|
+
|
24
|
+
_X_ARRAY = [[0, 1], [1, 0]]
|
25
|
+
_SX_ARRAY = [[0.5 + 0.5j, 0.5 - 0.5j], [0.5 - 0.5j, 0.5 + 0.5j]]
|
26
|
+
|
27
|
+
|
28
|
+
@with_gate_array(_X_ARRAY)
|
29
|
+
class XGate(SingletonGate):
|
30
|
+
r"""The single-qubit Pauli-X gate (:math:`\sigma_x`).
|
31
|
+
|
32
|
+
Can be applied to a :class:`~qiskit.circuit.QuantumCircuit`
|
33
|
+
with the :meth:`~qiskit.circuit.QuantumCircuit.x` method.
|
34
|
+
|
35
|
+
**Matrix Representation:**
|
36
|
+
|
37
|
+
.. math::
|
38
|
+
|
39
|
+
X = \begin{pmatrix}
|
40
|
+
0 & 1 \\
|
41
|
+
1 & 0
|
42
|
+
\end{pmatrix}
|
43
|
+
|
44
|
+
**Circuit symbol:**
|
45
|
+
|
46
|
+
.. code-block:: text
|
47
|
+
|
48
|
+
┌───┐
|
49
|
+
q_0: ┤ X ├
|
50
|
+
└───┘
|
51
|
+
|
52
|
+
Equivalent to a :math:`\pi` radian rotation about the X axis.
|
53
|
+
|
54
|
+
.. note::
|
55
|
+
|
56
|
+
A global phase difference exists between the definitions of
|
57
|
+
:math:`RX(\pi)` and :math:`X`.
|
58
|
+
|
59
|
+
.. math::
|
60
|
+
|
61
|
+
RX(\pi) = \begin{pmatrix}
|
62
|
+
0 & -i \\
|
63
|
+
-i & 0
|
64
|
+
\end{pmatrix}
|
65
|
+
= -i X
|
66
|
+
|
67
|
+
The gate is equivalent to a classical bit flip.
|
68
|
+
|
69
|
+
.. math::
|
70
|
+
|
71
|
+
|0\rangle \rightarrow |1\rangle \\
|
72
|
+
|1\rangle \rightarrow |0\rangle
|
73
|
+
"""
|
74
|
+
|
75
|
+
_standard_gate = StandardGate.XGate
|
76
|
+
|
77
|
+
def __init__(self, label: Optional[str] = None):
|
78
|
+
"""Create new X gate."""
|
79
|
+
super().__init__("x", 1, [], label=label)
|
80
|
+
|
81
|
+
_singleton_lookup_key = stdlib_singleton_key()
|
82
|
+
|
83
|
+
def _define(self):
|
84
|
+
"""
|
85
|
+
gate x a { u3(pi,0,pi) a; }
|
86
|
+
"""
|
87
|
+
# pylint: disable=cyclic-import
|
88
|
+
from qiskit.circuit import QuantumCircuit, QuantumRegister
|
89
|
+
from .u3 import U3Gate
|
90
|
+
|
91
|
+
q = QuantumRegister(1, "q")
|
92
|
+
qc = QuantumCircuit(q, name=self.name)
|
93
|
+
rules = [(U3Gate(pi, 0, pi), [q[0]], [])]
|
94
|
+
for instr, qargs, cargs in rules:
|
95
|
+
qc._append(instr, qargs, cargs)
|
96
|
+
|
97
|
+
self.definition = qc
|
98
|
+
|
99
|
+
def control(
|
100
|
+
self,
|
101
|
+
num_ctrl_qubits: int = 1,
|
102
|
+
label: Optional[str] = None,
|
103
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
104
|
+
annotated: bool = False,
|
105
|
+
):
|
106
|
+
"""Return a (multi-)controlled-X gate.
|
107
|
+
|
108
|
+
One control returns a CX gate. Two controls returns a CCX gate.
|
109
|
+
|
110
|
+
Args:
|
111
|
+
num_ctrl_qubits: number of control qubits.
|
112
|
+
label: An optional label for the gate [Default: ``None``]
|
113
|
+
ctrl_state: control state expressed as integer,
|
114
|
+
string (e.g. ``'110'``), or ``None``. If ``None``, use all 1s.
|
115
|
+
annotated: indicates whether the controlled gate should be implemented
|
116
|
+
as an annotated gate.
|
117
|
+
|
118
|
+
Returns:
|
119
|
+
ControlledGate: controlled version of this gate.
|
120
|
+
"""
|
121
|
+
if not annotated:
|
122
|
+
gate = MCXGate(
|
123
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
124
|
+
label=label,
|
125
|
+
ctrl_state=ctrl_state,
|
126
|
+
_base_label=self.label,
|
127
|
+
)
|
128
|
+
else:
|
129
|
+
gate = super().control(
|
130
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
131
|
+
label=label,
|
132
|
+
ctrl_state=ctrl_state,
|
133
|
+
annotated=annotated,
|
134
|
+
)
|
135
|
+
return gate
|
136
|
+
|
137
|
+
def inverse(self, annotated: bool = False):
|
138
|
+
r"""Return inverted X gate (itself).
|
139
|
+
|
140
|
+
Args:
|
141
|
+
annotated: when set to ``True``, this is typically used to return an
|
142
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
143
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
144
|
+
is self-inverse.
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
XGate: inverse gate (self-inverse).
|
148
|
+
"""
|
149
|
+
return XGate() # self-inverse
|
150
|
+
|
151
|
+
def __eq__(self, other):
|
152
|
+
return isinstance(other, XGate)
|
153
|
+
|
154
|
+
|
155
|
+
@with_controlled_gate_array(_X_ARRAY, num_ctrl_qubits=1)
|
156
|
+
class CXGate(SingletonControlledGate):
|
157
|
+
r"""Controlled-X gate.
|
158
|
+
|
159
|
+
Can be applied to a :class:`~qiskit.circuit.QuantumCircuit`
|
160
|
+
with the :meth:`~qiskit.circuit.QuantumCircuit.cx` and
|
161
|
+
:meth:`~qiskit.circuit.QuantumCircuit.cnot` methods.
|
162
|
+
|
163
|
+
**Circuit symbol:**
|
164
|
+
|
165
|
+
.. code-block:: text
|
166
|
+
|
167
|
+
q_0: ──■──
|
168
|
+
┌─┴─┐
|
169
|
+
q_1: ┤ X ├
|
170
|
+
└───┘
|
171
|
+
|
172
|
+
**Matrix representation:**
|
173
|
+
|
174
|
+
.. math::
|
175
|
+
|
176
|
+
CX\ q_0, q_1 =
|
177
|
+
I \otimes |0\rangle\langle0| + X \otimes |1\rangle\langle1| =
|
178
|
+
\begin{pmatrix}
|
179
|
+
1 & 0 & 0 & 0 \\
|
180
|
+
0 & 0 & 0 & 1 \\
|
181
|
+
0 & 0 & 1 & 0 \\
|
182
|
+
0 & 1 & 0 & 0
|
183
|
+
\end{pmatrix}
|
184
|
+
|
185
|
+
.. note::
|
186
|
+
|
187
|
+
In Qiskit's convention, higher qubit indices are more significant
|
188
|
+
(little endian convention). In many textbooks, controlled gates are
|
189
|
+
presented with the assumption of more significant qubits as control,
|
190
|
+
which in our case would be q_1. Thus a textbook matrix for this
|
191
|
+
gate will be:
|
192
|
+
|
193
|
+
.. code-block:: text
|
194
|
+
|
195
|
+
┌───┐
|
196
|
+
q_0: ┤ X ├
|
197
|
+
└─┬─┘
|
198
|
+
q_1: ──■──
|
199
|
+
|
200
|
+
.. math::
|
201
|
+
|
202
|
+
CX\ q_1, q_0 =
|
203
|
+
|0 \rangle\langle 0| \otimes I + |1 \rangle\langle 1| \otimes X =
|
204
|
+
\begin{pmatrix}
|
205
|
+
1 & 0 & 0 & 0 \\
|
206
|
+
0 & 1 & 0 & 0 \\
|
207
|
+
0 & 0 & 0 & 1 \\
|
208
|
+
0 & 0 & 1 & 0
|
209
|
+
\end{pmatrix}
|
210
|
+
|
211
|
+
|
212
|
+
In the computational basis, this gate flips the target qubit
|
213
|
+
if the control qubit is in the :math:`|1\rangle` state.
|
214
|
+
In this sense it is similar to a classical XOR gate.
|
215
|
+
|
216
|
+
.. math::
|
217
|
+
`|a, b\rangle \rightarrow |a, a \oplus b\rangle`
|
218
|
+
"""
|
219
|
+
|
220
|
+
_standard_gate = StandardGate.CXGate
|
221
|
+
|
222
|
+
def __init__(
|
223
|
+
self,
|
224
|
+
label: Optional[str] = None,
|
225
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
226
|
+
*,
|
227
|
+
_base_label=None,
|
228
|
+
):
|
229
|
+
"""Create new CX gate."""
|
230
|
+
super().__init__(
|
231
|
+
"cx",
|
232
|
+
2,
|
233
|
+
[],
|
234
|
+
num_ctrl_qubits=1,
|
235
|
+
label=label,
|
236
|
+
ctrl_state=ctrl_state,
|
237
|
+
base_gate=XGate(label=_base_label),
|
238
|
+
_base_label=_base_label,
|
239
|
+
)
|
240
|
+
|
241
|
+
_singleton_lookup_key = stdlib_singleton_key(num_ctrl_qubits=1)
|
242
|
+
|
243
|
+
def control(
|
244
|
+
self,
|
245
|
+
num_ctrl_qubits: int = 1,
|
246
|
+
label: Optional[str] = None,
|
247
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
248
|
+
annotated: bool = False,
|
249
|
+
):
|
250
|
+
"""Return a controlled-X gate with more control lines.
|
251
|
+
|
252
|
+
Args:
|
253
|
+
num_ctrl_qubits: number of control qubits.
|
254
|
+
label: An optional label for the gate [Default: ``None``]
|
255
|
+
ctrl_state: control state expressed as integer,
|
256
|
+
string (e.g. ``'110'``), or ``None``. If ``None``, use all 1s.
|
257
|
+
annotated: indicates whether the controlled gate should be implemented
|
258
|
+
as an annotated gate.
|
259
|
+
|
260
|
+
Returns:
|
261
|
+
ControlledGate: controlled version of this gate.
|
262
|
+
"""
|
263
|
+
if not annotated:
|
264
|
+
ctrl_state = _ctrl_state_to_int(ctrl_state, num_ctrl_qubits)
|
265
|
+
new_ctrl_state = (self.ctrl_state << num_ctrl_qubits) | ctrl_state
|
266
|
+
gate = MCXGate(
|
267
|
+
num_ctrl_qubits=num_ctrl_qubits + 1,
|
268
|
+
label=label,
|
269
|
+
ctrl_state=new_ctrl_state,
|
270
|
+
_base_label=self.label,
|
271
|
+
)
|
272
|
+
else:
|
273
|
+
gate = super().control(
|
274
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
275
|
+
label=label,
|
276
|
+
ctrl_state=ctrl_state,
|
277
|
+
annotated=annotated,
|
278
|
+
)
|
279
|
+
return gate
|
280
|
+
|
281
|
+
def inverse(self, annotated: bool = False):
|
282
|
+
"""Return inverted CX gate (itself).
|
283
|
+
|
284
|
+
Args:
|
285
|
+
annotated: when set to ``True``, this is typically used to return an
|
286
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
287
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
288
|
+
is self-inverse.
|
289
|
+
|
290
|
+
Returns:
|
291
|
+
CXGate: inverse gate (self-inverse).
|
292
|
+
"""
|
293
|
+
return CXGate(ctrl_state=self.ctrl_state) # self-inverse
|
294
|
+
|
295
|
+
def __eq__(self, other):
|
296
|
+
return isinstance(other, CXGate) and self.ctrl_state == other.ctrl_state
|
297
|
+
|
298
|
+
|
299
|
+
@with_controlled_gate_array(_X_ARRAY, num_ctrl_qubits=2, cached_states=(3,))
|
300
|
+
class CCXGate(SingletonControlledGate):
|
301
|
+
r"""CCX gate, also known as Toffoli gate.
|
302
|
+
|
303
|
+
Can be applied to a :class:`~qiskit.circuit.QuantumCircuit`
|
304
|
+
with the :meth:`~qiskit.circuit.QuantumCircuit.ccx` method.
|
305
|
+
|
306
|
+
**Circuit symbol:**
|
307
|
+
|
308
|
+
.. code-block:: text
|
309
|
+
|
310
|
+
q_0: ──■──
|
311
|
+
│
|
312
|
+
q_1: ──■──
|
313
|
+
┌─┴─┐
|
314
|
+
q_2: ┤ X ├
|
315
|
+
└───┘
|
316
|
+
|
317
|
+
**Matrix representation:**
|
318
|
+
|
319
|
+
.. math::
|
320
|
+
|
321
|
+
CCX q_0, q_1, q_2 =
|
322
|
+
I \otimes I \otimes |0 \rangle \langle 0| + CX \otimes |1 \rangle \langle 1| =
|
323
|
+
\begin{pmatrix}
|
324
|
+
1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
|
325
|
+
0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\
|
326
|
+
0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\
|
327
|
+
0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\
|
328
|
+
0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\
|
329
|
+
0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\
|
330
|
+
0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\\
|
331
|
+
0 & 0 & 0 & 1 & 0 & 0 & 0 & 0
|
332
|
+
\end{pmatrix}
|
333
|
+
|
334
|
+
.. note::
|
335
|
+
|
336
|
+
In Qiskit's convention, higher qubit indices are more significant
|
337
|
+
(little endian convention). In many textbooks, controlled gates are
|
338
|
+
presented with the assumption of more significant qubits as control,
|
339
|
+
which in our case would be q_2 and q_1. Thus a textbook matrix for this
|
340
|
+
gate will be:
|
341
|
+
|
342
|
+
.. code-block:: text
|
343
|
+
|
344
|
+
┌───┐
|
345
|
+
q_0: ┤ X ├
|
346
|
+
└─┬─┘
|
347
|
+
q_1: ──■──
|
348
|
+
│
|
349
|
+
q_2: ──■──
|
350
|
+
|
351
|
+
.. math::
|
352
|
+
|
353
|
+
CCX\ q_2, q_1, q_0 =
|
354
|
+
|0 \rangle \langle 0| \otimes I \otimes I + |1 \rangle \langle 1| \otimes CX =
|
355
|
+
\begin{pmatrix}
|
356
|
+
1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
|
357
|
+
0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\
|
358
|
+
0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\
|
359
|
+
0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\
|
360
|
+
0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\
|
361
|
+
0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\
|
362
|
+
0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\
|
363
|
+
0 & 0 & 0 & 0 & 0 & 0 & 1 & 0
|
364
|
+
\end{pmatrix}
|
365
|
+
|
366
|
+
"""
|
367
|
+
|
368
|
+
_standard_gate = StandardGate.CCXGate
|
369
|
+
|
370
|
+
def __init__(
|
371
|
+
self,
|
372
|
+
label: Optional[str] = None,
|
373
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
374
|
+
*,
|
375
|
+
_base_label=None,
|
376
|
+
):
|
377
|
+
"""Create new CCX gate."""
|
378
|
+
super().__init__(
|
379
|
+
"ccx",
|
380
|
+
3,
|
381
|
+
[],
|
382
|
+
num_ctrl_qubits=2,
|
383
|
+
label=label,
|
384
|
+
ctrl_state=ctrl_state,
|
385
|
+
base_gate=XGate(label=_base_label),
|
386
|
+
)
|
387
|
+
|
388
|
+
_singleton_lookup_key = stdlib_singleton_key(num_ctrl_qubits=2)
|
389
|
+
|
390
|
+
def _define(self):
|
391
|
+
"""
|
392
|
+
gate ccx a,b,c
|
393
|
+
{
|
394
|
+
h c; cx b,c; tdg c; cx a,c;
|
395
|
+
t c; cx b,c; tdg c; cx a,c;
|
396
|
+
t b; t c; h c; cx a,b;
|
397
|
+
t a; tdg b; cx a,b;}
|
398
|
+
"""
|
399
|
+
# pylint: disable=cyclic-import
|
400
|
+
from qiskit.circuit import QuantumCircuit, QuantumRegister
|
401
|
+
from .h import HGate
|
402
|
+
from .t import TGate, TdgGate
|
403
|
+
|
404
|
+
# ┌───┐
|
405
|
+
# q_0: ───────────────────■─────────────────────■────■───┤ T ├───■──
|
406
|
+
# │ ┌───┐ │ ┌─┴─┐┌┴───┴┐┌─┴─┐
|
407
|
+
# q_1: ───────■───────────┼─────────■───┤ T ├───┼──┤ X ├┤ Tdg ├┤ X ├
|
408
|
+
# ┌───┐┌─┴─┐┌─────┐┌─┴─┐┌───┐┌─┴─┐┌┴───┴┐┌─┴─┐├───┤└┬───┬┘└───┘
|
409
|
+
# q_2: ┤ H ├┤ X ├┤ Tdg ├┤ X ├┤ T ├┤ X ├┤ Tdg ├┤ X ├┤ T ├─┤ H ├──────
|
410
|
+
# └───┘└───┘└─────┘└───┘└───┘└───┘└─────┘└───┘└───┘ └───┘
|
411
|
+
q = QuantumRegister(3, "q")
|
412
|
+
qc = QuantumCircuit(q, name=self.name)
|
413
|
+
rules = [
|
414
|
+
(HGate(), [q[2]], []),
|
415
|
+
(CXGate(), [q[1], q[2]], []),
|
416
|
+
(TdgGate(), [q[2]], []),
|
417
|
+
(CXGate(), [q[0], q[2]], []),
|
418
|
+
(TGate(), [q[2]], []),
|
419
|
+
(CXGate(), [q[1], q[2]], []),
|
420
|
+
(TdgGate(), [q[2]], []),
|
421
|
+
(CXGate(), [q[0], q[2]], []),
|
422
|
+
(TGate(), [q[1]], []),
|
423
|
+
(TGate(), [q[2]], []),
|
424
|
+
(HGate(), [q[2]], []),
|
425
|
+
(CXGate(), [q[0], q[1]], []),
|
426
|
+
(TGate(), [q[0]], []),
|
427
|
+
(TdgGate(), [q[1]], []),
|
428
|
+
(CXGate(), [q[0], q[1]], []),
|
429
|
+
]
|
430
|
+
for instr, qargs, cargs in rules:
|
431
|
+
qc._append(instr, qargs, cargs)
|
432
|
+
|
433
|
+
self.definition = qc
|
434
|
+
|
435
|
+
def control(
|
436
|
+
self,
|
437
|
+
num_ctrl_qubits: int = 1,
|
438
|
+
label: Optional[str] = None,
|
439
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
440
|
+
annotated: bool = False,
|
441
|
+
):
|
442
|
+
"""Controlled version of this gate.
|
443
|
+
|
444
|
+
Args:
|
445
|
+
num_ctrl_qubits: number of control qubits.
|
446
|
+
label: An optional label for the gate [Default: ``None``]
|
447
|
+
ctrl_state: control state expressed as integer,
|
448
|
+
string (e.g. ``'110'``), or ``None``. If ``None``, use all 1s.
|
449
|
+
annotated: indicates whether the controlled gate should be implemented
|
450
|
+
as an annotated gate.
|
451
|
+
|
452
|
+
Returns:
|
453
|
+
ControlledGate: controlled version of this gate.
|
454
|
+
"""
|
455
|
+
if not annotated:
|
456
|
+
ctrl_state = _ctrl_state_to_int(ctrl_state, num_ctrl_qubits)
|
457
|
+
new_ctrl_state = (self.ctrl_state << num_ctrl_qubits) | ctrl_state
|
458
|
+
gate = MCXGate(
|
459
|
+
num_ctrl_qubits=num_ctrl_qubits + 2,
|
460
|
+
label=label,
|
461
|
+
ctrl_state=new_ctrl_state,
|
462
|
+
_base_label=self.label,
|
463
|
+
)
|
464
|
+
else:
|
465
|
+
gate = super().control(
|
466
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
467
|
+
label=label,
|
468
|
+
ctrl_state=ctrl_state,
|
469
|
+
annotated=annotated,
|
470
|
+
)
|
471
|
+
return gate
|
472
|
+
|
473
|
+
def inverse(self, annotated: bool = False):
|
474
|
+
"""Return an inverted CCX gate (also a CCX).
|
475
|
+
|
476
|
+
Args:
|
477
|
+
annotated: when set to ``True``, this is typically used to return an
|
478
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
479
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
480
|
+
is self-inverse.
|
481
|
+
|
482
|
+
Returns:
|
483
|
+
CCXGate: inverse gate (self-inverse).
|
484
|
+
"""
|
485
|
+
return CCXGate(ctrl_state=self.ctrl_state) # self-inverse
|
486
|
+
|
487
|
+
def __eq__(self, other):
|
488
|
+
return isinstance(other, CCXGate) and self.ctrl_state == other.ctrl_state
|
489
|
+
|
490
|
+
|
491
|
+
@with_gate_array(
|
492
|
+
[
|
493
|
+
[1, 0, 0, 0, 0, 0, 0, 0],
|
494
|
+
[0, 1, 0, 0, 0, 0, 0, 0],
|
495
|
+
[0, 0, 1, 0, 0, 0, 0, 0],
|
496
|
+
[0, 0, 0, 0, 0, 0, 0, -1j],
|
497
|
+
[0, 0, 0, 0, 1, 0, 0, 0],
|
498
|
+
[0, 0, 0, 0, 0, -1, 0, 0],
|
499
|
+
[0, 0, 0, 0, 0, 0, 1, 0],
|
500
|
+
[0, 0, 0, 1j, 0, 0, 0, 0],
|
501
|
+
]
|
502
|
+
)
|
503
|
+
class RCCXGate(SingletonGate):
|
504
|
+
"""The simplified Toffoli gate, also referred to as Margolus gate.
|
505
|
+
|
506
|
+
The simplified Toffoli gate implements the Toffoli gate up to relative phases.
|
507
|
+
This implementation requires three CX gates which is the minimal amount possible,
|
508
|
+
as shown in https://arxiv.org/abs/quant-ph/0312225.
|
509
|
+
Note, that the simplified Toffoli is not equivalent to the Toffoli. But can be used in places
|
510
|
+
where the Toffoli gate is uncomputed again.
|
511
|
+
|
512
|
+
This concrete implementation is from https://arxiv.org/abs/1508.03273, the dashed box
|
513
|
+
of Fig. 3.
|
514
|
+
|
515
|
+
Can be applied to a :class:`~qiskit.circuit.QuantumCircuit`
|
516
|
+
with the :meth:`~qiskit.circuit.QuantumCircuit.rccx` method.
|
517
|
+
"""
|
518
|
+
|
519
|
+
_standard_gate = StandardGate.RCCXGate
|
520
|
+
|
521
|
+
def __init__(self, label: Optional[str] = None):
|
522
|
+
"""Create a new simplified CCX gate."""
|
523
|
+
super().__init__("rccx", 3, [], label=label)
|
524
|
+
|
525
|
+
_singleton_lookup_key = stdlib_singleton_key()
|
526
|
+
|
527
|
+
def _define(self):
|
528
|
+
"""
|
529
|
+
gate rccx a,b,c
|
530
|
+
{ u2(0,pi) c;
|
531
|
+
u1(pi/4) c;
|
532
|
+
cx b, c;
|
533
|
+
u1(-pi/4) c;
|
534
|
+
cx a, c;
|
535
|
+
u1(pi/4) c;
|
536
|
+
cx b, c;
|
537
|
+
u1(-pi/4) c;
|
538
|
+
u2(0,pi) c;
|
539
|
+
}
|
540
|
+
"""
|
541
|
+
# pylint: disable=cyclic-import
|
542
|
+
from qiskit.circuit import QuantumCircuit, QuantumRegister
|
543
|
+
from .u1 import U1Gate
|
544
|
+
from .u2 import U2Gate
|
545
|
+
|
546
|
+
q = QuantumRegister(3, "q")
|
547
|
+
qc = QuantumCircuit(q, name=self.name)
|
548
|
+
rules = [
|
549
|
+
(U2Gate(0, pi), [q[2]], []), # H gate
|
550
|
+
(U1Gate(pi / 4), [q[2]], []), # T gate
|
551
|
+
(CXGate(), [q[1], q[2]], []),
|
552
|
+
(U1Gate(-pi / 4), [q[2]], []), # inverse T gate
|
553
|
+
(CXGate(), [q[0], q[2]], []),
|
554
|
+
(U1Gate(pi / 4), [q[2]], []),
|
555
|
+
(CXGate(), [q[1], q[2]], []),
|
556
|
+
(U1Gate(-pi / 4), [q[2]], []), # inverse T gate
|
557
|
+
(U2Gate(0, pi), [q[2]], []), # H gate
|
558
|
+
]
|
559
|
+
for instr, qargs, cargs in rules:
|
560
|
+
qc._append(instr, qargs, cargs)
|
561
|
+
|
562
|
+
self.definition = qc
|
563
|
+
|
564
|
+
def __eq__(self, other):
|
565
|
+
return isinstance(other, RCCXGate)
|
566
|
+
|
567
|
+
|
568
|
+
@with_controlled_gate_array(_SX_ARRAY, num_ctrl_qubits=3, cached_states=(7,))
|
569
|
+
class C3SXGate(SingletonControlledGate):
|
570
|
+
"""The 3-qubit controlled sqrt-X gate.
|
571
|
+
|
572
|
+
This implementation is based on Page 17 of [1].
|
573
|
+
|
574
|
+
References:
|
575
|
+
[1] Barenco et al., 1995. https://arxiv.org/pdf/quant-ph/9503016.pdf
|
576
|
+
"""
|
577
|
+
|
578
|
+
_standard_gate = StandardGate.C3SXGate
|
579
|
+
|
580
|
+
def __init__(
|
581
|
+
self,
|
582
|
+
label: Optional[str] = None,
|
583
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
584
|
+
*,
|
585
|
+
_base_label=None,
|
586
|
+
):
|
587
|
+
"""Create a new 3-qubit controlled sqrt-X gate.
|
588
|
+
|
589
|
+
Args:
|
590
|
+
label: An optional label for the gate [Default: ``None``]
|
591
|
+
ctrl_state: control state expressed as integer,
|
592
|
+
string (e.g. ``'110'``), or ``None``. If ``None``, use all 1s.
|
593
|
+
"""
|
594
|
+
from .sx import SXGate
|
595
|
+
|
596
|
+
super().__init__(
|
597
|
+
"c3sx",
|
598
|
+
4,
|
599
|
+
[],
|
600
|
+
num_ctrl_qubits=3,
|
601
|
+
label=label,
|
602
|
+
ctrl_state=ctrl_state,
|
603
|
+
base_gate=SXGate(label=_base_label),
|
604
|
+
)
|
605
|
+
|
606
|
+
_singleton_lookup_key = stdlib_singleton_key(num_ctrl_qubits=3)
|
607
|
+
|
608
|
+
def _define(self):
|
609
|
+
"""
|
610
|
+
gate c3sqrtx a,b,c,d
|
611
|
+
{
|
612
|
+
h d; cu1(pi/8) a,d; h d;
|
613
|
+
cx a,b;
|
614
|
+
h d; cu1(-pi/8) b,d; h d;
|
615
|
+
cx a,b;
|
616
|
+
h d; cu1(pi/8) b,d; h d;
|
617
|
+
cx b,c;
|
618
|
+
h d; cu1(-pi/8) c,d; h d;
|
619
|
+
cx a,c;
|
620
|
+
h d; cu1(pi/8) c,d; h d;
|
621
|
+
cx b,c;
|
622
|
+
h d; cu1(-pi/8) c,d; h d;
|
623
|
+
cx a,c;
|
624
|
+
h d; cu1(pi/8) c,d; h d;
|
625
|
+
}
|
626
|
+
"""
|
627
|
+
# pylint: disable=cyclic-import
|
628
|
+
from qiskit.circuit import QuantumCircuit, QuantumRegister
|
629
|
+
from .u1 import CU1Gate
|
630
|
+
from .h import HGate
|
631
|
+
|
632
|
+
angle = numpy.pi / 8
|
633
|
+
q = QuantumRegister(4, name="q")
|
634
|
+
rules = [
|
635
|
+
(HGate(), [q[3]], []),
|
636
|
+
(CU1Gate(angle), [q[0], q[3]], []),
|
637
|
+
(HGate(), [q[3]], []),
|
638
|
+
(CXGate(), [q[0], q[1]], []),
|
639
|
+
(HGate(), [q[3]], []),
|
640
|
+
(CU1Gate(-angle), [q[1], q[3]], []),
|
641
|
+
(HGate(), [q[3]], []),
|
642
|
+
(CXGate(), [q[0], q[1]], []),
|
643
|
+
(HGate(), [q[3]], []),
|
644
|
+
(CU1Gate(angle), [q[1], q[3]], []),
|
645
|
+
(HGate(), [q[3]], []),
|
646
|
+
(CXGate(), [q[1], q[2]], []),
|
647
|
+
(HGate(), [q[3]], []),
|
648
|
+
(CU1Gate(-angle), [q[2], q[3]], []),
|
649
|
+
(HGate(), [q[3]], []),
|
650
|
+
(CXGate(), [q[0], q[2]], []),
|
651
|
+
(HGate(), [q[3]], []),
|
652
|
+
(CU1Gate(angle), [q[2], q[3]], []),
|
653
|
+
(HGate(), [q[3]], []),
|
654
|
+
(CXGate(), [q[1], q[2]], []),
|
655
|
+
(HGate(), [q[3]], []),
|
656
|
+
(CU1Gate(-angle), [q[2], q[3]], []),
|
657
|
+
(HGate(), [q[3]], []),
|
658
|
+
(CXGate(), [q[0], q[2]], []),
|
659
|
+
(HGate(), [q[3]], []),
|
660
|
+
(CU1Gate(angle), [q[2], q[3]], []),
|
661
|
+
(HGate(), [q[3]], []),
|
662
|
+
]
|
663
|
+
qc = QuantumCircuit(q)
|
664
|
+
for instr, qargs, cargs in rules:
|
665
|
+
qc._append(instr, qargs, cargs)
|
666
|
+
|
667
|
+
self.definition = qc
|
668
|
+
|
669
|
+
def __eq__(self, other):
|
670
|
+
return isinstance(other, C3SXGate) and self.ctrl_state == other.ctrl_state
|
671
|
+
|
672
|
+
|
673
|
+
@with_controlled_gate_array(_X_ARRAY, num_ctrl_qubits=3, cached_states=(7,))
|
674
|
+
class C3XGate(SingletonControlledGate):
|
675
|
+
r"""The X gate controlled on 3 qubits.
|
676
|
+
|
677
|
+
This implementation uses :math:`\sqrt{T}` and 14 CNOT gates.
|
678
|
+
"""
|
679
|
+
|
680
|
+
_standard_gate = StandardGate.C3XGate
|
681
|
+
|
682
|
+
def __init__(
|
683
|
+
self,
|
684
|
+
label: Optional[str] = None,
|
685
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
686
|
+
*,
|
687
|
+
_base_label=None,
|
688
|
+
):
|
689
|
+
"""Create a new 3-qubit controlled X gate."""
|
690
|
+
super().__init__(
|
691
|
+
"mcx",
|
692
|
+
4,
|
693
|
+
[],
|
694
|
+
num_ctrl_qubits=3,
|
695
|
+
label=label,
|
696
|
+
ctrl_state=ctrl_state,
|
697
|
+
base_gate=XGate(label=_base_label),
|
698
|
+
)
|
699
|
+
|
700
|
+
_singleton_lookup_key = stdlib_singleton_key(num_ctrl_qubits=3)
|
701
|
+
|
702
|
+
# seems like open controls not happening?
|
703
|
+
def _define(self):
|
704
|
+
"""
|
705
|
+
gate c3x a,b,c,d
|
706
|
+
{
|
707
|
+
h d;
|
708
|
+
p(pi/8) a;
|
709
|
+
p(pi/8) b;
|
710
|
+
p(pi/8) c;
|
711
|
+
p(pi/8) d;
|
712
|
+
cx a, b;
|
713
|
+
p(-pi/8) b;
|
714
|
+
cx a, b;
|
715
|
+
cx b, c;
|
716
|
+
p(-pi/8) c;
|
717
|
+
cx a, c;
|
718
|
+
p(pi/8) c;
|
719
|
+
cx b, c;
|
720
|
+
p(-pi/8) c;
|
721
|
+
cx a, c;
|
722
|
+
cx c, d;
|
723
|
+
p(-pi/8) d;
|
724
|
+
cx b, d;
|
725
|
+
p(pi/8) d;
|
726
|
+
cx c, d;
|
727
|
+
p(-pi/8) d;
|
728
|
+
cx a, d;
|
729
|
+
p(pi/8) d;
|
730
|
+
cx c, d;
|
731
|
+
p(-pi/8) d;
|
732
|
+
cx b, d;
|
733
|
+
p(pi/8) d;
|
734
|
+
cx c, d;
|
735
|
+
p(-pi/8) d;
|
736
|
+
cx a, d;
|
737
|
+
h d;
|
738
|
+
}
|
739
|
+
"""
|
740
|
+
from qiskit.circuit import QuantumCircuit, QuantumRegister
|
741
|
+
|
742
|
+
q = QuantumRegister(4, name="q")
|
743
|
+
qc = QuantumCircuit(q, name=self.name)
|
744
|
+
qc.h(3)
|
745
|
+
qc.p(pi / 8, [0, 1, 2, 3])
|
746
|
+
qc.cx(0, 1)
|
747
|
+
qc.p(-pi / 8, 1)
|
748
|
+
qc.cx(0, 1)
|
749
|
+
qc.cx(1, 2)
|
750
|
+
qc.p(-pi / 8, 2)
|
751
|
+
qc.cx(0, 2)
|
752
|
+
qc.p(pi / 8, 2)
|
753
|
+
qc.cx(1, 2)
|
754
|
+
qc.p(-pi / 8, 2)
|
755
|
+
qc.cx(0, 2)
|
756
|
+
qc.cx(2, 3)
|
757
|
+
qc.p(-pi / 8, 3)
|
758
|
+
qc.cx(1, 3)
|
759
|
+
qc.p(pi / 8, 3)
|
760
|
+
qc.cx(2, 3)
|
761
|
+
qc.p(-pi / 8, 3)
|
762
|
+
qc.cx(0, 3)
|
763
|
+
qc.p(pi / 8, 3)
|
764
|
+
qc.cx(2, 3)
|
765
|
+
qc.p(-pi / 8, 3)
|
766
|
+
qc.cx(1, 3)
|
767
|
+
qc.p(pi / 8, 3)
|
768
|
+
qc.cx(2, 3)
|
769
|
+
qc.p(-pi / 8, 3)
|
770
|
+
qc.cx(0, 3)
|
771
|
+
qc.h(3)
|
772
|
+
|
773
|
+
self.definition = qc
|
774
|
+
|
775
|
+
def control(
|
776
|
+
self,
|
777
|
+
num_ctrl_qubits: int = 1,
|
778
|
+
label: Optional[str] = None,
|
779
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
780
|
+
annotated: bool = False,
|
781
|
+
):
|
782
|
+
"""Controlled version of this gate.
|
783
|
+
|
784
|
+
Args:
|
785
|
+
num_ctrl_qubits: number of control qubits.
|
786
|
+
label: An optional label for the gate [Default: ``None``]
|
787
|
+
ctrl_state: control state expressed as integer,
|
788
|
+
string (e.g. ``'110'``), or ``None``. If ``None``, use all 1s.
|
789
|
+
annotated: indicates whether the controlled gate should be implemented
|
790
|
+
as an annotated gate.
|
791
|
+
|
792
|
+
Returns:
|
793
|
+
ControlledGate: controlled version of this gate.
|
794
|
+
"""
|
795
|
+
if not annotated:
|
796
|
+
ctrl_state = _ctrl_state_to_int(ctrl_state, num_ctrl_qubits)
|
797
|
+
new_ctrl_state = (self.ctrl_state << num_ctrl_qubits) | ctrl_state
|
798
|
+
gate = MCXGate(
|
799
|
+
num_ctrl_qubits=num_ctrl_qubits + 3,
|
800
|
+
label=label,
|
801
|
+
ctrl_state=new_ctrl_state,
|
802
|
+
_base_label=self.label,
|
803
|
+
)
|
804
|
+
else:
|
805
|
+
gate = super().control(
|
806
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
807
|
+
label=label,
|
808
|
+
ctrl_state=ctrl_state,
|
809
|
+
annotated=annotated,
|
810
|
+
)
|
811
|
+
return gate
|
812
|
+
|
813
|
+
def inverse(self, annotated: bool = False):
|
814
|
+
"""Invert this gate. The C3X is its own inverse.
|
815
|
+
|
816
|
+
Args:
|
817
|
+
annotated: when set to ``True``, this is typically used to return an
|
818
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
819
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
820
|
+
is self-inverse.
|
821
|
+
|
822
|
+
Returns:
|
823
|
+
C3XGate: inverse gate (self-inverse).
|
824
|
+
"""
|
825
|
+
return C3XGate(ctrl_state=self.ctrl_state)
|
826
|
+
|
827
|
+
def __eq__(self, other):
|
828
|
+
return isinstance(other, C3XGate) and self.ctrl_state == other.ctrl_state
|
829
|
+
|
830
|
+
|
831
|
+
@with_gate_array(
|
832
|
+
[
|
833
|
+
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
834
|
+
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
835
|
+
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
836
|
+
[0, 0, 0, 1j, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
837
|
+
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
838
|
+
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
839
|
+
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
840
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
841
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
|
842
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
|
843
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
|
844
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1j, 0, 0, 0, 0],
|
845
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
|
846
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
|
847
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
|
848
|
+
[0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0],
|
849
|
+
]
|
850
|
+
)
|
851
|
+
class RC3XGate(SingletonGate):
|
852
|
+
"""The simplified 3-controlled Toffoli gate.
|
853
|
+
|
854
|
+
The simplified Toffoli gate implements the Toffoli gate up to relative phases.
|
855
|
+
Note, that the simplified Toffoli is not equivalent to the Toffoli. But can be used in places
|
856
|
+
where the Toffoli gate is uncomputed again.
|
857
|
+
|
858
|
+
This concrete implementation is from https://arxiv.org/abs/1508.03273, the complete circuit
|
859
|
+
of Fig. 4.
|
860
|
+
|
861
|
+
Can be applied to a :class:`~qiskit.circuit.QuantumCircuit`
|
862
|
+
with the :meth:`~qiskit.circuit.QuantumCircuit.rcccx` method.
|
863
|
+
"""
|
864
|
+
|
865
|
+
_standard_gate = StandardGate.RC3XGate
|
866
|
+
|
867
|
+
def __init__(self, label: Optional[str] = None):
|
868
|
+
"""Create a new RC3X gate."""
|
869
|
+
super().__init__("rcccx", 4, [], label=label)
|
870
|
+
|
871
|
+
_singleton_lookup_key = stdlib_singleton_key()
|
872
|
+
|
873
|
+
def _define(self):
|
874
|
+
"""
|
875
|
+
gate rc3x a,b,c,d
|
876
|
+
{ u2(0,pi) d;
|
877
|
+
u1(pi/4) d;
|
878
|
+
cx c,d;
|
879
|
+
u1(-pi/4) d;
|
880
|
+
u2(0,pi) d;
|
881
|
+
cx a,d;
|
882
|
+
u1(pi/4) d;
|
883
|
+
cx b,d;
|
884
|
+
u1(-pi/4) d;
|
885
|
+
cx a,d;
|
886
|
+
u1(pi/4) d;
|
887
|
+
cx b,d;
|
888
|
+
u1(-pi/4) d;
|
889
|
+
u2(0,pi) d;
|
890
|
+
u1(pi/4) d;
|
891
|
+
cx c,d;
|
892
|
+
u1(-pi/4) d;
|
893
|
+
u2(0,pi) d;
|
894
|
+
}
|
895
|
+
"""
|
896
|
+
# pylint: disable=cyclic-import
|
897
|
+
from qiskit.circuit import QuantumCircuit, QuantumRegister
|
898
|
+
from .u1 import U1Gate
|
899
|
+
from .u2 import U2Gate
|
900
|
+
|
901
|
+
q = QuantumRegister(4, "q")
|
902
|
+
qc = QuantumCircuit(q, name=self.name)
|
903
|
+
rules = [
|
904
|
+
(U2Gate(0, pi), [q[3]], []), # H gate
|
905
|
+
(U1Gate(pi / 4), [q[3]], []), # T gate
|
906
|
+
(CXGate(), [q[2], q[3]], []),
|
907
|
+
(U1Gate(-pi / 4), [q[3]], []), # inverse T gate
|
908
|
+
(U2Gate(0, pi), [q[3]], []),
|
909
|
+
(CXGate(), [q[0], q[3]], []),
|
910
|
+
(U1Gate(pi / 4), [q[3]], []),
|
911
|
+
(CXGate(), [q[1], q[3]], []),
|
912
|
+
(U1Gate(-pi / 4), [q[3]], []),
|
913
|
+
(CXGate(), [q[0], q[3]], []),
|
914
|
+
(U1Gate(pi / 4), [q[3]], []),
|
915
|
+
(CXGate(), [q[1], q[3]], []),
|
916
|
+
(U1Gate(-pi / 4), [q[3]], []),
|
917
|
+
(U2Gate(0, pi), [q[3]], []),
|
918
|
+
(U1Gate(pi / 4), [q[3]], []),
|
919
|
+
(CXGate(), [q[2], q[3]], []),
|
920
|
+
(U1Gate(-pi / 4), [q[3]], []),
|
921
|
+
(U2Gate(0, pi), [q[3]], []),
|
922
|
+
]
|
923
|
+
for instr, qargs, cargs in rules:
|
924
|
+
qc._append(instr, qargs, cargs)
|
925
|
+
|
926
|
+
self.definition = qc
|
927
|
+
|
928
|
+
def __eq__(self, other):
|
929
|
+
return isinstance(other, RC3XGate)
|
930
|
+
|
931
|
+
|
932
|
+
@with_controlled_gate_array(_X_ARRAY, num_ctrl_qubits=4, cached_states=(15,))
|
933
|
+
class C4XGate(SingletonControlledGate):
|
934
|
+
"""The 4-qubit controlled X gate.
|
935
|
+
|
936
|
+
This implementation is based on Page 21, Lemma 7.5, of [1], with the use
|
937
|
+
of the relative phase version of c3x, the rc3x [2].
|
938
|
+
|
939
|
+
References:
|
940
|
+
1. Barenco et al., 1995. https://arxiv.org/pdf/quant-ph/9503016.pdf
|
941
|
+
2. Maslov, 2015. https://arxiv.org/abs/1508.03273
|
942
|
+
"""
|
943
|
+
|
944
|
+
def __init__(
|
945
|
+
self,
|
946
|
+
label: Optional[str] = None,
|
947
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
948
|
+
*,
|
949
|
+
_base_label=None,
|
950
|
+
):
|
951
|
+
"""Create a new 4-qubit controlled X gate."""
|
952
|
+
super().__init__(
|
953
|
+
"mcx",
|
954
|
+
5,
|
955
|
+
[],
|
956
|
+
num_ctrl_qubits=4,
|
957
|
+
label=label,
|
958
|
+
ctrl_state=ctrl_state,
|
959
|
+
base_gate=XGate(label=_base_label),
|
960
|
+
)
|
961
|
+
|
962
|
+
_singleton_lookup_key = stdlib_singleton_key(num_ctrl_qubits=4)
|
963
|
+
|
964
|
+
# seems like open controls not happening?
|
965
|
+
def _define(self):
|
966
|
+
"""
|
967
|
+
gate c3sqrtx a,b,c,d
|
968
|
+
{
|
969
|
+
h d; cu1(pi/8) a,d; h d;
|
970
|
+
cx a,b;
|
971
|
+
h d; cu1(-pi/8) b,d; h d;
|
972
|
+
cx a,b;
|
973
|
+
h d; cu1(pi/8) b,d; h d;
|
974
|
+
cx b,c;
|
975
|
+
h d; cu1(-pi/8) c,d; h d;
|
976
|
+
cx a,c;
|
977
|
+
h d; cu1(pi/8) c,d; h d;
|
978
|
+
cx b,c;
|
979
|
+
h d; cu1(-pi/8) c,d; h d;
|
980
|
+
cx a,c;
|
981
|
+
h d; cu1(pi/8) c,d; h d;
|
982
|
+
}
|
983
|
+
gate c4x a,b,c,d,e
|
984
|
+
{
|
985
|
+
h e; cu1(pi/2) d,e; h e;
|
986
|
+
rc3x a,b,c,d;
|
987
|
+
h e; cu1(-pi/2) d,e; h e;
|
988
|
+
rc3x a,b,c,d;
|
989
|
+
c3sqrtx a,b,c,e;
|
990
|
+
}
|
991
|
+
"""
|
992
|
+
# pylint: disable=cyclic-import
|
993
|
+
from qiskit.circuit import QuantumCircuit, QuantumRegister
|
994
|
+
from .u1 import CU1Gate
|
995
|
+
from .h import HGate
|
996
|
+
|
997
|
+
q = QuantumRegister(5, name="q")
|
998
|
+
qc = QuantumCircuit(q, name=self.name)
|
999
|
+
rules = [
|
1000
|
+
(HGate(), [q[4]], []),
|
1001
|
+
(CU1Gate(numpy.pi / 2), [q[3], q[4]], []),
|
1002
|
+
(HGate(), [q[4]], []),
|
1003
|
+
(RC3XGate(), [q[0], q[1], q[2], q[3]], []),
|
1004
|
+
(HGate(), [q[4]], []),
|
1005
|
+
(CU1Gate(-numpy.pi / 2), [q[3], q[4]], []),
|
1006
|
+
(HGate(), [q[4]], []),
|
1007
|
+
(RC3XGate().inverse(), [q[0], q[1], q[2], q[3]], []),
|
1008
|
+
(C3SXGate(), [q[0], q[1], q[2], q[4]], []),
|
1009
|
+
]
|
1010
|
+
for instr, qargs, cargs in rules:
|
1011
|
+
qc._append(instr, qargs, cargs)
|
1012
|
+
|
1013
|
+
self.definition = qc
|
1014
|
+
|
1015
|
+
def control(
|
1016
|
+
self,
|
1017
|
+
num_ctrl_qubits: int = 1,
|
1018
|
+
label: Optional[str] = None,
|
1019
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1020
|
+
annotated: bool = False,
|
1021
|
+
):
|
1022
|
+
"""Controlled version of this gate.
|
1023
|
+
|
1024
|
+
Args:
|
1025
|
+
num_ctrl_qubits: number of control qubits.
|
1026
|
+
label: An optional label for the gate [Default: ``None``]
|
1027
|
+
ctrl_state: control state expressed as integer,
|
1028
|
+
string (e.g. ``'110'``), or ``None``. If ``None``, use all 1s.
|
1029
|
+
annotated: indicates whether the controlled gate should be implemented
|
1030
|
+
as an annotated gate.
|
1031
|
+
|
1032
|
+
Returns:
|
1033
|
+
ControlledGate: controlled version of this gate.
|
1034
|
+
"""
|
1035
|
+
if not annotated:
|
1036
|
+
ctrl_state = _ctrl_state_to_int(ctrl_state, num_ctrl_qubits)
|
1037
|
+
new_ctrl_state = (self.ctrl_state << num_ctrl_qubits) | ctrl_state
|
1038
|
+
gate = MCXGate(
|
1039
|
+
num_ctrl_qubits=num_ctrl_qubits + 4,
|
1040
|
+
label=label,
|
1041
|
+
ctrl_state=new_ctrl_state,
|
1042
|
+
_base_label=self.label,
|
1043
|
+
)
|
1044
|
+
else:
|
1045
|
+
gate = super().control(
|
1046
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
1047
|
+
label=label,
|
1048
|
+
ctrl_state=ctrl_state,
|
1049
|
+
annotated=annotated,
|
1050
|
+
)
|
1051
|
+
return gate
|
1052
|
+
|
1053
|
+
def inverse(self, annotated: bool = False):
|
1054
|
+
"""Invert this gate. The C4X is its own inverse.
|
1055
|
+
|
1056
|
+
Args:
|
1057
|
+
annotated: when set to ``True``, this is typically used to return an
|
1058
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
1059
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
1060
|
+
is self-inverse.
|
1061
|
+
|
1062
|
+
Returns:
|
1063
|
+
C4XGate: inverse gate (self-inverse).
|
1064
|
+
"""
|
1065
|
+
return C4XGate(ctrl_state=self.ctrl_state)
|
1066
|
+
|
1067
|
+
def __eq__(self, other):
|
1068
|
+
return isinstance(other, C4XGate) and self.ctrl_state == other.ctrl_state
|
1069
|
+
|
1070
|
+
|
1071
|
+
class MCXGate(ControlledGate):
|
1072
|
+
"""The general, multi-controlled X gate.
|
1073
|
+
|
1074
|
+
Can be applied to a :class:`~qiskit.circuit.QuantumCircuit`
|
1075
|
+
with the :meth:`~qiskit.circuit.QuantumCircuit.mcx` method.
|
1076
|
+
"""
|
1077
|
+
|
1078
|
+
def __new__(
|
1079
|
+
cls,
|
1080
|
+
num_ctrl_qubits: Optional[int] = None,
|
1081
|
+
label: Optional[str] = None,
|
1082
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1083
|
+
*,
|
1084
|
+
_base_label=None,
|
1085
|
+
):
|
1086
|
+
"""Create a new MCX instance.
|
1087
|
+
|
1088
|
+
Depending on the number of controls and which mode of the MCX, this creates an
|
1089
|
+
explicit CX, CCX, C3X or C4X instance or a generic MCX gate.
|
1090
|
+
"""
|
1091
|
+
# The CXGate and CCXGate will be implemented for all modes of the MCX, and
|
1092
|
+
# the C3XGate and C4XGate are handled in the gate definition.
|
1093
|
+
explicit: dict[int, Type[ControlledGate]] = {1: CXGate, 2: CCXGate}
|
1094
|
+
gate_class = explicit.get(num_ctrl_qubits, None)
|
1095
|
+
if gate_class is not None:
|
1096
|
+
gate = gate_class.__new__(
|
1097
|
+
gate_class, label=label, ctrl_state=ctrl_state, _base_label=_base_label
|
1098
|
+
)
|
1099
|
+
# if __new__ does not return the same type as cls, init is not called
|
1100
|
+
gate.__init__(
|
1101
|
+
label=label,
|
1102
|
+
ctrl_state=ctrl_state,
|
1103
|
+
_base_label=_base_label,
|
1104
|
+
)
|
1105
|
+
return gate
|
1106
|
+
return super().__new__(cls)
|
1107
|
+
|
1108
|
+
def __init__(
|
1109
|
+
self,
|
1110
|
+
num_ctrl_qubits: int,
|
1111
|
+
label: Optional[str] = None,
|
1112
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1113
|
+
*,
|
1114
|
+
_name="mcx",
|
1115
|
+
_base_label=None,
|
1116
|
+
):
|
1117
|
+
"""Create new MCX gate."""
|
1118
|
+
num_ancilla_qubits = self.__class__.get_num_ancilla_qubits(num_ctrl_qubits)
|
1119
|
+
super().__init__(
|
1120
|
+
_name,
|
1121
|
+
num_ctrl_qubits + 1 + num_ancilla_qubits,
|
1122
|
+
[],
|
1123
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
1124
|
+
label=label,
|
1125
|
+
ctrl_state=ctrl_state,
|
1126
|
+
base_gate=XGate(label=_base_label),
|
1127
|
+
)
|
1128
|
+
|
1129
|
+
def inverse(self, annotated: bool = False):
|
1130
|
+
"""Invert this gate. The MCX is its own inverse.
|
1131
|
+
|
1132
|
+
Args:
|
1133
|
+
annotated: when set to ``True``, this is typically used to return an
|
1134
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
1135
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
1136
|
+
is self-inverse.
|
1137
|
+
|
1138
|
+
Returns:
|
1139
|
+
MCXGate: inverse gate (self-inverse).
|
1140
|
+
"""
|
1141
|
+
return MCXGate(num_ctrl_qubits=self.num_ctrl_qubits, ctrl_state=self.ctrl_state)
|
1142
|
+
|
1143
|
+
@staticmethod
|
1144
|
+
@deprecate_func(
|
1145
|
+
additional_msg=(
|
1146
|
+
"For an MCXGate it is no longer possible to know the number of ancilla qubits "
|
1147
|
+
"that would be eventually used by the transpiler when the gate is created. "
|
1148
|
+
"Instead, it is recommended to use MCXGate and let HighLevelSynthesis choose "
|
1149
|
+
"the best synthesis method depending on the number of ancilla qubits available. "
|
1150
|
+
"However, if a specific synthesis method using a specific number of ancilla "
|
1151
|
+
"qubits is require, one can create a custom gate by calling the corresponding "
|
1152
|
+
"synthesis function directly."
|
1153
|
+
),
|
1154
|
+
since="1.3",
|
1155
|
+
pending=True,
|
1156
|
+
)
|
1157
|
+
def get_num_ancilla_qubits(num_ctrl_qubits: int, mode: str = "noancilla") -> int:
|
1158
|
+
"""Get the number of required ancilla qubits without instantiating the class.
|
1159
|
+
|
1160
|
+
This staticmethod might be necessary to check the number of ancillas before
|
1161
|
+
creating the gate, or to use the number of ancillas in the initialization.
|
1162
|
+
"""
|
1163
|
+
if mode == "noancilla":
|
1164
|
+
return 0
|
1165
|
+
if mode in ["recursion", "advanced"]:
|
1166
|
+
return int(num_ctrl_qubits > 4)
|
1167
|
+
if mode[:7] == "v-chain" or mode[:5] == "basic":
|
1168
|
+
return max(0, num_ctrl_qubits - 2)
|
1169
|
+
raise AttributeError(f"Unsupported mode ({mode}) specified!")
|
1170
|
+
|
1171
|
+
def _define(self):
|
1172
|
+
"""This definition is based on MCPhaseGate implementation."""
|
1173
|
+
# pylint: disable=cyclic-import
|
1174
|
+
from qiskit.synthesis.multi_controlled import synth_mcx_noaux_v24
|
1175
|
+
|
1176
|
+
qc = synth_mcx_noaux_v24(self.num_ctrl_qubits)
|
1177
|
+
self.definition = qc
|
1178
|
+
|
1179
|
+
@property
|
1180
|
+
def num_ancilla_qubits(self):
|
1181
|
+
"""The number of ancilla qubits."""
|
1182
|
+
return self.__class__.get_num_ancilla_qubits(self.num_ctrl_qubits)
|
1183
|
+
|
1184
|
+
def control(
|
1185
|
+
self,
|
1186
|
+
num_ctrl_qubits: int = 1,
|
1187
|
+
label: Optional[str] = None,
|
1188
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1189
|
+
annotated: bool = False,
|
1190
|
+
):
|
1191
|
+
"""Return a multi-controlled-X gate with more control lines.
|
1192
|
+
|
1193
|
+
Args:
|
1194
|
+
num_ctrl_qubits: number of control qubits.
|
1195
|
+
label: An optional label for the gate [Default: ``None``]
|
1196
|
+
ctrl_state: control state expressed as integer,
|
1197
|
+
string (e.g. ``'110'``), or ``None``. If ``None``, use all 1s.
|
1198
|
+
annotated: indicates whether the controlled gate should be implemented
|
1199
|
+
as an annotated gate.
|
1200
|
+
|
1201
|
+
Returns:
|
1202
|
+
ControlledGate: controlled version of this gate.
|
1203
|
+
"""
|
1204
|
+
if not annotated and ctrl_state is None:
|
1205
|
+
# use __class__ so this works for derived classes
|
1206
|
+
gate = self.__class__(
|
1207
|
+
self.num_ctrl_qubits + num_ctrl_qubits,
|
1208
|
+
label=label,
|
1209
|
+
ctrl_state=ctrl_state,
|
1210
|
+
_base_label=self.label,
|
1211
|
+
)
|
1212
|
+
else:
|
1213
|
+
gate = super().control(num_ctrl_qubits, label=label, ctrl_state=ctrl_state)
|
1214
|
+
return gate
|
1215
|
+
|
1216
|
+
|
1217
|
+
class MCXGrayCode(MCXGate):
|
1218
|
+
r"""Implement the multi-controlled X gate using the Gray code.
|
1219
|
+
|
1220
|
+
This delegates the implementation to the MCU1 gate, since :math:`X = H \cdot U1(\pi) \cdot H`.
|
1221
|
+
"""
|
1222
|
+
|
1223
|
+
def __new__(
|
1224
|
+
cls,
|
1225
|
+
num_ctrl_qubits: Optional[int] = None,
|
1226
|
+
label: Optional[str] = None,
|
1227
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1228
|
+
*,
|
1229
|
+
_base_label=None,
|
1230
|
+
):
|
1231
|
+
"""Create a new MCXGrayCode instance"""
|
1232
|
+
# if 1 to 4 control qubits, create explicit gates
|
1233
|
+
explicit = {1: CXGate, 2: CCXGate, 3: C3XGate, 4: C4XGate}
|
1234
|
+
gate_class = explicit.get(num_ctrl_qubits, None)
|
1235
|
+
if gate_class is not None:
|
1236
|
+
gate = gate_class.__new__(
|
1237
|
+
gate_class,
|
1238
|
+
label=label,
|
1239
|
+
ctrl_state=ctrl_state,
|
1240
|
+
_base_label=_base_label,
|
1241
|
+
)
|
1242
|
+
# if __new__ does not return the same type as cls, init is not called
|
1243
|
+
gate.__init__(
|
1244
|
+
label=label,
|
1245
|
+
ctrl_state=ctrl_state,
|
1246
|
+
)
|
1247
|
+
return gate
|
1248
|
+
return super().__new__(cls)
|
1249
|
+
|
1250
|
+
@deprecate_func(
|
1251
|
+
additional_msg=(
|
1252
|
+
"It is recommended to use MCXGate and let HighLevelSynthesis choose "
|
1253
|
+
"the best synthesis method depending on the number of ancilla qubits available. "
|
1254
|
+
"If this specific synthesis method is required, one can specify it using the "
|
1255
|
+
"high-level-synthesis plugin `gray_code` for MCX gates, or, alternatively, "
|
1256
|
+
"one can use synth_mcx_gray_code to construct the gate directly."
|
1257
|
+
),
|
1258
|
+
since="1.3",
|
1259
|
+
pending=True,
|
1260
|
+
)
|
1261
|
+
def __init__(
|
1262
|
+
self,
|
1263
|
+
num_ctrl_qubits: int,
|
1264
|
+
label: Optional[str] = None,
|
1265
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1266
|
+
):
|
1267
|
+
super().__init__(num_ctrl_qubits, label=label, ctrl_state=ctrl_state, _name="mcx_gray")
|
1268
|
+
|
1269
|
+
def inverse(self, annotated: bool = False):
|
1270
|
+
"""Invert this gate. The MCX is its own inverse.
|
1271
|
+
|
1272
|
+
Args:
|
1273
|
+
annotated: when set to ``True``, this is typically used to return an
|
1274
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
1275
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
1276
|
+
is self-inverse.
|
1277
|
+
|
1278
|
+
Returns:
|
1279
|
+
MCXGrayCode: inverse gate (self-inverse).
|
1280
|
+
"""
|
1281
|
+
return MCXGrayCode(num_ctrl_qubits=self.num_ctrl_qubits, ctrl_state=self.ctrl_state)
|
1282
|
+
|
1283
|
+
def _define(self):
|
1284
|
+
"""Define the MCX gate using the Gray code."""
|
1285
|
+
# pylint: disable=cyclic-import
|
1286
|
+
from qiskit.synthesis.multi_controlled import synth_mcx_gray_code
|
1287
|
+
|
1288
|
+
qc = synth_mcx_gray_code(self.num_ctrl_qubits)
|
1289
|
+
self.definition = qc
|
1290
|
+
|
1291
|
+
|
1292
|
+
class MCXRecursive(MCXGate):
|
1293
|
+
"""Implement the multi-controlled X gate using recursion.
|
1294
|
+
|
1295
|
+
Using a single clean ancilla qubit, the multi-controlled X gate is split into
|
1296
|
+
four sub-registers, each one of them uses the V-chain method.
|
1297
|
+
|
1298
|
+
The method is based on Lemma 9 of [2], first shown in Lemma 7.3 of [1].
|
1299
|
+
|
1300
|
+
References:
|
1301
|
+
1. Barenco et al., 1995. https://arxiv.org/pdf/quant-ph/9503016.pdf
|
1302
|
+
2. Iten et al., 2015. https://arxiv.org/abs/1501.06911
|
1303
|
+
"""
|
1304
|
+
|
1305
|
+
@deprecate_func(
|
1306
|
+
additional_msg=(
|
1307
|
+
"It is recommended to use MCXGate and let HighLevelSynthesis choose "
|
1308
|
+
"the best synthesis method depending on the number of ancilla qubits available. "
|
1309
|
+
"If this specific synthesis method is required, one can specify it using the "
|
1310
|
+
"high-level-synthesis plugin '1_clean_b95' for MCX gates, or, alternatively, "
|
1311
|
+
"one can use synth_mcx_1_clean to construct the gate directly."
|
1312
|
+
),
|
1313
|
+
since="1.3",
|
1314
|
+
pending=True,
|
1315
|
+
)
|
1316
|
+
def __init__(
|
1317
|
+
self,
|
1318
|
+
num_ctrl_qubits: int,
|
1319
|
+
label: Optional[str] = None,
|
1320
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1321
|
+
*,
|
1322
|
+
_base_label=None,
|
1323
|
+
):
|
1324
|
+
super().__init__(
|
1325
|
+
num_ctrl_qubits,
|
1326
|
+
label=label,
|
1327
|
+
ctrl_state=ctrl_state,
|
1328
|
+
_name="mcx_recursive",
|
1329
|
+
_base_label=None,
|
1330
|
+
)
|
1331
|
+
|
1332
|
+
@staticmethod
|
1333
|
+
def get_num_ancilla_qubits(num_ctrl_qubits: int, mode: str = "recursion"):
|
1334
|
+
"""Get the number of required ancilla qubits."""
|
1335
|
+
return MCXGate.get_num_ancilla_qubits(num_ctrl_qubits, mode)
|
1336
|
+
|
1337
|
+
def inverse(self, annotated: bool = False):
|
1338
|
+
"""Invert this gate. The MCX is its own inverse.
|
1339
|
+
|
1340
|
+
Args:
|
1341
|
+
annotated: when set to ``True``, this is typically used to return an
|
1342
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
1343
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
1344
|
+
is self-inverse.
|
1345
|
+
|
1346
|
+
Returns:
|
1347
|
+
MCXRecursive: inverse gate (self-inverse).
|
1348
|
+
"""
|
1349
|
+
return MCXRecursive(num_ctrl_qubits=self.num_ctrl_qubits, ctrl_state=self.ctrl_state)
|
1350
|
+
|
1351
|
+
def _define(self):
|
1352
|
+
"""Define the MCX gate using recursion."""
|
1353
|
+
|
1354
|
+
# pylint: disable=cyclic-import
|
1355
|
+
from qiskit.synthesis.multi_controlled import synth_mcx_1_clean_b95
|
1356
|
+
|
1357
|
+
qc = synth_mcx_1_clean_b95(self.num_ctrl_qubits)
|
1358
|
+
self.definition = qc
|
1359
|
+
|
1360
|
+
|
1361
|
+
class MCXVChain(MCXGate):
|
1362
|
+
"""Implement the multi-controlled X gate using a V-chain of CX gates."""
|
1363
|
+
|
1364
|
+
def __new__(
|
1365
|
+
cls,
|
1366
|
+
num_ctrl_qubits: Optional[int] = None,
|
1367
|
+
dirty_ancillas: bool = False, # pylint: disable=unused-argument
|
1368
|
+
label: Optional[str] = None,
|
1369
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1370
|
+
*,
|
1371
|
+
_base_label=None,
|
1372
|
+
relative_phase: bool = False, # pylint: disable=unused-argument
|
1373
|
+
action_only: bool = False, # pylint: disable=unused-argument
|
1374
|
+
):
|
1375
|
+
"""Create a new MCX instance.
|
1376
|
+
|
1377
|
+
This must be defined anew to include the additional argument ``dirty_ancillas``.
|
1378
|
+
"""
|
1379
|
+
return super().__new__(
|
1380
|
+
cls,
|
1381
|
+
num_ctrl_qubits,
|
1382
|
+
label=label,
|
1383
|
+
ctrl_state=ctrl_state,
|
1384
|
+
_base_label=_base_label,
|
1385
|
+
)
|
1386
|
+
|
1387
|
+
@deprecate_func(
|
1388
|
+
additional_msg=(
|
1389
|
+
"It is recommended to use MCXGate and let HighLevelSynthesis choose "
|
1390
|
+
"the best synthesis method depending on the number of ancilla qubits available. "
|
1391
|
+
"If this specific synthesis method is required, one can specify it using the "
|
1392
|
+
"high-level-synthesis plugins `n_clean_m15` (using clean ancillas) or "
|
1393
|
+
"`n_dirty_i15` (using dirty ancillas) for MCX gates. Alternatively, one can "
|
1394
|
+
"use synth_mcx_n_dirty_i15 and synth_mcx_n_clean_m15 to construct the gate directly."
|
1395
|
+
),
|
1396
|
+
since="1.3",
|
1397
|
+
pending=True,
|
1398
|
+
)
|
1399
|
+
def __init__(
|
1400
|
+
self,
|
1401
|
+
num_ctrl_qubits: int,
|
1402
|
+
dirty_ancillas: bool = False,
|
1403
|
+
label: Optional[str] = None,
|
1404
|
+
ctrl_state: Optional[Union[str, int]] = None,
|
1405
|
+
*,
|
1406
|
+
_base_label=None,
|
1407
|
+
relative_phase: bool = False,
|
1408
|
+
action_only: bool = False,
|
1409
|
+
):
|
1410
|
+
"""
|
1411
|
+
Args:
|
1412
|
+
dirty_ancillas: when set to ``True``, the method applies an optimized multicontrolled-X gate
|
1413
|
+
up to a relative phase using dirty ancillary qubits with the properties of lemmas 7 and 8
|
1414
|
+
from arXiv:1501.06911, with at most 8*k - 6 CNOT gates.
|
1415
|
+
For k within the range {1, ..., ceil(n/2)}. And for n representing the total number of
|
1416
|
+
qubits.
|
1417
|
+
relative_phase: when set to ``True``, the method applies the optimized multicontrolled-X gate
|
1418
|
+
up to a relative phase, in a way that, by lemma 7 of arXiv:1501.06911, the relative
|
1419
|
+
phases of the ``action part`` cancel out with the phases of the ``reset part``.
|
1420
|
+
|
1421
|
+
action_only: when set to ``True``, the method applies only the action part of lemma 8
|
1422
|
+
from arXiv:1501.06911.
|
1423
|
+
|
1424
|
+
"""
|
1425
|
+
super().__init__(
|
1426
|
+
num_ctrl_qubits,
|
1427
|
+
label=label,
|
1428
|
+
ctrl_state=ctrl_state,
|
1429
|
+
_name="mcx_vchain",
|
1430
|
+
_base_label=_base_label,
|
1431
|
+
)
|
1432
|
+
self._dirty_ancillas = dirty_ancillas
|
1433
|
+
self._relative_phase = relative_phase
|
1434
|
+
self._action_only = action_only
|
1435
|
+
super().__init__(num_ctrl_qubits, label=label, ctrl_state=ctrl_state, _name="mcx_vchain")
|
1436
|
+
|
1437
|
+
def inverse(self, annotated: bool = False):
|
1438
|
+
"""Invert this gate. The MCX is its own inverse.
|
1439
|
+
|
1440
|
+
Args:
|
1441
|
+
annotated: when set to ``True``, this is typically used to return an
|
1442
|
+
:class:`.AnnotatedOperation` with an inverse modifier set instead of a concrete
|
1443
|
+
:class:`.Gate`. However, for this class this argument is ignored as this gate
|
1444
|
+
is self-inverse.
|
1445
|
+
|
1446
|
+
Returns:
|
1447
|
+
MCXVChain: inverse gate (self-inverse).
|
1448
|
+
"""
|
1449
|
+
return MCXVChain(
|
1450
|
+
num_ctrl_qubits=self.num_ctrl_qubits,
|
1451
|
+
dirty_ancillas=self._dirty_ancillas,
|
1452
|
+
ctrl_state=self.ctrl_state,
|
1453
|
+
relative_phase=self._relative_phase,
|
1454
|
+
action_only=self._action_only,
|
1455
|
+
)
|
1456
|
+
|
1457
|
+
@staticmethod
|
1458
|
+
def get_num_ancilla_qubits(num_ctrl_qubits: int, mode: str = "v-chain"):
|
1459
|
+
"""Get the number of required ancilla qubits."""
|
1460
|
+
return MCXGate.get_num_ancilla_qubits(num_ctrl_qubits, mode)
|
1461
|
+
|
1462
|
+
def _define(self):
|
1463
|
+
"""Define the MCX gate using a V-chain of CX gates."""
|
1464
|
+
|
1465
|
+
if self._dirty_ancillas:
|
1466
|
+
# pylint: disable=cyclic-import
|
1467
|
+
from qiskit.synthesis.multi_controlled import synth_mcx_n_dirty_i15
|
1468
|
+
|
1469
|
+
qc = synth_mcx_n_dirty_i15(
|
1470
|
+
self.num_ctrl_qubits,
|
1471
|
+
self._relative_phase,
|
1472
|
+
self._action_only,
|
1473
|
+
)
|
1474
|
+
|
1475
|
+
else: # use clean ancillas
|
1476
|
+
# pylint: disable=cyclic-import
|
1477
|
+
from qiskit.synthesis.multi_controlled import synth_mcx_n_clean_m15
|
1478
|
+
|
1479
|
+
qc = synth_mcx_n_clean_m15(self.num_ctrl_qubits)
|
1480
|
+
|
1481
|
+
self.definition = qc
|