qiskit 1.3.0b1__cp39-abi3-win32.whl → 1.3.0rc2__cp39-abi3-win32.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 -1
- qiskit/__init__.py +20 -1
- qiskit/_accelerate.pyd +0 -0
- qiskit/assembler/assemble_schedules.py +2 -0
- qiskit/circuit/__init__.py +44 -1
- qiskit/circuit/_standard_gates_commutations.py +585 -0
- qiskit/circuit/barrier.py +2 -0
- qiskit/circuit/controlflow/builder.py +3 -3
- qiskit/circuit/controlflow/if_else.py +13 -5
- qiskit/circuit/controlflow/while_loop.py +10 -2
- qiskit/circuit/delay.py +20 -3
- qiskit/circuit/equivalence.py +13 -214
- qiskit/circuit/gate.py +3 -1
- qiskit/circuit/instruction.py +32 -11
- qiskit/circuit/instructionset.py +2 -0
- qiskit/circuit/library/__init__.py +110 -14
- qiskit/circuit/library/arithmetic/__init__.py +9 -2
- qiskit/circuit/library/arithmetic/adders/__init__.py +1 -0
- qiskit/circuit/library/arithmetic/adders/adder.py +154 -2
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +20 -56
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +14 -1
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +21 -91
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +1 -0
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +8 -1
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +94 -3
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +8 -1
- qiskit/circuit/library/arithmetic/weighted_adder.py +1 -1
- qiskit/circuit/library/basis_change/qft.py +20 -38
- qiskit/circuit/library/blueprintcircuit.py +64 -0
- qiskit/circuit/library/boolean_logic/__init__.py +4 -4
- qiskit/circuit/library/boolean_logic/inner_product.py +81 -4
- qiskit/circuit/library/boolean_logic/quantum_and.py +107 -4
- qiskit/circuit/library/boolean_logic/quantum_or.py +107 -3
- qiskit/circuit/library/boolean_logic/quantum_xor.py +97 -3
- qiskit/circuit/library/data_preparation/__init__.py +6 -3
- qiskit/circuit/library/data_preparation/{z_feature_map.py → _z_feature_map.py} +45 -34
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +342 -29
- qiskit/circuit/library/fourier_checking.py +72 -11
- qiskit/circuit/library/generalized_gates/__init__.py +1 -1
- qiskit/circuit/library/generalized_gates/diagonal.py +45 -51
- qiskit/circuit/library/generalized_gates/gms.py +67 -14
- qiskit/circuit/library/generalized_gates/gr.py +4 -4
- qiskit/circuit/library/generalized_gates/isometry.py +2 -2
- qiskit/circuit/library/generalized_gates/linear_function.py +12 -6
- qiskit/circuit/library/generalized_gates/mcmt.py +167 -107
- qiskit/circuit/library/generalized_gates/permutation.py +8 -6
- qiskit/circuit/library/generalized_gates/rv.py +8 -9
- qiskit/circuit/library/graph_state.py +93 -10
- qiskit/circuit/library/grover_operator.py +270 -2
- qiskit/circuit/library/hidden_linear_function.py +83 -20
- qiskit/circuit/library/iqp.py +99 -20
- qiskit/circuit/library/n_local/__init__.py +19 -7
- qiskit/circuit/library/n_local/efficient_su2.py +118 -5
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +259 -0
- qiskit/circuit/library/n_local/excitation_preserving.py +130 -6
- qiskit/circuit/library/n_local/n_local.py +406 -5
- qiskit/circuit/library/n_local/pauli_two_design.py +106 -4
- qiskit/circuit/library/n_local/qaoa_ansatz.py +80 -1
- qiskit/circuit/library/n_local/real_amplitudes.py +127 -7
- qiskit/circuit/library/n_local/two_local.py +14 -7
- qiskit/circuit/library/overlap.py +91 -26
- qiskit/circuit/library/pauli_evolution.py +17 -15
- qiskit/circuit/library/phase_estimation.py +80 -4
- qiskit/circuit/library/quantum_volume.py +72 -20
- qiskit/circuit/library/standard_gates/__init__.py +20 -1
- qiskit/circuit/library/standard_gates/dcx.py +2 -1
- qiskit/circuit/library/standard_gates/ecr.py +2 -2
- qiskit/circuit/library/standard_gates/h.py +4 -3
- qiskit/circuit/library/standard_gates/i.py +2 -1
- qiskit/circuit/library/standard_gates/iswap.py +2 -2
- qiskit/circuit/library/standard_gates/p.py +20 -12
- qiskit/circuit/library/standard_gates/r.py +1 -1
- qiskit/circuit/library/standard_gates/rx.py +4 -3
- qiskit/circuit/library/standard_gates/rxx.py +2 -2
- qiskit/circuit/library/standard_gates/ry.py +4 -3
- qiskit/circuit/library/standard_gates/ryy.py +2 -2
- qiskit/circuit/library/standard_gates/rz.py +13 -12
- qiskit/circuit/library/standard_gates/rzx.py +6 -6
- qiskit/circuit/library/standard_gates/rzz.py +1 -1
- qiskit/circuit/library/standard_gates/s.py +4 -4
- qiskit/circuit/library/standard_gates/swap.py +3 -3
- qiskit/circuit/library/standard_gates/sx.py +4 -3
- qiskit/circuit/library/standard_gates/t.py +2 -2
- qiskit/circuit/library/standard_gates/u.py +11 -3
- qiskit/circuit/library/standard_gates/u1.py +65 -15
- qiskit/circuit/library/standard_gates/u2.py +4 -1
- qiskit/circuit/library/standard_gates/u3.py +31 -3
- qiskit/circuit/library/standard_gates/x.py +7 -5
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -2
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -2
- qiskit/circuit/library/standard_gates/y.py +4 -3
- qiskit/circuit/library/standard_gates/z.py +3 -3
- qiskit/circuit/library/templates/clifford/clifford_2_1.py +9 -8
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +9 -7
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +9 -8
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +9 -8
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +9 -8
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +10 -9
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +9 -7
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +10 -8
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +16 -14
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +14 -12
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +14 -12
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +11 -9
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +11 -9
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +11 -9
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +11 -9
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +12 -10
- qiskit/circuit/library/templates/rzx/rzx_cy.py +11 -10
- qiskit/circuit/library/templates/rzx/rzx_xz.py +16 -15
- qiskit/circuit/library/templates/rzx/rzx_yz.py +12 -10
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +22 -20
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +16 -15
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +17 -15
- qiskit/circuit/parameter.py +4 -0
- qiskit/circuit/parameterexpression.py +167 -34
- qiskit/circuit/quantumcircuit.py +162 -126
- qiskit/circuit/singleton.py +2 -0
- qiskit/circuit/store.py +2 -0
- qiskit/circuit/twirling.py +145 -0
- qiskit/compiler/assembler.py +17 -4
- qiskit/compiler/scheduler.py +2 -0
- qiskit/compiler/sequencer.py +2 -0
- qiskit/compiler/transpiler.py +81 -26
- qiskit/converters/circuit_to_dag.py +2 -2
- qiskit/converters/circuit_to_dagdependency.py +1 -1
- qiskit/converters/circuit_to_dagdependency_v2.py +1 -1
- qiskit/converters/circuit_to_instruction.py +1 -1
- qiskit/converters/dag_to_circuit.py +7 -5
- qiskit/converters/dag_to_dagdependency.py +1 -1
- qiskit/converters/dag_to_dagdependency_v2.py +1 -1
- qiskit/converters/dagdependency_to_circuit.py +5 -1
- qiskit/converters/dagdependency_to_dag.py +6 -1
- qiskit/dagcircuit/collect_blocks.py +3 -3
- qiskit/dagcircuit/dagdependency.py +18 -5
- qiskit/dagcircuit/dagdependency_v2.py +1 -1
- qiskit/dagcircuit/dagnode.py +2 -2
- qiskit/passmanager/__init__.py +2 -2
- qiskit/primitives/backend_estimator.py +5 -2
- qiskit/primitives/backend_sampler_v2.py +61 -18
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +9 -1
- qiskit/primitives/statevector_sampler.py +1 -1
- qiskit/primitives/utils.py +1 -1
- qiskit/providers/__init__.py +3 -3
- qiskit/providers/backend.py +12 -1
- qiskit/providers/backend_compat.py +23 -3
- qiskit/providers/basic_provider/basic_simulator.py +12 -2
- qiskit/providers/fake_provider/fake_pulse_backend.py +6 -1
- qiskit/providers/fake_provider/generic_backend_v2.py +46 -30
- qiskit/providers/models/pulsedefaults.py +2 -0
- qiskit/pulse/builder.py +59 -18
- qiskit/pulse/calibration_entries.py +4 -1
- qiskit/pulse/channels.py +2 -0
- qiskit/pulse/exceptions.py +2 -0
- qiskit/pulse/instruction_schedule_map.py +21 -6
- qiskit/pulse/instructions/acquire.py +2 -0
- qiskit/pulse/instructions/delay.py +2 -0
- qiskit/pulse/instructions/directives.py +8 -0
- qiskit/pulse/instructions/frequency.py +3 -0
- qiskit/pulse/instructions/instruction.py +2 -0
- qiskit/pulse/instructions/phase.py +3 -0
- qiskit/pulse/instructions/play.py +2 -0
- qiskit/pulse/instructions/reference.py +2 -0
- qiskit/pulse/instructions/snapshot.py +2 -0
- qiskit/pulse/library/pulse.py +2 -0
- qiskit/pulse/library/symbolic_pulses.py +28 -0
- qiskit/pulse/library/waveform.py +2 -0
- qiskit/pulse/macros.py +1 -1
- qiskit/pulse/schedule.py +12 -13
- qiskit/pulse/transforms/alignments.py +5 -3
- qiskit/pulse/transforms/dag.py +7 -0
- qiskit/qasm2/export.py +5 -3
- qiskit/qasm2/parse.py +46 -2
- qiskit/qasm3/__init__.py +1 -0
- qiskit/qasm3/ast.py +123 -15
- qiskit/qasm3/exporter.py +103 -77
- qiskit/qobj/converters/pulse_instruction.py +6 -4
- qiskit/qpy/__init__.py +181 -0
- qiskit/qpy/binary_io/circuits.py +20 -5
- qiskit/qpy/binary_io/schedules.py +3 -4
- qiskit/qpy/binary_io/value.py +310 -13
- qiskit/qpy/common.py +46 -2
- qiskit/qpy/formats.py +7 -0
- qiskit/qpy/interface.py +40 -4
- qiskit/quantum_info/__init__.py +4 -0
- qiskit/quantum_info/operators/channel/transformations.py +28 -21
- qiskit/quantum_info/operators/dihedral/dihedral.py +1 -1
- qiskit/quantum_info/operators/operator.py +54 -8
- qiskit/quantum_info/operators/symplectic/base_pauli.py +11 -19
- qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +1 -1
- qiskit/quantum_info/operators/symplectic/pauli.py +2 -0
- qiskit/quantum_info/operators/symplectic/pauli_list.py +4 -4
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +23 -2
- qiskit/quantum_info/states/densitymatrix.py +5 -5
- qiskit/quantum_info/states/stabilizerstate.py +1 -1
- qiskit/quantum_info/states/statevector.py +6 -6
- qiskit/result/mitigation/base_readout_mitigator.py +1 -1
- qiskit/result/mitigation/correlated_readout_mitigator.py +9 -1
- qiskit/result/mitigation/local_readout_mitigator.py +9 -1
- qiskit/result/mitigation/utils.py +57 -0
- qiskit/scheduler/config.py +2 -0
- qiskit/scheduler/methods/basic.py +3 -0
- qiskit/scheduler/schedule_circuit.py +2 -0
- qiskit/scheduler/sequence.py +2 -0
- qiskit/synthesis/__init__.py +25 -0
- qiskit/synthesis/arithmetic/__init__.py +16 -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/multipliers/__init__.py +16 -0
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +102 -0
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +99 -0
- qiskit/synthesis/clifford/clifford_decompose_bm.py +1 -2
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +3 -2
- qiskit/synthesis/clifford/clifford_decompose_layers.py +2 -1
- qiskit/synthesis/evolution/__init__.py +1 -0
- qiskit/synthesis/evolution/lie_trotter.py +16 -42
- qiskit/synthesis/evolution/pauli_network.py +80 -0
- qiskit/synthesis/evolution/product_formula.py +165 -238
- qiskit/synthesis/evolution/qdrift.py +36 -29
- qiskit/synthesis/evolution/suzuki_trotter.py +87 -27
- qiskit/synthesis/multi_controlled/__init__.py +1 -0
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
- qiskit/synthesis/qft/qft_decompose_full.py +19 -1
- qiskit/synthesis/qft/qft_decompose_lnn.py +2 -1
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -1
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +4 -63
- qiskit/synthesis/unitary/qsd.py +5 -5
- qiskit/transpiler/__init__.py +21 -14
- qiskit/transpiler/basepasses.py +1 -1
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +9 -565
- qiskit/transpiler/passes/basis/decompose.py +45 -12
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
- qiskit/transpiler/passes/calibration/pulse_gate.py +4 -2
- qiskit/transpiler/passes/calibration/rx_builder.py +11 -7
- qiskit/transpiler/passes/calibration/rzx_builder.py +46 -30
- qiskit/transpiler/passes/layout/disjoint_utils.py +15 -13
- qiskit/transpiler/passes/layout/sabre_layout.py +7 -2
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +5 -0
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +19 -3
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +1 -1
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
- qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +1 -1
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +48 -131
- qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +4 -2
- qiskit/transpiler/passes/optimization/elide_permutations.py +9 -32
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +5 -11
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
- qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +1 -1
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +69 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +5 -5
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +4 -4
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +2 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +1 -1
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +7 -3
- qiskit/transpiler/passes/routing/star_prerouting.py +2 -2
- qiskit/transpiler/passes/scheduling/alap.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +2 -2
- qiskit/transpiler/passes/scheduling/asap.py +1 -1
- qiskit/transpiler/passes/scheduling/base_scheduler.py +14 -12
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +9 -4
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +16 -5
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +4 -1
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +6 -2
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +9 -4
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +262 -99
- qiskit/transpiler/passes/synthesis/hls_plugins.py +637 -7
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +3 -3
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +55 -34
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +2 -56
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +5 -0
- qiskit/transpiler/passes/utils/gate_direction.py +12 -275
- qiskit/transpiler/passes/utils/gates_basis.py +7 -30
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +2 -1
- qiskit/transpiler/passmanager_config.py +22 -4
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +40 -14
- qiskit/transpiler/preset_passmanagers/common.py +5 -3
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +125 -42
- qiskit/transpiler/preset_passmanagers/plugin.py +1 -1
- qiskit/transpiler/target.py +74 -16
- qiskit/utils/deprecate_pulse.py +119 -0
- qiskit/visualization/circuit/_utils.py +2 -2
- qiskit/visualization/circuit/circuit_visualization.py +3 -2
- qiskit/visualization/circuit/matplotlib.py +1 -1
- qiskit/visualization/dag_visualization.py +1 -1
- qiskit/visualization/pass_manager_visualization.py +3 -14
- qiskit/visualization/pulse_v2/interface.py +3 -1
- qiskit/visualization/timeline/core.py +25 -2
- qiskit/visualization/timeline/interface.py +12 -0
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/METADATA +9 -8
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/RECORD +357 -346
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/WHEEL +1 -1
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/entry_points.txt +19 -0
- qiskit/circuit/library/data_preparation/zz_feature_map.py +0 -118
- qiskit/synthesis/two_qubit/weyl.py +0 -97
- qiskit/transpiler/passes/synthesis/qubit_tracker.py +0 -132
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/top_level.txt +0 -0
@@ -14,14 +14,14 @@
|
|
14
14
|
|
15
15
|
from __future__ import annotations
|
16
16
|
|
17
|
+
import warnings
|
17
18
|
from collections.abc import Callable
|
18
19
|
|
19
20
|
from qiskit import circuit
|
20
|
-
from qiskit.circuit import ControlledGate, Gate,
|
21
|
-
from qiskit.
|
22
|
-
|
23
|
-
|
24
|
-
from ..standard_gates import XGate, YGate, ZGate, HGate, TGate, TdgGate, SGate, SdgGate
|
21
|
+
from qiskit.circuit import ControlledGate, Gate, QuantumCircuit
|
22
|
+
from qiskit.circuit._utils import _ctrl_state_to_int
|
23
|
+
from qiskit.utils.deprecation import deprecate_func
|
24
|
+
from ..standard_gates import get_standard_gate_name_mapping
|
25
25
|
|
26
26
|
|
27
27
|
class MCMT(QuantumCircuit):
|
@@ -29,7 +29,7 @@ class MCMT(QuantumCircuit):
|
|
29
29
|
|
30
30
|
For example, the H gate controlled on 3 qubits and acting on 2 target qubit is represented as:
|
31
31
|
|
32
|
-
..
|
32
|
+
.. code-block:: text
|
33
33
|
|
34
34
|
───■────
|
35
35
|
│
|
@@ -49,6 +49,7 @@ class MCMT(QuantumCircuit):
|
|
49
49
|
:class:`~qiskit.circuit.library.MCMTVChain`.
|
50
50
|
"""
|
51
51
|
|
52
|
+
@deprecate_func(since="1.3", additional_msg="Use MCMTGate instead.", pending=True)
|
52
53
|
def __init__(
|
53
54
|
self,
|
54
55
|
gate: Gate | Callable[[QuantumCircuit, circuit.Qubit, circuit.Qubit], circuit.Instruction],
|
@@ -71,77 +72,41 @@ class MCMT(QuantumCircuit):
|
|
71
72
|
if num_ctrl_qubits == 0 or num_target_qubits == 0:
|
72
73
|
raise AttributeError("Need at least one control and one target qubit.")
|
73
74
|
|
74
|
-
|
75
|
-
|
75
|
+
if callable(gate):
|
76
|
+
warnings.warn(
|
77
|
+
"Passing a callable to MCMT is pending deprecation since Qiskit 1.3. Pass a "
|
78
|
+
"gate instance or the gate name instead, e.g. pass 'h' instead of QuantumCircuit.h.",
|
79
|
+
category=PendingDeprecationWarning,
|
80
|
+
stacklevel=2,
|
81
|
+
)
|
82
|
+
gate = gate.__name__
|
83
|
+
elif isinstance(gate, QuantumCircuit):
|
84
|
+
warnings.warn(
|
85
|
+
"Passing a QuantumCircuit is pending deprecation since Qiskit 1.3. Pass a gate "
|
86
|
+
"or turn the circuit into a gate using the ``to_gate`` method, instead.",
|
87
|
+
category=PendingDeprecationWarning,
|
88
|
+
stacklevel=2,
|
89
|
+
)
|
90
|
+
gate = gate.to_gate()
|
91
|
+
|
92
|
+
self.gate = MCMTGate._identify_base_gate(gate)
|
76
93
|
self.num_ctrl_qubits = num_ctrl_qubits
|
77
94
|
self.num_target_qubits = num_target_qubits
|
78
|
-
num_qubits = num_ctrl_qubits + num_target_qubits + self.num_ancilla_qubits
|
79
95
|
|
80
96
|
# initialize the circuit object
|
97
|
+
num_qubits = num_ctrl_qubits + num_target_qubits + self.num_ancilla_qubits
|
81
98
|
super().__init__(num_qubits, name="mcmt")
|
82
|
-
self._label = f"{num_target_qubits}-{self.gate.name.capitalize()}"
|
83
|
-
|
84
|
-
# build the circuit
|
85
99
|
self._build()
|
86
100
|
|
87
101
|
def _build(self):
|
88
|
-
|
89
|
-
|
90
|
-
# no broadcasting needed (makes for better circuit diagrams)
|
91
|
-
broadcasted_gate = self.gate
|
92
|
-
else:
|
93
|
-
broadcasted = QuantumCircuit(self.num_target_qubits, name=self._label)
|
94
|
-
for target in list(range(self.num_target_qubits)):
|
95
|
-
broadcasted.append(self.gate, [target], [])
|
96
|
-
broadcasted_gate = broadcasted.to_gate()
|
97
|
-
|
98
|
-
mcmt_gate = broadcasted_gate.control(self.num_ctrl_qubits)
|
99
|
-
self.append(mcmt_gate, self.qubits, [])
|
102
|
+
gate = MCMTGate(self.gate, self.num_ctrl_qubits, self.num_target_qubits)
|
103
|
+
self.append(gate, self.qubits)
|
100
104
|
|
101
105
|
@property
|
102
106
|
def num_ancilla_qubits(self):
|
103
107
|
"""Return the number of ancillas."""
|
104
108
|
return 0
|
105
109
|
|
106
|
-
def _identify_gate(self, gate):
|
107
|
-
"""Case the gate input to a gate."""
|
108
|
-
valid_gates = {
|
109
|
-
"ch": HGate(),
|
110
|
-
"cx": XGate(),
|
111
|
-
"cy": YGate(),
|
112
|
-
"cz": ZGate(),
|
113
|
-
"h": HGate(),
|
114
|
-
"s": SGate(),
|
115
|
-
"sdg": SdgGate(),
|
116
|
-
"x": XGate(),
|
117
|
-
"y": YGate(),
|
118
|
-
"z": ZGate(),
|
119
|
-
"t": TGate(),
|
120
|
-
"tdg": TdgGate(),
|
121
|
-
}
|
122
|
-
if isinstance(gate, ControlledGate):
|
123
|
-
base_gate = gate.base_gate
|
124
|
-
elif isinstance(gate, Gate):
|
125
|
-
if gate.num_qubits != 1:
|
126
|
-
raise AttributeError("Base gate must act on one qubit only.")
|
127
|
-
base_gate = gate
|
128
|
-
elif isinstance(gate, QuantumCircuit):
|
129
|
-
if gate.num_qubits != 1:
|
130
|
-
raise AttributeError(
|
131
|
-
"The circuit you specified as control gate can only have one qubit!"
|
132
|
-
)
|
133
|
-
base_gate = gate.to_gate() # raises error if circuit contains non-unitary instructions
|
134
|
-
else:
|
135
|
-
if callable(gate): # identify via name of the passed function
|
136
|
-
name = gate.__name__
|
137
|
-
elif isinstance(gate, str):
|
138
|
-
name = gate
|
139
|
-
else:
|
140
|
-
raise AttributeError(f"Invalid gate specified: {gate}")
|
141
|
-
base_gate = valid_gates[name]
|
142
|
-
|
143
|
-
return base_gate
|
144
|
-
|
145
110
|
def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None, annotated=False):
|
146
111
|
"""Return the controlled version of the MCMT circuit."""
|
147
112
|
if not annotated and ctrl_state is None:
|
@@ -191,66 +156,161 @@ class MCMTVChain(MCMT):
|
|
191
156
|
└───┘ └───┘
|
192
157
|
"""
|
193
158
|
|
159
|
+
@deprecate_func(
|
160
|
+
since="1.3",
|
161
|
+
additional_msg="Use MCMTGate with the V-chain synthesis plugin instead.",
|
162
|
+
pending=True,
|
163
|
+
)
|
164
|
+
def __init__(
|
165
|
+
self,
|
166
|
+
gate: Gate | Callable[[QuantumCircuit, circuit.Qubit, circuit.Qubit], circuit.Instruction],
|
167
|
+
num_ctrl_qubits: int,
|
168
|
+
num_target_qubits: int,
|
169
|
+
) -> None:
|
170
|
+
super().__init__(gate, num_ctrl_qubits, num_target_qubits)
|
171
|
+
|
194
172
|
def _build(self):
|
195
|
-
|
196
|
-
|
197
|
-
target_qubits = self.qubits[
|
198
|
-
self.num_ctrl_qubits : self.num_ctrl_qubits + self.num_target_qubits
|
199
|
-
]
|
200
|
-
ancilla_qubits = self.qubits[self.num_ctrl_qubits + self.num_target_qubits :]
|
201
|
-
|
202
|
-
if len(ancilla_qubits) > 0:
|
203
|
-
master_control = ancilla_qubits[-1]
|
204
|
-
else:
|
205
|
-
master_control = control_qubits[0]
|
173
|
+
# pylint: disable=cyclic-import
|
174
|
+
from qiskit.synthesis.multi_controlled import synth_mcmt_vchain
|
206
175
|
|
207
|
-
self.
|
208
|
-
|
209
|
-
self.append(self.gate.control(), [master_control, qubit], [])
|
210
|
-
self._ccx_v_chain_rule(control_qubits, ancilla_qubits, reverse=True)
|
176
|
+
synthesized = synth_mcmt_vchain(self.gate, self.num_ctrl_qubits, self.num_target_qubits)
|
177
|
+
self.compose(synthesized, inplace=True, copy=False)
|
211
178
|
|
212
179
|
@property
|
213
180
|
def num_ancilla_qubits(self):
|
214
181
|
"""Return the number of ancilla qubits required."""
|
215
182
|
return max(0, self.num_ctrl_qubits - 1)
|
216
183
|
|
217
|
-
def
|
184
|
+
def inverse(self, annotated: bool = False):
|
185
|
+
return MCMTVChain(self.gate, self.num_ctrl_qubits, self.num_target_qubits)
|
186
|
+
|
187
|
+
|
188
|
+
class MCMTGate(ControlledGate):
|
189
|
+
"""The multi-controlled multi-target gate, for an arbitrary singly controlled target gate.
|
190
|
+
|
191
|
+
For example, the H gate controlled on 3 qubits and acting on 2 target qubit is represented as:
|
192
|
+
|
193
|
+
.. parsed-literal::
|
194
|
+
|
195
|
+
───■────
|
196
|
+
│
|
197
|
+
───■────
|
198
|
+
│
|
199
|
+
───■────
|
200
|
+
┌──┴───┐
|
201
|
+
┤0 ├
|
202
|
+
│ 2-H │
|
203
|
+
┤1 ├
|
204
|
+
└──────┘
|
205
|
+
|
206
|
+
Depending on the number of available auxiliary qubits, this operation can be synthesized
|
207
|
+
using different methods. For example, if :math:`n - 1` clean auxiliary qubits are available
|
208
|
+
(where :math:`n` is the number of control qubits), a V-chain decomposition can be used whose
|
209
|
+
depth is linear in :math:`n`. See also :func:`.synth_mcmt_chain`.
|
210
|
+
"""
|
211
|
+
|
212
|
+
def __init__(
|
218
213
|
self,
|
219
|
-
|
220
|
-
|
221
|
-
|
214
|
+
gate: Gate,
|
215
|
+
num_ctrl_qubits: int,
|
216
|
+
num_target_qubits: int,
|
217
|
+
ctrl_state: int | str | None = None,
|
218
|
+
label: str | None = None,
|
222
219
|
) -> None:
|
223
|
-
"""
|
220
|
+
"""
|
221
|
+
Args:
|
222
|
+
gate: The base gate to apply on multiple target qubits, controlled by other qubits.
|
223
|
+
This must be a single-qubit gate or a controlled single-qubit gate.
|
224
|
+
num_ctrl_qubits: The number of control qubits.
|
225
|
+
num_target_qubits: The number of target qubits.
|
226
|
+
ctrl_state: The control state of the control qubits. Defaults to all closed controls.
|
227
|
+
label: The gate label.
|
228
|
+
"""
|
229
|
+
if num_target_qubits < 1:
|
230
|
+
raise ValueError("Need at least one target qubit.")
|
224
231
|
|
225
|
-
|
226
|
-
|
232
|
+
if num_ctrl_qubits < 1:
|
233
|
+
raise ValueError("Need at least one control qubit.")
|
227
234
|
|
228
|
-
|
229
|
-
control_qubits: The control qubits.
|
230
|
-
ancilla_qubits: The ancilla qubits.
|
231
|
-
reverse: If True, compute the chain down to the qubit. If False, compute upwards.
|
235
|
+
self.num_target_qubits = num_target_qubits
|
232
236
|
|
233
|
-
|
234
|
-
|
237
|
+
base_gate = self._identify_base_gate(gate)
|
238
|
+
num_qubits = num_ctrl_qubits + num_target_qubits
|
239
|
+
|
240
|
+
if label is None:
|
241
|
+
label = f"{num_target_qubits}-{gate.name.capitalize()}"
|
242
|
+
|
243
|
+
super().__init__(
|
244
|
+
"mcmt",
|
245
|
+
base_gate=base_gate,
|
246
|
+
num_qubits=num_qubits,
|
247
|
+
params=gate.params,
|
248
|
+
num_ctrl_qubits=num_ctrl_qubits,
|
249
|
+
ctrl_state=ctrl_state,
|
250
|
+
label=label,
|
251
|
+
)
|
252
|
+
|
253
|
+
def _define(self):
|
254
|
+
"""Default definition relying on gate.control. Control state is handled by superclass."""
|
255
|
+
# pylint: disable=cyclic-import
|
256
|
+
from qiskit.transpiler.passes.synthesis.hls_plugins import MCMTSynthesisDefault
|
257
|
+
|
258
|
+
self.definition = MCMTSynthesisDefault().run(self)
|
259
|
+
|
260
|
+
@staticmethod
|
261
|
+
def _identify_base_gate(gate):
|
262
|
+
"""Get the control base gate. Note this must be a single qubit gate."""
|
263
|
+
|
264
|
+
# try getting the standard name from the string
|
265
|
+
if isinstance(gate, str):
|
266
|
+
standard_gates = get_standard_gate_name_mapping()
|
267
|
+
if gate in standard_gates:
|
268
|
+
gate = standard_gates[gate]
|
269
|
+
else:
|
270
|
+
raise AttributeError(
|
271
|
+
f"Unknown gate {gate}. Available: {list(get_standard_gate_name_mapping.keys())}"
|
272
|
+
)
|
235
273
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
274
|
+
# extract the base gate
|
275
|
+
if isinstance(gate, ControlledGate):
|
276
|
+
warnings.warn(
|
277
|
+
"Passing a controlled gate to MCMT is pending deprecation since Qiskit 1.3. Pass a "
|
278
|
+
"single-qubit gate instance or the gate name instead, e.g. pass 'h' instead of 'ch'.",
|
279
|
+
category=PendingDeprecationWarning,
|
280
|
+
stacklevel=2,
|
281
|
+
)
|
282
|
+
base_gate = gate.base_gate
|
283
|
+
elif isinstance(gate, Gate):
|
284
|
+
base_gate = gate
|
285
|
+
else:
|
286
|
+
raise TypeError(f"Invalid gate type {type(gate)}.")
|
287
|
+
|
288
|
+
if base_gate.num_qubits != 1:
|
289
|
+
raise ValueError(
|
290
|
+
f"MCMTGate requires a base gate with a single qubit, but got {base_gate.num_qubits}."
|
291
|
+
)
|
241
292
|
|
242
|
-
|
243
|
-
raise QiskitError("Insufficient number of ancilla qubits.")
|
293
|
+
return base_gate
|
244
294
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
295
|
+
def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None, annotated=False):
|
296
|
+
"""Return the controlled version of the MCMT circuit."""
|
297
|
+
if not annotated:
|
298
|
+
ctrl_state = _ctrl_state_to_int(ctrl_state, num_ctrl_qubits)
|
299
|
+
new_ctrl_state = (self.ctrl_state << num_ctrl_qubits) | ctrl_state
|
300
|
+
|
301
|
+
gate = MCMTGate(
|
302
|
+
self.base_gate,
|
303
|
+
self.num_ctrl_qubits + num_ctrl_qubits,
|
304
|
+
self.num_target_qubits,
|
305
|
+
ctrl_state=new_ctrl_state,
|
306
|
+
)
|
250
307
|
else:
|
251
|
-
|
252
|
-
|
253
|
-
|
308
|
+
gate = super().control(num_ctrl_qubits, label, ctrl_state, annotated=annotated)
|
309
|
+
|
310
|
+
return gate
|
254
311
|
|
255
312
|
def inverse(self, annotated: bool = False):
|
256
|
-
|
313
|
+
"""Return the inverse MCMT circuit."""
|
314
|
+
return MCMTGate(
|
315
|
+
self.base_gate.inverse(), self.num_ctrl_qubits, self.num_target_qubits, self.ctrl_state
|
316
|
+
)
|
@@ -22,11 +22,13 @@ import numpy as np
|
|
22
22
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
23
23
|
from qiskit.circuit.quantumcircuit import Gate
|
24
24
|
from qiskit.circuit.exceptions import CircuitError
|
25
|
+
from qiskit.utils.deprecation import deprecate_func
|
25
26
|
|
26
27
|
|
27
28
|
class Permutation(QuantumCircuit):
|
28
29
|
"""An n_qubit circuit that permutes qubits."""
|
29
30
|
|
31
|
+
@deprecate_func(since="1.3", pending=True, additional_msg="Use PermutationGate instead.")
|
30
32
|
def __init__(
|
31
33
|
self,
|
32
34
|
num_qubits: int,
|
@@ -117,11 +119,11 @@ class PermutationGate(Gate):
|
|
117
119
|
|
118
120
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
119
121
|
from qiskit.circuit.library import PermutationGate
|
120
|
-
A = [2,4,3,0,1]
|
122
|
+
A = [2, 4, 3, 0, 1]
|
121
123
|
permutation = PermutationGate(A)
|
122
124
|
circuit = QuantumCircuit(5)
|
123
125
|
circuit.append(permutation, [0, 1, 2, 3, 4])
|
124
|
-
circuit.draw(
|
126
|
+
circuit.draw("mpl")
|
125
127
|
|
126
128
|
Expanded Circuit:
|
127
129
|
.. plot::
|
@@ -129,7 +131,7 @@ class PermutationGate(Gate):
|
|
129
131
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
130
132
|
from qiskit.circuit.library import PermutationGate
|
131
133
|
from qiskit.visualization.library import _generate_circuit_library_visualization
|
132
|
-
A = [2,4,3,0,1]
|
134
|
+
A = [2, 4, 3, 0, 1]
|
133
135
|
permutation = PermutationGate(A)
|
134
136
|
circuit = QuantumCircuit(5)
|
135
137
|
circuit.append(permutation, [0, 1, 2, 3, 4])
|
@@ -141,7 +143,7 @@ class PermutationGate(Gate):
|
|
141
143
|
raise CircuitError(
|
142
144
|
"Permutation pattern must be some ordering of 0..num_qubits-1 in a list."
|
143
145
|
)
|
144
|
-
pattern = np.array(pattern)
|
146
|
+
pattern = np.array(pattern, dtype=np.int32)
|
145
147
|
|
146
148
|
super().__init__(name="permutation", num_qubits=num_qubits, params=[pattern])
|
147
149
|
|
@@ -168,11 +170,11 @@ class PermutationGate(Gate):
|
|
168
170
|
return parameter
|
169
171
|
|
170
172
|
@property
|
171
|
-
def pattern(self):
|
173
|
+
def pattern(self) -> np.ndarray[bool]:
|
172
174
|
"""Returns the permutation pattern defining this permutation."""
|
173
175
|
return self.params[0]
|
174
176
|
|
175
|
-
def inverse(self, annotated: bool = False):
|
177
|
+
def inverse(self, annotated: bool = False) -> PermutationGate:
|
176
178
|
"""Returns the inverse of the permutation."""
|
177
179
|
|
178
180
|
# pylint: disable=cyclic-import
|
@@ -27,7 +27,7 @@ class RVGate(Gate):
|
|
27
27
|
|
28
28
|
**Circuit symbol:**
|
29
29
|
|
30
|
-
..
|
30
|
+
.. code-block:: text
|
31
31
|
|
32
32
|
┌─────────────────┐
|
33
33
|
q_0: ┤ RV(v_x,v_y,v_z) ├
|
@@ -51,14 +51,13 @@ class RVGate(Gate):
|
|
51
51
|
\end{pmatrix}
|
52
52
|
"""
|
53
53
|
|
54
|
-
def __init__(self, v_x, v_y, v_z, basis="U"):
|
55
|
-
"""
|
56
|
-
|
54
|
+
def __init__(self, v_x: float, v_y: float, v_z: float, basis: str = "U"):
|
55
|
+
"""
|
57
56
|
Args:
|
58
|
-
v_x
|
59
|
-
v_y
|
60
|
-
v_z
|
61
|
-
basis
|
57
|
+
v_x: x-component
|
58
|
+
v_y: y-component
|
59
|
+
v_z: z-component
|
60
|
+
basis: basis (see
|
62
61
|
:class:`~qiskit.synthesis.one_qubit.one_qubit_decompose.OneQubitEulerDecomposer`)
|
63
62
|
"""
|
64
63
|
# pylint: disable=cyclic-import
|
@@ -80,7 +79,7 @@ class RVGate(Gate):
|
|
80
79
|
vx, vy, vz = self.params
|
81
80
|
return RVGate(-vx, -vy, -vz)
|
82
81
|
|
83
|
-
def to_matrix(self):
|
82
|
+
def to_matrix(self) -> numpy.ndarray:
|
84
83
|
"""Return a numpy.array for the R(v) gate."""
|
85
84
|
v = numpy.asarray(self.params, dtype=float)
|
86
85
|
angle = math.sqrt(v.dot(v))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# This code is part of Qiskit.
|
2
2
|
#
|
3
|
-
# (C) Copyright IBM 2017,
|
3
|
+
# (C) Copyright IBM 2017, 2024.
|
4
4
|
#
|
5
5
|
# This code is licensed under the Apache License, Version 2.0. You may
|
6
6
|
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
@@ -10,13 +10,14 @@
|
|
10
10
|
# copyright notice, and modified files need to carry a notice indicating
|
11
11
|
# that they have been altered from the originals.
|
12
12
|
|
13
|
-
"""Graph State circuit."""
|
13
|
+
"""Graph State circuit and gate."""
|
14
14
|
|
15
15
|
from __future__ import annotations
|
16
16
|
|
17
17
|
import numpy as np
|
18
|
-
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
18
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit, Gate
|
19
19
|
from qiskit.circuit.exceptions import CircuitError
|
20
|
+
from qiskit.utils.deprecation import deprecate_func
|
20
21
|
|
21
22
|
|
22
23
|
class GraphState(QuantumCircuit):
|
@@ -56,6 +57,11 @@ class GraphState(QuantumCircuit):
|
|
56
57
|
`arXiv:1512.07892 <https://arxiv.org/pdf/1512.07892.pdf>`_
|
57
58
|
"""
|
58
59
|
|
60
|
+
@deprecate_func(
|
61
|
+
since="1.3",
|
62
|
+
additional_msg="Use qiskit.circuit.library.GraphStateGate instead.",
|
63
|
+
pending=True,
|
64
|
+
)
|
59
65
|
def __init__(self, adjacency_matrix: list | np.ndarray) -> None:
|
60
66
|
"""Create graph state preparation circuit.
|
61
67
|
|
@@ -73,14 +79,91 @@ class GraphState(QuantumCircuit):
|
|
73
79
|
if not np.allclose(adjacency_matrix, adjacency_matrix.transpose()):
|
74
80
|
raise CircuitError("The adjacency matrix must be symmetric.")
|
75
81
|
|
82
|
+
graph_state_gate = GraphStateGate(adjacency_matrix)
|
83
|
+
super().__init__(graph_state_gate.num_qubits, name=f"graph: {adjacency_matrix}")
|
84
|
+
self.compose(graph_state_gate, qubits=self.qubits, inplace=True)
|
85
|
+
|
86
|
+
|
87
|
+
class GraphStateGate(Gate):
|
88
|
+
r"""A gate representing a graph state.
|
89
|
+
|
90
|
+
Given a graph G = (V, E), with the set of vertices V and the set of edges E,
|
91
|
+
the corresponding graph state is defined as
|
92
|
+
|
93
|
+
.. math::
|
94
|
+
|
95
|
+
|G\rangle = \prod_{(a,b) \in E} CZ_{(a,b)} {|+\rangle}^{\otimes V}
|
96
|
+
|
97
|
+
Such a state can be prepared by first preparing all qubits in the :math:`+`
|
98
|
+
state, then applying a :math:`CZ` gate for each corresponding graph edge.
|
99
|
+
|
100
|
+
Graph state preparation circuits are Clifford circuits, and thus
|
101
|
+
easy to simulate classically. However, by adding a layer of measurements
|
102
|
+
in a product basis at the end, there is evidence that the circuit becomes
|
103
|
+
hard to simulate [2].
|
104
|
+
|
105
|
+
**Reference Circuit:**
|
106
|
+
|
107
|
+
.. plot::
|
108
|
+
:include-source:
|
109
|
+
|
110
|
+
from qiskit.circuit import QuantumCircuit
|
111
|
+
from qiskit.circuit.library import GraphStateGate
|
112
|
+
import rustworkx as rx
|
113
|
+
|
114
|
+
G = rx.generators.cycle_graph(5)
|
115
|
+
circuit = QuantumCircuit(5)
|
116
|
+
circuit.append(GraphStateGate(rx.adjacency_matrix(G)), [0, 1, 2, 3, 4])
|
117
|
+
circuit.decompose().draw('mpl')
|
118
|
+
|
119
|
+
**References:**
|
120
|
+
|
121
|
+
[1] M. Hein, J. Eisert, H.J. Briegel, Multi-party Entanglement in Graph States,
|
122
|
+
`arXiv:0307130 <https://arxiv.org/pdf/quant-ph/0307130.pdf>`_
|
123
|
+
[2] D. Koh, Further Extensions of Clifford Circuits & their Classical Simulation Complexities.
|
124
|
+
`arXiv:1512.07892 <https://arxiv.org/pdf/1512.07892.pdf>`_
|
125
|
+
"""
|
126
|
+
|
127
|
+
def __init__(self, adjacency_matrix: list | np.ndarray) -> None:
|
128
|
+
"""
|
129
|
+
Args:
|
130
|
+
adjacency_matrix: input graph as n-by-n list of 0-1 lists
|
131
|
+
|
132
|
+
Raises:
|
133
|
+
CircuitError: If adjacency_matrix is not symmetric.
|
134
|
+
|
135
|
+
The gate represents a graph state with the given adjacency matrix.
|
136
|
+
"""
|
137
|
+
|
138
|
+
adjacency_matrix = np.asarray(adjacency_matrix)
|
139
|
+
if not np.allclose(adjacency_matrix, adjacency_matrix.transpose()):
|
140
|
+
raise CircuitError("The adjacency matrix must be symmetric.")
|
76
141
|
num_qubits = len(adjacency_matrix)
|
77
|
-
circuit = QuantumCircuit(num_qubits, name=f"graph: {adjacency_matrix}")
|
78
142
|
|
79
|
-
|
80
|
-
|
81
|
-
|
143
|
+
super().__init__(name="graph_state", num_qubits=num_qubits, params=[adjacency_matrix])
|
144
|
+
|
145
|
+
def _define(self):
|
146
|
+
adjacency_matrix = self.adjacency_matrix
|
147
|
+
circuit = QuantumCircuit(self.num_qubits, name=self.name)
|
148
|
+
circuit.h(range(self.num_qubits))
|
149
|
+
for i in range(self.num_qubits):
|
150
|
+
for j in range(i + 1, self.num_qubits):
|
82
151
|
if adjacency_matrix[i][j] == 1:
|
83
152
|
circuit.cz(i, j)
|
84
|
-
|
85
|
-
|
86
|
-
|
153
|
+
self.definition = circuit
|
154
|
+
|
155
|
+
def validate_parameter(self, parameter):
|
156
|
+
"""Parameter validation"""
|
157
|
+
return parameter
|
158
|
+
|
159
|
+
@property
|
160
|
+
def adjacency_matrix(self):
|
161
|
+
"""Returns the adjacency matrix."""
|
162
|
+
return self.params[0]
|
163
|
+
|
164
|
+
def __eq__(self, other):
|
165
|
+
return (
|
166
|
+
isinstance(other, GraphStateGate)
|
167
|
+
and self.num_qubits == other.num_qubits
|
168
|
+
and np.all(self.adjacency_matrix == other.adjacency_matrix)
|
169
|
+
)
|