qiskit 1.3.0__cp39-abi3-win32.whl → 1.3.0b1__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 +1 -20
- qiskit/_accelerate.pyd +0 -0
- qiskit/assembler/assemble_schedules.py +0 -2
- qiskit/circuit/__init__.py +1 -44
- qiskit/circuit/_standard_gates_commutations.py +0 -585
- qiskit/circuit/barrier.py +0 -2
- qiskit/circuit/controlflow/builder.py +3 -3
- qiskit/circuit/controlflow/if_else.py +5 -13
- qiskit/circuit/controlflow/while_loop.py +2 -10
- qiskit/circuit/delay.py +3 -20
- qiskit/circuit/equivalence.py +214 -13
- qiskit/circuit/gate.py +1 -3
- qiskit/circuit/instruction.py +11 -32
- qiskit/circuit/instructionset.py +0 -2
- qiskit/circuit/library/__init__.py +14 -110
- qiskit/circuit/library/arithmetic/__init__.py +2 -9
- qiskit/circuit/library/arithmetic/adders/__init__.py +0 -1
- qiskit/circuit/library/arithmetic/adders/adder.py +2 -154
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +56 -20
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +1 -14
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +91 -21
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +0 -1
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -8
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +3 -94
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +1 -8
- qiskit/circuit/library/arithmetic/weighted_adder.py +1 -1
- qiskit/circuit/library/basis_change/qft.py +38 -20
- qiskit/circuit/library/blueprintcircuit.py +0 -64
- qiskit/circuit/library/boolean_logic/__init__.py +4 -4
- qiskit/circuit/library/boolean_logic/inner_product.py +4 -81
- qiskit/circuit/library/boolean_logic/quantum_and.py +4 -107
- qiskit/circuit/library/boolean_logic/quantum_or.py +3 -107
- qiskit/circuit/library/boolean_logic/quantum_xor.py +3 -97
- qiskit/circuit/library/data_preparation/__init__.py +3 -6
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +29 -342
- qiskit/circuit/library/data_preparation/{_z_feature_map.py → z_feature_map.py} +34 -45
- qiskit/circuit/library/data_preparation/zz_feature_map.py +118 -0
- qiskit/circuit/library/fourier_checking.py +11 -72
- qiskit/circuit/library/generalized_gates/__init__.py +1 -1
- qiskit/circuit/library/generalized_gates/diagonal.py +51 -45
- qiskit/circuit/library/generalized_gates/gms.py +14 -67
- 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 +6 -12
- qiskit/circuit/library/generalized_gates/mcmt.py +107 -167
- qiskit/circuit/library/generalized_gates/permutation.py +6 -8
- qiskit/circuit/library/generalized_gates/rv.py +9 -8
- qiskit/circuit/library/graph_state.py +10 -93
- qiskit/circuit/library/grover_operator.py +2 -270
- qiskit/circuit/library/hidden_linear_function.py +20 -83
- qiskit/circuit/library/iqp.py +20 -99
- qiskit/circuit/library/n_local/__init__.py +7 -19
- qiskit/circuit/library/n_local/efficient_su2.py +5 -118
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +0 -259
- qiskit/circuit/library/n_local/excitation_preserving.py +6 -130
- qiskit/circuit/library/n_local/n_local.py +5 -406
- qiskit/circuit/library/n_local/pauli_two_design.py +4 -106
- qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -80
- qiskit/circuit/library/n_local/real_amplitudes.py +7 -127
- qiskit/circuit/library/n_local/two_local.py +7 -14
- qiskit/circuit/library/overlap.py +26 -91
- qiskit/circuit/library/pauli_evolution.py +15 -17
- qiskit/circuit/library/phase_estimation.py +4 -80
- qiskit/circuit/library/quantum_volume.py +20 -72
- qiskit/circuit/library/standard_gates/__init__.py +1 -20
- qiskit/circuit/library/standard_gates/dcx.py +1 -2
- qiskit/circuit/library/standard_gates/ecr.py +2 -2
- qiskit/circuit/library/standard_gates/h.py +3 -4
- qiskit/circuit/library/standard_gates/i.py +1 -2
- qiskit/circuit/library/standard_gates/iswap.py +2 -2
- qiskit/circuit/library/standard_gates/p.py +12 -20
- qiskit/circuit/library/standard_gates/r.py +1 -1
- qiskit/circuit/library/standard_gates/rx.py +3 -4
- qiskit/circuit/library/standard_gates/rxx.py +2 -2
- qiskit/circuit/library/standard_gates/ry.py +3 -4
- qiskit/circuit/library/standard_gates/ryy.py +2 -2
- qiskit/circuit/library/standard_gates/rz.py +12 -13
- 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 +3 -4
- qiskit/circuit/library/standard_gates/t.py +2 -2
- qiskit/circuit/library/standard_gates/u.py +3 -11
- qiskit/circuit/library/standard_gates/u1.py +15 -65
- qiskit/circuit/library/standard_gates/u2.py +1 -4
- qiskit/circuit/library/standard_gates/u3.py +3 -31
- qiskit/circuit/library/standard_gates/x.py +5 -7
- 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 +3 -4
- qiskit/circuit/library/standard_gates/z.py +3 -3
- qiskit/circuit/library/templates/clifford/clifford_2_1.py +8 -9
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +7 -9
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +8 -9
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +8 -9
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +8 -9
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +9 -10
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +7 -9
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +8 -10
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +14 -16
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +12 -14
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +12 -14
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +9 -11
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +9 -11
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +9 -11
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +9 -11
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +10 -12
- qiskit/circuit/library/templates/rzx/rzx_cy.py +10 -11
- qiskit/circuit/library/templates/rzx/rzx_xz.py +15 -16
- qiskit/circuit/library/templates/rzx/rzx_yz.py +10 -12
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +20 -22
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +15 -16
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +15 -17
- qiskit/circuit/parameter.py +0 -4
- qiskit/circuit/parameterexpression.py +34 -167
- qiskit/circuit/quantumcircuit.py +126 -162
- qiskit/circuit/singleton.py +0 -2
- qiskit/circuit/store.py +0 -2
- qiskit/compiler/assembler.py +4 -17
- qiskit/compiler/scheduler.py +0 -2
- qiskit/compiler/sequencer.py +0 -2
- qiskit/compiler/transpiler.py +26 -81
- 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 +5 -7
- qiskit/converters/dag_to_dagdependency.py +1 -1
- qiskit/converters/dag_to_dagdependency_v2.py +1 -1
- qiskit/converters/dagdependency_to_circuit.py +1 -5
- qiskit/converters/dagdependency_to_dag.py +1 -6
- qiskit/dagcircuit/collect_blocks.py +3 -3
- qiskit/dagcircuit/dagdependency.py +5 -18
- qiskit/dagcircuit/dagdependency_v2.py +1 -1
- qiskit/dagcircuit/dagnode.py +2 -2
- qiskit/passmanager/__init__.py +2 -2
- qiskit/primitives/backend_estimator.py +2 -5
- qiskit/primitives/backend_sampler_v2.py +18 -61
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +1 -9
- qiskit/primitives/statevector_sampler.py +1 -1
- qiskit/primitives/utils.py +1 -1
- qiskit/providers/__init__.py +3 -3
- qiskit/providers/backend.py +1 -12
- qiskit/providers/backend_compat.py +3 -23
- qiskit/providers/basic_provider/basic_simulator.py +2 -12
- qiskit/providers/fake_provider/fake_pulse_backend.py +1 -6
- qiskit/providers/fake_provider/generic_backend_v2.py +30 -46
- qiskit/providers/models/pulsedefaults.py +0 -2
- qiskit/pulse/builder.py +18 -59
- qiskit/pulse/calibration_entries.py +1 -4
- qiskit/pulse/channels.py +0 -2
- qiskit/pulse/exceptions.py +0 -2
- qiskit/pulse/instruction_schedule_map.py +6 -21
- qiskit/pulse/instructions/acquire.py +0 -2
- qiskit/pulse/instructions/delay.py +0 -2
- qiskit/pulse/instructions/directives.py +0 -8
- qiskit/pulse/instructions/frequency.py +0 -3
- qiskit/pulse/instructions/instruction.py +0 -2
- qiskit/pulse/instructions/phase.py +0 -3
- qiskit/pulse/instructions/play.py +0 -2
- qiskit/pulse/instructions/reference.py +0 -2
- qiskit/pulse/instructions/snapshot.py +0 -2
- qiskit/pulse/library/pulse.py +0 -2
- qiskit/pulse/library/symbolic_pulses.py +0 -28
- qiskit/pulse/library/waveform.py +0 -2
- qiskit/pulse/macros.py +1 -1
- qiskit/pulse/schedule.py +13 -12
- qiskit/pulse/transforms/alignments.py +3 -5
- qiskit/pulse/transforms/dag.py +0 -7
- qiskit/qasm2/export.py +3 -5
- qiskit/qasm2/parse.py +2 -46
- qiskit/qasm3/__init__.py +0 -1
- qiskit/qasm3/ast.py +15 -123
- qiskit/qasm3/exporter.py +77 -103
- qiskit/qobj/converters/pulse_instruction.py +4 -6
- qiskit/qpy/__init__.py +0 -181
- qiskit/qpy/binary_io/circuits.py +5 -20
- qiskit/qpy/binary_io/schedules.py +4 -3
- qiskit/qpy/binary_io/value.py +13 -310
- qiskit/qpy/common.py +2 -46
- qiskit/qpy/formats.py +0 -7
- qiskit/qpy/interface.py +4 -40
- qiskit/quantum_info/__init__.py +0 -4
- qiskit/quantum_info/operators/channel/transformations.py +21 -28
- qiskit/quantum_info/operators/dihedral/dihedral.py +1 -1
- qiskit/quantum_info/operators/operator.py +8 -54
- qiskit/quantum_info/operators/symplectic/base_pauli.py +19 -11
- 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 +0 -2
- qiskit/quantum_info/operators/symplectic/pauli_list.py +4 -4
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +2 -23
- 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 +1 -9
- qiskit/result/mitigation/local_readout_mitigator.py +1 -9
- qiskit/result/mitigation/utils.py +0 -57
- qiskit/scheduler/config.py +0 -2
- qiskit/scheduler/methods/basic.py +0 -3
- qiskit/scheduler/schedule_circuit.py +0 -2
- qiskit/scheduler/sequence.py +0 -2
- qiskit/synthesis/__init__.py +0 -25
- qiskit/synthesis/clifford/clifford_decompose_bm.py +2 -1
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +2 -3
- qiskit/synthesis/clifford/clifford_decompose_layers.py +1 -2
- qiskit/synthesis/evolution/__init__.py +0 -1
- qiskit/synthesis/evolution/lie_trotter.py +42 -16
- qiskit/synthesis/evolution/product_formula.py +238 -165
- qiskit/synthesis/evolution/qdrift.py +29 -36
- qiskit/synthesis/evolution/suzuki_trotter.py +27 -87
- qiskit/synthesis/multi_controlled/__init__.py +0 -1
- qiskit/synthesis/qft/qft_decompose_full.py +1 -19
- qiskit/synthesis/qft/qft_decompose_lnn.py +1 -2
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +1 -2
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +63 -4
- qiskit/synthesis/two_qubit/weyl.py +97 -0
- qiskit/synthesis/unitary/qsd.py +5 -5
- qiskit/transpiler/__init__.py +14 -21
- qiskit/transpiler/basepasses.py +1 -1
- qiskit/transpiler/passes/__init__.py +0 -2
- qiskit/transpiler/passes/basis/basis_translator.py +565 -9
- qiskit/transpiler/passes/basis/decompose.py +12 -45
- 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 +2 -4
- qiskit/transpiler/passes/calibration/rx_builder.py +7 -11
- qiskit/transpiler/passes/calibration/rzx_builder.py +30 -46
- qiskit/transpiler/passes/layout/disjoint_utils.py +13 -15
- qiskit/transpiler/passes/layout/sabre_layout.py +2 -7
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +0 -5
- qiskit/transpiler/passes/optimization/__init__.py +0 -1
- qiskit/transpiler/passes/optimization/collect_cliffords.py +3 -19
- 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 +131 -48
- qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +2 -4
- qiskit/transpiler/passes/optimization/elide_permutations.py +32 -9
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +0 -2
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +11 -5
- 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/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 +3 -7
- 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 +0 -2
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +2 -2
- qiskit/transpiler/passes/scheduling/asap.py +1 -1
- qiskit/transpiler/passes/scheduling/base_scheduler.py +12 -14
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +4 -9
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +5 -16
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +1 -4
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +2 -6
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -9
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +99 -262
- qiskit/transpiler/passes/synthesis/hls_plugins.py +7 -638
- qiskit/transpiler/passes/synthesis/qubit_tracker.py +132 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +3 -3
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -55
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +56 -2
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -5
- qiskit/transpiler/passes/utils/gate_direction.py +275 -12
- qiskit/transpiler/passes/utils/gates_basis.py +30 -7
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +1 -2
- qiskit/transpiler/passmanager_config.py +4 -22
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +14 -40
- qiskit/transpiler/preset_passmanagers/common.py +3 -5
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +42 -125
- qiskit/transpiler/preset_passmanagers/plugin.py +1 -1
- qiskit/transpiler/target.py +16 -74
- qiskit/visualization/circuit/_utils.py +2 -2
- qiskit/visualization/circuit/circuit_visualization.py +2 -3
- qiskit/visualization/circuit/matplotlib.py +1 -1
- qiskit/visualization/dag_visualization.py +1 -1
- qiskit/visualization/pass_manager_visualization.py +14 -3
- qiskit/visualization/pulse_v2/interface.py +1 -3
- qiskit/visualization/timeline/core.py +2 -25
- qiskit/visualization/timeline/interface.py +0 -12
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/METADATA +19 -20
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/RECORD +347 -358
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/WHEEL +1 -1
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/entry_points.txt +0 -19
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +0 -150
- qiskit/circuit/twirling.py +0 -145
- qiskit/synthesis/arithmetic/__init__.py +0 -16
- qiskit/synthesis/arithmetic/adders/__init__.py +0 -17
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +0 -154
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +0 -103
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +0 -161
- qiskit/synthesis/arithmetic/multipliers/__init__.py +0 -16
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +0 -102
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +0 -99
- qiskit/synthesis/evolution/pauli_network.py +0 -80
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +0 -52
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +0 -69
- qiskit/utils/deprecate_pulse.py +0 -119
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/top_level.txt +0 -0
qiskit/synthesis/__init__.py
CHANGED
@@ -125,7 +125,6 @@ Two-Qubit Synthesis
|
|
125
125
|
Multi Controlled Synthesis
|
126
126
|
==========================
|
127
127
|
|
128
|
-
.. autofunction:: synth_mcmt_vchain
|
129
128
|
.. autofunction:: synth_mcx_n_dirty_i15
|
130
129
|
.. autofunction:: synth_mcx_n_clean_m15
|
131
130
|
.. autofunction:: synth_mcx_1_clean_b95
|
@@ -134,22 +133,6 @@ Multi Controlled Synthesis
|
|
134
133
|
.. autofunction:: synth_c3x
|
135
134
|
.. autofunction:: synth_c4x
|
136
135
|
|
137
|
-
Binary Arithmetic Synthesis
|
138
|
-
===========================
|
139
|
-
|
140
|
-
Adders
|
141
|
-
------
|
142
|
-
|
143
|
-
.. autofunction:: adder_qft_d00
|
144
|
-
.. autofunction:: adder_ripple_c04
|
145
|
-
.. autofunction:: adder_ripple_v95
|
146
|
-
|
147
|
-
Multipliers
|
148
|
-
-----------
|
149
|
-
|
150
|
-
.. autofunction:: multiplier_cumulative_h18
|
151
|
-
.. autofunction:: multiplier_qft_r17
|
152
|
-
|
153
136
|
"""
|
154
137
|
|
155
138
|
from .evolution import (
|
@@ -202,7 +185,6 @@ from .two_qubit.two_qubit_decompose import (
|
|
202
185
|
TwoQubitWeylDecomposition,
|
203
186
|
)
|
204
187
|
from .multi_controlled import (
|
205
|
-
synth_mcmt_vchain,
|
206
188
|
synth_mcx_n_dirty_i15,
|
207
189
|
synth_mcx_n_clean_m15,
|
208
190
|
synth_mcx_1_clean_b95,
|
@@ -211,10 +193,3 @@ from .multi_controlled import (
|
|
211
193
|
synth_c3x,
|
212
194
|
synth_c4x,
|
213
195
|
)
|
214
|
-
from .arithmetic import (
|
215
|
-
adder_qft_d00,
|
216
|
-
adder_ripple_c04,
|
217
|
-
adder_ripple_v95,
|
218
|
-
multiplier_cumulative_h18,
|
219
|
-
multiplier_qft_r17,
|
220
|
-
)
|
@@ -41,6 +41,7 @@ def synth_clifford_bm(clifford: Clifford) -> QuantumCircuit:
|
|
41
41
|
`arXiv:2003.09412 [quant-ph] <https://arxiv.org/abs/2003.09412>`_
|
42
42
|
"""
|
43
43
|
circuit = QuantumCircuit._from_circuit_data(
|
44
|
-
synth_clifford_bm_inner(clifford.tableau.astype(bool)), add_regs=True
|
44
|
+
synth_clifford_bm_inner(clifford.tableau.astype(bool)), add_regs=True
|
45
45
|
)
|
46
|
+
circuit.name = str(clifford)
|
46
47
|
return circuit
|
@@ -51,8 +51,7 @@ def synth_clifford_greedy(clifford: Clifford) -> QuantumCircuit:
|
|
51
51
|
`arXiv:2105.02291 [quant-ph] <https://arxiv.org/abs/2105.02291>`_
|
52
52
|
"""
|
53
53
|
circuit = QuantumCircuit._from_circuit_data(
|
54
|
-
synth_clifford_greedy_inner(clifford.tableau.astype(bool)),
|
55
|
-
add_regs=True,
|
56
|
-
name=str(clifford),
|
54
|
+
synth_clifford_greedy_inner(clifford.tableau.astype(bool)), add_regs=True
|
57
55
|
)
|
56
|
+
circuit.name = str(clifford)
|
58
57
|
return circuit
|
@@ -77,8 +77,7 @@ def synth_clifford_layers(
|
|
77
77
|
|
78
78
|
For example, a 5-qubit Clifford circuit is decomposed into the following layers:
|
79
79
|
|
80
|
-
..
|
81
|
-
|
80
|
+
.. parsed-literal::
|
82
81
|
┌─────┐┌─────┐┌────────┐┌─────┐┌─────┐┌─────┐┌─────┐┌────────┐
|
83
82
|
q_0: ┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├
|
84
83
|
│ ││ ││ ││ ││ ││ ││ ││ │
|
@@ -14,15 +14,18 @@
|
|
14
14
|
|
15
15
|
from __future__ import annotations
|
16
16
|
|
17
|
+
import inspect
|
17
18
|
from collections.abc import Callable
|
18
19
|
from typing import Any
|
20
|
+
import numpy as np
|
19
21
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
20
22
|
from qiskit.quantum_info.operators import SparsePauliOp, Pauli
|
23
|
+
from qiskit.utils.deprecation import deprecate_arg
|
21
24
|
|
22
|
-
from .
|
25
|
+
from .product_formula import ProductFormula
|
23
26
|
|
24
27
|
|
25
|
-
class LieTrotter(
|
28
|
+
class LieTrotter(ProductFormula):
|
26
29
|
r"""The Lie-Trotter product formula.
|
27
30
|
|
28
31
|
The Lie-Trotter formula approximates the exponential of two non-commuting operators
|
@@ -37,7 +40,7 @@ class LieTrotter(SuzukiTrotter):
|
|
37
40
|
|
38
41
|
.. math::
|
39
42
|
|
40
|
-
e^{-it(
|
43
|
+
e^{-it(XX + ZZ)} = e^{-it XX}e^{-it ZZ} + \mathcal{O}(t^2).
|
41
44
|
|
42
45
|
References:
|
43
46
|
|
@@ -49,6 +52,21 @@ class LieTrotter(SuzukiTrotter):
|
|
49
52
|
`arXiv:math-ph/0506007 <https://arxiv.org/pdf/math-ph/0506007.pdf>`_
|
50
53
|
"""
|
51
54
|
|
55
|
+
@deprecate_arg(
|
56
|
+
name="atomic_evolution",
|
57
|
+
since="1.2",
|
58
|
+
predicate=lambda callable: callable is not None
|
59
|
+
and len(inspect.signature(callable).parameters) == 2,
|
60
|
+
deprecation_description=(
|
61
|
+
"The 'Callable[[Pauli | SparsePauliOp, float], QuantumCircuit]' signature of the "
|
62
|
+
"'atomic_evolution' argument"
|
63
|
+
),
|
64
|
+
additional_msg=(
|
65
|
+
"Instead you should update your 'atomic_evolution' function to be of the following "
|
66
|
+
"type: 'Callable[[QuantumCircuit, Pauli | SparsePauliOp, float], None]'."
|
67
|
+
),
|
68
|
+
pending=True,
|
69
|
+
)
|
52
70
|
def __init__(
|
53
71
|
self,
|
54
72
|
reps: int = 1,
|
@@ -60,7 +78,6 @@ class LieTrotter(SuzukiTrotter):
|
|
60
78
|
| None
|
61
79
|
) = None,
|
62
80
|
wrap: bool = False,
|
63
|
-
preserve_order: bool = True,
|
64
81
|
) -> None:
|
65
82
|
"""
|
66
83
|
Args:
|
@@ -80,19 +97,28 @@ class LieTrotter(SuzukiTrotter):
|
|
80
97
|
built.
|
81
98
|
wrap: Whether to wrap the atomic evolutions into custom gate objects. This only takes
|
82
99
|
effect when ``atomic_evolution is None``.
|
83
|
-
preserve_order: If ``False``, allows reordering the terms of the operator to
|
84
|
-
potentially yield a shallower evolution circuit. Not relevant
|
85
|
-
when synthesizing operator with a single term.
|
86
100
|
"""
|
87
|
-
super().__init__(
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
)
|
101
|
+
super().__init__(1, reps, insert_barriers, cx_structure, atomic_evolution, wrap)
|
102
|
+
|
103
|
+
def synthesize(self, evolution):
|
104
|
+
# get operators and time to evolve
|
105
|
+
operators = evolution.operator
|
106
|
+
time = evolution.time
|
107
|
+
|
108
|
+
# construct the evolution circuit
|
109
|
+
single_rep = QuantumCircuit(operators[0].num_qubits)
|
110
|
+
|
111
|
+
if not isinstance(operators, list):
|
112
|
+
pauli_list = [(Pauli(op), np.real(coeff)) for op, coeff in operators.to_list()]
|
113
|
+
else:
|
114
|
+
pauli_list = [(op, 1) for op in operators]
|
115
|
+
|
116
|
+
for i, (op, coeff) in enumerate(pauli_list):
|
117
|
+
self.atomic_evolution(single_rep, op, coeff * time / self.reps)
|
118
|
+
if self.insert_barriers and i != len(pauli_list) - 1:
|
119
|
+
single_rep.barrier()
|
120
|
+
|
121
|
+
return single_rep.repeat(self.reps, insert_barriers=self.insert_barriers).decompose()
|
96
122
|
|
97
123
|
@property
|
98
124
|
def settings(self) -> dict[str, Any]:
|
@@ -15,26 +15,17 @@
|
|
15
15
|
from __future__ import annotations
|
16
16
|
|
17
17
|
import inspect
|
18
|
-
import
|
19
|
-
from
|
20
|
-
from
|
21
|
-
from itertools import combinations
|
22
|
-
import typing
|
18
|
+
from collections.abc import Callable
|
19
|
+
from typing import Any
|
20
|
+
from functools import partial
|
23
21
|
import numpy as np
|
24
|
-
import rustworkx as rx
|
25
22
|
from qiskit.circuit.parameterexpression import ParameterExpression
|
26
|
-
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
23
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
27
24
|
from qiskit.quantum_info import SparsePauliOp, Pauli
|
28
25
|
from qiskit.utils.deprecation import deprecate_arg
|
29
|
-
from qiskit._accelerate.circuit_library import pauli_evolution
|
30
26
|
|
31
27
|
from .evolution_synthesis import EvolutionSynthesis
|
32
28
|
|
33
|
-
if typing.TYPE_CHECKING:
|
34
|
-
from qiskit.circuit.library import PauliEvolutionGate
|
35
|
-
|
36
|
-
SparsePauliLabel = typing.Tuple[str, list[int], ParameterValueType]
|
37
|
-
|
38
29
|
|
39
30
|
class ProductFormula(EvolutionSynthesis):
|
40
31
|
"""Product formula base class for the decomposition of non-commuting operator exponentials.
|
@@ -69,7 +60,6 @@ class ProductFormula(EvolutionSynthesis):
|
|
69
60
|
| None
|
70
61
|
) = None,
|
71
62
|
wrap: bool = False,
|
72
|
-
preserve_order: bool = True,
|
73
63
|
) -> None:
|
74
64
|
"""
|
75
65
|
Args:
|
@@ -88,31 +78,24 @@ class ProductFormula(EvolutionSynthesis):
|
|
88
78
|
Alternatively, the function can also take Pauli operator and evolution time as
|
89
79
|
inputs and returns the circuit that will be appended to the overall circuit being
|
90
80
|
built.
|
91
|
-
wrap: Whether to wrap the atomic evolutions into custom gate objects.
|
92
|
-
|
93
|
-
``atomic_evolution is None``.
|
94
|
-
preserve_order: If ``False``, allows reordering the terms of the operator to
|
95
|
-
potentially yield a shallower evolution circuit. Not relevant
|
96
|
-
when synthesizing operator with a single term.
|
81
|
+
wrap: Whether to wrap the atomic evolutions into custom gate objects. This only takes
|
82
|
+
effect when ``atomic_evolution is None``.
|
97
83
|
"""
|
98
84
|
super().__init__()
|
99
85
|
self.order = order
|
100
86
|
self.reps = reps
|
101
87
|
self.insert_barriers = insert_barriers
|
102
|
-
self.preserve_order = preserve_order
|
103
88
|
|
104
89
|
# user-provided atomic evolution, stored for serialization
|
105
90
|
self._atomic_evolution = atomic_evolution
|
106
|
-
|
107
|
-
if cx_structure not in ["chain", "fountain"]:
|
108
|
-
raise ValueError(f"Unsupported CX structure: {cx_structure}")
|
109
|
-
|
110
91
|
self._cx_structure = cx_structure
|
111
92
|
self._wrap = wrap
|
112
93
|
|
113
94
|
# if atomic evolution is not provided, set a default
|
114
95
|
if atomic_evolution is None:
|
115
|
-
self.atomic_evolution =
|
96
|
+
self.atomic_evolution = partial(
|
97
|
+
_default_atomic_evolution, cx_structure=cx_structure, wrap=wrap
|
98
|
+
)
|
116
99
|
|
117
100
|
elif len(inspect.signature(atomic_evolution).parameters) == 2:
|
118
101
|
|
@@ -125,50 +108,8 @@ class ProductFormula(EvolutionSynthesis):
|
|
125
108
|
else:
|
126
109
|
self.atomic_evolution = atomic_evolution
|
127
110
|
|
128
|
-
def expand(
|
129
|
-
self, evolution: PauliEvolutionGate
|
130
|
-
) -> list[tuple[str, tuple[int], ParameterValueType]]:
|
131
|
-
"""Apply the product formula to expand the Hamiltonian in the evolution gate.
|
132
|
-
|
133
|
-
Args:
|
134
|
-
evolution: The :class:`.PauliEvolutionGate`, whose Hamiltonian we expand.
|
135
|
-
|
136
|
-
Returns:
|
137
|
-
A list of Pauli rotations in a sparse format, where each element is
|
138
|
-
``(paulistring, qubits, coefficient)``. For example, the Lie-Trotter expansion
|
139
|
-
of ``H = XI + ZZ`` would return ``[("X", [1], 1), ("ZZ", [0, 1], 1)]``.
|
140
|
-
"""
|
141
|
-
raise NotImplementedError(
|
142
|
-
f"The method ``expand`` is not implemented for {self.__class__}. Implement it to "
|
143
|
-
f"automatically enable the call to {self.__class__}.synthesize."
|
144
|
-
)
|
145
|
-
|
146
|
-
def synthesize(self, evolution: PauliEvolutionGate) -> QuantumCircuit:
|
147
|
-
"""Synthesize a :class:`.PauliEvolutionGate`.
|
148
|
-
|
149
|
-
Args:
|
150
|
-
evolution: The evolution gate to synthesize.
|
151
|
-
|
152
|
-
Returns:
|
153
|
-
QuantumCircuit: A circuit implementing the evolution.
|
154
|
-
"""
|
155
|
-
pauli_rotations = self.expand(evolution)
|
156
|
-
num_qubits = evolution.num_qubits
|
157
|
-
|
158
|
-
if self._wrap or self._atomic_evolution is not None:
|
159
|
-
# this is the slow path, where each Pauli evolution is constructed in Rust
|
160
|
-
# separately and then wrapped into a gate object
|
161
|
-
circuit = self._custom_evolution(num_qubits, pauli_rotations)
|
162
|
-
else:
|
163
|
-
# this is the fast path, where the whole evolution is constructed Rust-side
|
164
|
-
cx_fountain = self._cx_structure == "fountain"
|
165
|
-
data = pauli_evolution(num_qubits, pauli_rotations, self.insert_barriers, cx_fountain)
|
166
|
-
circuit = QuantumCircuit._from_circuit_data(data, add_regs=True)
|
167
|
-
|
168
|
-
return circuit
|
169
|
-
|
170
111
|
@property
|
171
|
-
def settings(self) -> dict[str,
|
112
|
+
def settings(self) -> dict[str, Any]:
|
172
113
|
"""Return the settings in a dictionary, which can be used to reconstruct the object.
|
173
114
|
|
174
115
|
Returns:
|
@@ -188,124 +129,256 @@ class ProductFormula(EvolutionSynthesis):
|
|
188
129
|
"insert_barriers": self.insert_barriers,
|
189
130
|
"cx_structure": self._cx_structure,
|
190
131
|
"wrap": self._wrap,
|
191
|
-
"preserve_order": self.preserve_order,
|
192
132
|
}
|
193
133
|
|
194
|
-
def _normalize_coefficients(
|
195
|
-
self, paulis: list[str | list[int], float | complex | ParameterExpression]
|
196
|
-
) -> list[str | list[int] | ParameterValueType]:
|
197
|
-
"""Ensure the coefficients are real (or parameter expressions)."""
|
198
|
-
return [[(op, qubits, real_or_fail(coeff)) for op, qubits, coeff in ops] for ops in paulis]
|
199
134
|
|
200
|
-
|
201
|
-
|
135
|
+
def evolve_pauli(
|
136
|
+
output: QuantumCircuit,
|
137
|
+
pauli: Pauli,
|
138
|
+
time: float | ParameterExpression = 1.0,
|
139
|
+
cx_structure: str = "chain",
|
140
|
+
wrap: bool = False,
|
141
|
+
label: str | None = None,
|
142
|
+
) -> None:
|
143
|
+
r"""Construct a circuit implementing the time evolution of a single Pauli string.
|
202
144
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
145
|
+
For a Pauli string :math:`P = \{I, X, Y, Z\}^{\otimes n}` on :math:`n` qubits and an
|
146
|
+
evolution time :math:`t`, the returned circuit implements the unitary operation
|
147
|
+
|
148
|
+
.. math::
|
149
|
+
|
150
|
+
U(t) = e^{-itP}.
|
151
|
+
|
152
|
+
Since only a single Pauli string is evolved the circuit decomposition is exact.
|
153
|
+
|
154
|
+
Args:
|
155
|
+
output: The circuit object to which to append the evolved Pauli.
|
156
|
+
pauli: The Pauli to evolve.
|
157
|
+
time: The evolution time.
|
158
|
+
cx_structure: Determine the structure of CX gates, can be either ``"chain"`` for
|
159
|
+
next-neighbor connections or ``"fountain"`` to connect directly to the top qubit.
|
160
|
+
wrap: Whether to wrap the single Pauli evolutions into custom gate objects.
|
161
|
+
label: A label for the gate.
|
162
|
+
"""
|
163
|
+
num_non_identity = len([label for label in pauli.to_label() if label != "I"])
|
164
|
+
|
165
|
+
# first check, if the Pauli is only the identity, in which case the evolution only
|
166
|
+
# adds a global phase
|
167
|
+
if num_non_identity == 0:
|
168
|
+
output.global_phase -= time
|
169
|
+
# if we evolve on a single qubit, if yes use the corresponding qubit rotation
|
170
|
+
elif num_non_identity == 1:
|
171
|
+
_single_qubit_evolution(output, pauli, time, wrap)
|
172
|
+
# same for two qubits, use Qiskit's native rotations
|
173
|
+
elif num_non_identity == 2:
|
174
|
+
_two_qubit_evolution(output, pauli, time, cx_structure, wrap)
|
175
|
+
# otherwise do basis transformation and CX chains
|
176
|
+
else:
|
177
|
+
_multi_qubit_evolution(output, pauli, time, cx_structure, wrap)
|
178
|
+
|
179
|
+
|
180
|
+
def _single_qubit_evolution(output, pauli, time, wrap):
|
181
|
+
dest = QuantumCircuit(1) if wrap else output
|
182
|
+
# Note that all phases are removed from the pauli label and are only in the coefficients.
|
183
|
+
# That's because the operators we evolved have all been translated to a SparsePauliOp.
|
184
|
+
qubits = []
|
185
|
+
label = ""
|
186
|
+
for i, pauli_i in enumerate(reversed(pauli.to_label())):
|
187
|
+
idx = 0 if wrap else i
|
188
|
+
if pauli_i == "X":
|
189
|
+
dest.rx(2 * time, idx)
|
190
|
+
qubits.append(i)
|
191
|
+
label += "X"
|
192
|
+
elif pauli_i == "Y":
|
193
|
+
dest.ry(2 * time, idx)
|
194
|
+
qubits.append(i)
|
195
|
+
label += "Y"
|
196
|
+
elif pauli_i == "Z":
|
197
|
+
dest.rz(2 * time, idx)
|
198
|
+
qubits.append(i)
|
199
|
+
label += "Z"
|
200
|
+
|
201
|
+
if wrap:
|
202
|
+
gate = dest.to_gate(label=f"exp(it {label})")
|
203
|
+
qubits = [output.qubits[q] for q in qubits]
|
204
|
+
output.append(gate, qargs=qubits, copy=False)
|
205
|
+
|
206
|
+
|
207
|
+
def _two_qubit_evolution(output, pauli, time, cx_structure, wrap):
|
208
|
+
# Get the Paulis and the qubits they act on.
|
209
|
+
# Note that all phases are removed from the pauli label and are only in the coefficients.
|
210
|
+
# That's because the operators we evolved have all been translated to a SparsePauliOp.
|
211
|
+
labels_as_array = np.array(list(reversed(pauli.to_label())))
|
212
|
+
qubits = np.where(labels_as_array != "I")[0]
|
213
|
+
indices = [0, 1] if wrap else qubits
|
214
|
+
labels = np.array([labels_as_array[idx] for idx in qubits])
|
215
|
+
|
216
|
+
dest = QuantumCircuit(2) if wrap else output
|
217
|
+
|
218
|
+
# go through all cases we have implemented in Qiskit
|
219
|
+
if all(labels == "X"): # RXX
|
220
|
+
dest.rxx(2 * time, indices[0], indices[1])
|
221
|
+
elif all(labels == "Y"): # RYY
|
222
|
+
dest.ryy(2 * time, indices[0], indices[1])
|
223
|
+
elif all(labels == "Z"): # RZZ
|
224
|
+
dest.rzz(2 * time, indices[0], indices[1])
|
225
|
+
elif labels[0] == "Z" and labels[1] == "X": # RZX
|
226
|
+
dest.rzx(2 * time, indices[0], indices[1])
|
227
|
+
elif labels[0] == "X" and labels[1] == "Z": # RXZ
|
228
|
+
dest.rzx(2 * time, indices[1], indices[0])
|
229
|
+
else: # all the others are not native in Qiskit, so use default the decomposition
|
230
|
+
_multi_qubit_evolution(output, pauli, time, cx_structure, wrap)
|
231
|
+
return
|
232
|
+
|
233
|
+
if wrap:
|
234
|
+
gate = dest.to_gate(label=f"exp(it {''.join(labels)})")
|
235
|
+
qubits = [output.qubits[q] for q in qubits]
|
236
|
+
output.append(gate, qargs=qubits, copy=False)
|
237
|
+
|
238
|
+
|
239
|
+
def _multi_qubit_evolution(output, pauli, time, cx_structure, wrap):
|
240
|
+
# get diagonalizing clifford
|
241
|
+
cliff = diagonalizing_clifford(pauli)
|
242
|
+
|
243
|
+
# get CX chain to reduce the evolution to the top qubit
|
244
|
+
if cx_structure == "chain":
|
245
|
+
chain = cnot_chain(pauli)
|
246
|
+
else:
|
247
|
+
chain = cnot_fountain(pauli)
|
248
|
+
|
249
|
+
# determine qubit to do the rotation on
|
250
|
+
target = None
|
251
|
+
# Note that all phases are removed from the pauli label and are only in the coefficients.
|
252
|
+
# That's because the operators we evolved have all been translated to a SparsePauliOp.
|
253
|
+
for i, pauli_i in enumerate(reversed(pauli.to_label())):
|
254
|
+
if pauli_i != "I":
|
255
|
+
target = i
|
256
|
+
break
|
257
|
+
|
258
|
+
# build the evolution as: diagonalization, reduction, 1q evolution, followed by inverses
|
259
|
+
dest = QuantumCircuit(pauli.num_qubits) if wrap else output
|
260
|
+
dest.compose(cliff, inplace=True)
|
261
|
+
dest.compose(chain, inplace=True)
|
262
|
+
dest.rz(2 * time, target)
|
263
|
+
dest.compose(chain.inverse(), inplace=True)
|
264
|
+
dest.compose(cliff.inverse(), inplace=True)
|
265
|
+
|
266
|
+
if wrap:
|
267
|
+
gate = dest.to_gate(label=f"exp(it {pauli.to_label()})")
|
268
|
+
output.append(gate, qargs=output.qubits, copy=False)
|
269
|
+
|
270
|
+
|
271
|
+
def diagonalizing_clifford(pauli: Pauli) -> QuantumCircuit:
|
272
|
+
"""Get the clifford circuit to diagonalize the Pauli operator.
|
208
273
|
|
209
|
-
|
210
|
-
|
211
|
-
if self._atomic_evolution is not None:
|
212
|
-
# use the user-provided evolution with a global operator
|
213
|
-
operator = SparsePauliOp.from_sparse_list([pauli_rotation], num_qubits)
|
214
|
-
self.atomic_evolution(circuit, operator, time=1) # time is inside the Pauli coeff
|
274
|
+
Args:
|
275
|
+
pauli: The Pauli to diagonalize.
|
215
276
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
277
|
+
Returns:
|
278
|
+
A circuit to diagonalize.
|
279
|
+
"""
|
280
|
+
cliff = QuantumCircuit(pauli.num_qubits)
|
281
|
+
for i, pauli_i in enumerate(reversed(pauli.to_label())):
|
282
|
+
if pauli_i == "Y":
|
283
|
+
cliff.sdg(i)
|
284
|
+
if pauli_i in ["X", "Y"]:
|
285
|
+
cliff.h(i)
|
221
286
|
|
222
|
-
|
223
|
-
data = pauli_evolution(
|
224
|
-
len(qubits),
|
225
|
-
[local_pauli],
|
226
|
-
False,
|
227
|
-
cx_fountain,
|
228
|
-
)
|
229
|
-
evo = QuantumCircuit._from_circuit_data(data)
|
287
|
+
return cliff
|
230
288
|
|
231
|
-
# and append it to the circuit with the correct label
|
232
|
-
gate = evo.to_gate(label=f"exp(it {pauli_string})")
|
233
|
-
circuit.append(gate, qubits)
|
234
289
|
|
235
|
-
|
236
|
-
|
290
|
+
def cnot_chain(pauli: Pauli) -> QuantumCircuit:
|
291
|
+
"""CX chain.
|
237
292
|
|
238
|
-
|
293
|
+
For example, for the Pauli with the label 'XYZIX'.
|
239
294
|
|
295
|
+
.. parsed-literal::
|
240
296
|
|
241
|
-
|
242
|
-
|
297
|
+
┌───┐
|
298
|
+
q_0: ──────────┤ X ├
|
299
|
+
└─┬─┘
|
300
|
+
q_1: ────────────┼──
|
301
|
+
┌───┐ │
|
302
|
+
q_2: ─────┤ X ├──■──
|
303
|
+
┌───┐└─┬─┘
|
304
|
+
q_3: ┤ X ├──■───────
|
305
|
+
└─┬─┘
|
306
|
+
q_4: ──■────────────
|
307
|
+
|
308
|
+
Args:
|
309
|
+
pauli: The Pauli for which to construct the CX chain.
|
243
310
|
|
244
|
-
|
311
|
+
Returns:
|
312
|
+
A circuit implementing the CX chain.
|
245
313
|
"""
|
246
|
-
if isinstance(value, ParameterExpression):
|
247
|
-
return value
|
248
314
|
|
249
|
-
|
250
|
-
|
251
|
-
return np.real(value)
|
315
|
+
chain = QuantumCircuit(pauli.num_qubits)
|
316
|
+
control, target = None, None
|
252
317
|
|
253
|
-
|
318
|
+
# iterate over the Pauli's and add CNOTs
|
319
|
+
for i, pauli_i in enumerate(pauli.to_label()):
|
320
|
+
i = pauli.num_qubits - i - 1
|
321
|
+
if pauli_i != "I":
|
322
|
+
if control is None:
|
323
|
+
control = i
|
324
|
+
else:
|
325
|
+
target = i
|
254
326
|
|
327
|
+
if control is not None and target is not None:
|
328
|
+
chain.cx(control, target)
|
329
|
+
control = i
|
330
|
+
target = None
|
255
331
|
|
256
|
-
|
257
|
-
paulis: Sequence[SparsePauliLabel],
|
258
|
-
strategy: rx.ColoringStrategy = rx.ColoringStrategy.Saturation,
|
259
|
-
) -> list[SparsePauliLabel]:
|
260
|
-
r"""
|
261
|
-
Creates an equivalent operator by reordering terms in order to yield a
|
262
|
-
shallower circuit after evolution synthesis. The original operator remains
|
263
|
-
unchanged.
|
332
|
+
return chain
|
264
333
|
|
265
|
-
This method works in three steps. First, a graph is constructed, where the
|
266
|
-
nodes are the terms of the operator and where two nodes are connected if
|
267
|
-
their terms act on the same qubit (for example, the terms :math:`IXX` and
|
268
|
-
:math:`IYI` would be connected, but not :math:`IXX` and :math:`YII`). Then,
|
269
|
-
the graph is colored. Two terms with the same color thus do not act on the
|
270
|
-
same qubit, and in particular, their evolution subcircuits can be run in
|
271
|
-
parallel in the greater evolution circuit of ``paulis``.
|
272
334
|
|
273
|
-
|
274
|
-
|
335
|
+
def cnot_fountain(pauli: Pauli) -> QuantumCircuit:
|
336
|
+
"""CX chain in the fountain shape.
|
275
337
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
Default is ``ColoringStrategy.Saturation``.
|
338
|
+
For example, for the Pauli with the label 'XYZIX'.
|
339
|
+
|
340
|
+
.. parsed-literal::
|
280
341
|
|
281
|
-
|
342
|
+
┌───┐┌───┐┌───┐
|
343
|
+
q_0: ┤ X ├┤ X ├┤ X ├
|
344
|
+
└─┬─┘└─┬─┘└─┬─┘
|
345
|
+
q_1: ──┼────┼────┼──
|
346
|
+
│ │ │
|
347
|
+
q_2: ──■────┼────┼──
|
348
|
+
│ │
|
349
|
+
q_3: ───────■────┼──
|
350
|
+
│
|
351
|
+
q_4: ────────────■──
|
352
|
+
|
353
|
+
Args:
|
354
|
+
pauli: The Pauli for which to construct the CX chain.
|
282
355
|
|
356
|
+
Returns:
|
357
|
+
A circuit implementing the CX chain.
|
283
358
|
"""
|
284
359
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
terms = list(itertools.chain(*terms_by_color.values()))
|
311
|
-
return terms
|
360
|
+
chain = QuantumCircuit(pauli.num_qubits)
|
361
|
+
control, target = None, None
|
362
|
+
for i, pauli_i in enumerate(reversed(pauli.to_label())):
|
363
|
+
if pauli_i != "I":
|
364
|
+
if target is None:
|
365
|
+
target = i
|
366
|
+
else:
|
367
|
+
control = i
|
368
|
+
|
369
|
+
if control is not None and target is not None:
|
370
|
+
chain.cx(control, target)
|
371
|
+
control = None
|
372
|
+
|
373
|
+
return chain
|
374
|
+
|
375
|
+
|
376
|
+
def _default_atomic_evolution(output, operator, time, cx_structure, wrap):
|
377
|
+
if isinstance(operator, Pauli):
|
378
|
+
# single Pauli operator: just exponentiate it
|
379
|
+
evolve_pauli(output, operator, time, cx_structure, wrap)
|
380
|
+
else:
|
381
|
+
# sum of Pauli operators: exponentiate each term (this assumes they commute)
|
382
|
+
pauli_list = [(Pauli(op), np.real(coeff)) for op, coeff in operator.to_list()]
|
383
|
+
for pauli, coeff in pauli_list:
|
384
|
+
evolve_pauli(output, pauli, coeff * time, cx_structure, wrap)
|