qiskit 1.4.0__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0rc1__cp39-abi3-macosx_11_0_arm64.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 +2 -5
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/__init__.py +24 -5
- qiskit/circuit/{add_control.py → _add_control.py} +32 -12
- qiskit/circuit/_classical_resource_map.py +5 -3
- qiskit/circuit/barrier.py +3 -7
- qiskit/circuit/classical/expr/__init__.py +31 -3
- qiskit/circuit/classical/expr/constructors.py +248 -28
- qiskit/circuit/classical/expr/expr.py +104 -3
- qiskit/circuit/classical/expr/visitors.py +75 -0
- qiskit/circuit/classical/types/__init__.py +12 -8
- qiskit/circuit/classical/types/ordering.py +14 -7
- qiskit/circuit/classical/types/types.py +36 -0
- qiskit/circuit/commutation_checker.py +34 -7
- qiskit/circuit/controlflow/__init__.py +32 -1
- qiskit/circuit/controlflow/_builder_utils.py +9 -5
- qiskit/circuit/controlflow/box.py +163 -0
- qiskit/circuit/controlflow/break_loop.py +1 -1
- qiskit/circuit/controlflow/builder.py +139 -39
- qiskit/circuit/controlflow/continue_loop.py +1 -3
- qiskit/circuit/controlflow/control_flow.py +10 -0
- qiskit/circuit/controlflow/for_loop.py +2 -1
- qiskit/circuit/controlflow/if_else.py +3 -16
- qiskit/circuit/controlflow/switch_case.py +2 -8
- qiskit/circuit/controlflow/while_loop.py +2 -7
- qiskit/circuit/controlledgate.py +2 -4
- qiskit/circuit/delay.py +40 -11
- qiskit/circuit/duration.py +0 -15
- qiskit/circuit/gate.py +2 -4
- qiskit/circuit/instruction.py +7 -140
- qiskit/circuit/instructionset.py +7 -54
- qiskit/circuit/library/__init__.py +34 -5
- qiskit/circuit/library/arithmetic/__init__.py +16 -10
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
- qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
- qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
- qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
- qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
- qiskit/circuit/library/bit_flip_oracle.py +130 -0
- qiskit/circuit/library/blueprintcircuit.py +52 -16
- qiskit/circuit/library/data_preparation/initializer.py +1 -1
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
- qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
- qiskit/circuit/library/generalized_gates/gms.py +1 -1
- qiskit/circuit/library/generalized_gates/isometry.py +1 -1
- qiskit/circuit/library/generalized_gates/pauli.py +1 -2
- qiskit/circuit/library/generalized_gates/uc.py +97 -7
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
- qiskit/circuit/library/generalized_gates/unitary.py +4 -2
- qiskit/circuit/library/hamiltonian_gate.py +1 -1
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
- qiskit/circuit/library/n_local/n_local.py +1 -1
- qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
- qiskit/circuit/library/overlap.py +2 -2
- qiskit/circuit/library/pauli_evolution.py +39 -24
- qiskit/circuit/library/phase_oracle.py +130 -51
- qiskit/circuit/library/standard_gates/__init__.py +0 -1
- qiskit/circuit/library/standard_gates/dcx.py +3 -4
- qiskit/circuit/library/standard_gates/ecr.py +3 -4
- qiskit/circuit/library/standard_gates/global_phase.py +5 -6
- qiskit/circuit/library/standard_gates/h.py +4 -9
- qiskit/circuit/library/standard_gates/i.py +2 -2
- qiskit/circuit/library/standard_gates/iswap.py +3 -4
- qiskit/circuit/library/standard_gates/p.py +15 -34
- qiskit/circuit/library/standard_gates/r.py +2 -6
- qiskit/circuit/library/standard_gates/rx.py +5 -15
- qiskit/circuit/library/standard_gates/rxx.py +3 -6
- qiskit/circuit/library/standard_gates/ry.py +5 -17
- qiskit/circuit/library/standard_gates/ryy.py +3 -6
- qiskit/circuit/library/standard_gates/rz.py +5 -17
- qiskit/circuit/library/standard_gates/rzx.py +3 -6
- qiskit/circuit/library/standard_gates/rzz.py +3 -6
- qiskit/circuit/library/standard_gates/s.py +6 -15
- qiskit/circuit/library/standard_gates/swap.py +4 -11
- qiskit/circuit/library/standard_gates/sx.py +7 -12
- qiskit/circuit/library/standard_gates/t.py +6 -7
- qiskit/circuit/library/standard_gates/u.py +2 -10
- qiskit/circuit/library/standard_gates/u1.py +5 -16
- qiskit/circuit/library/standard_gates/u2.py +2 -6
- qiskit/circuit/library/standard_gates/u3.py +3 -11
- qiskit/circuit/library/standard_gates/x.py +13 -60
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
- qiskit/circuit/library/standard_gates/y.py +4 -9
- qiskit/circuit/library/standard_gates/z.py +5 -15
- qiskit/circuit/measure.py +11 -2
- qiskit/circuit/parameterexpression.py +4 -0
- qiskit/circuit/quantumcircuit.py +881 -555
- qiskit/circuit/random/utils.py +12 -6
- qiskit/circuit/reset.py +5 -2
- qiskit/circuit/singleton.py +5 -11
- qiskit/circuit/store.py +0 -8
- qiskit/compiler/__init__.py +1 -7
- qiskit/compiler/transpiler.py +38 -196
- qiskit/converters/circuit_to_dag.py +4 -2
- qiskit/converters/circuit_to_dagdependency.py +0 -2
- qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
- qiskit/converters/circuit_to_gate.py +1 -1
- qiskit/converters/circuit_to_instruction.py +16 -29
- qiskit/converters/dag_to_circuit.py +5 -5
- qiskit/converters/dag_to_dagdependency.py +0 -1
- qiskit/converters/dag_to_dagdependency_v2.py +0 -1
- qiskit/converters/dagdependency_to_circuit.py +0 -6
- qiskit/converters/dagdependency_to_dag.py +0 -6
- qiskit/dagcircuit/collect_blocks.py +32 -20
- qiskit/dagcircuit/dagdependency.py +3 -37
- qiskit/dagcircuit/dagdependency_v2.py +2 -80
- qiskit/dagcircuit/dagnode.py +14 -2
- qiskit/passmanager/__init__.py +24 -6
- qiskit/passmanager/passmanager.py +26 -24
- qiskit/primitives/__init__.py +44 -35
- qiskit/primitives/backend_estimator_v2.py +102 -23
- qiskit/primitives/backend_sampler_v2.py +5 -20
- qiskit/primitives/base/__init__.py +4 -4
- qiskit/primitives/base/base_estimator.py +77 -82
- qiskit/primitives/base/base_primitive_job.py +2 -2
- qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
- qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
- qiskit/primitives/base/base_sampler.py +52 -60
- qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
- qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
- qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
- qiskit/primitives/containers/bindings_array.py +3 -1
- qiskit/primitives/containers/bit_array.py +23 -0
- qiskit/primitives/containers/data_bin.py +3 -1
- qiskit/primitives/containers/observables_array.py +19 -2
- qiskit/primitives/statevector_sampler.py +6 -8
- qiskit/primitives/utils.py +14 -189
- qiskit/providers/__init__.py +4 -130
- qiskit/providers/backend.py +11 -314
- qiskit/providers/basic_provider/__init__.py +3 -1
- qiskit/providers/basic_provider/basic_provider.py +29 -9
- qiskit/providers/basic_provider/basic_simulator.py +158 -298
- qiskit/providers/exceptions.py +0 -33
- qiskit/providers/fake_provider/__init__.py +0 -37
- qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
- qiskit/qasm2/__init__.py +21 -6
- qiskit/qasm2/export.py +2 -10
- qiskit/qasm2/parse.py +11 -25
- qiskit/qasm3/__init__.py +5 -1
- qiskit/qasm3/ast.py +44 -0
- qiskit/qasm3/exporter.py +65 -27
- qiskit/qasm3/printer.py +35 -4
- qiskit/qpy/__init__.py +141 -19
- qiskit/qpy/binary_io/__init__.py +0 -1
- qiskit/qpy/binary_io/circuits.py +91 -116
- qiskit/qpy/binary_io/schedules.py +61 -388
- qiskit/qpy/binary_io/value.py +168 -28
- qiskit/qpy/common.py +10 -7
- qiskit/qpy/formats.py +41 -0
- qiskit/qpy/interface.py +29 -62
- qiskit/qpy/type_keys.py +58 -221
- qiskit/quantum_info/analysis/distance.py +3 -1
- qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
- qiskit/quantum_info/operators/operator.py +6 -2
- qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
- qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
- qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
- qiskit/quantum_info/states/densitymatrix.py +16 -6
- qiskit/quantum_info/states/stabilizerstate.py +35 -4
- qiskit/quantum_info/states/statevector.py +16 -6
- qiskit/result/__init__.py +5 -17
- qiskit/result/models.py +18 -10
- qiskit/result/result.py +28 -126
- qiskit/result/sampled_expval.py +1 -2
- qiskit/result/utils.py +3 -4
- qiskit/synthesis/__init__.py +21 -1
- qiskit/synthesis/arithmetic/__init__.py +3 -1
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
- qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
- qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
- qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
- qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
- qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
- 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/discrete_basis/generate_basis_approximations.py +2 -0
- qiskit/synthesis/evolution/lie_trotter.py +10 -7
- qiskit/synthesis/evolution/product_formula.py +44 -35
- qiskit/synthesis/evolution/qdrift.py +17 -24
- qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
- qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
- qiskit/synthesis/multi_controlled/__init__.py +1 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
- qiskit/synthesis/two_qubit/__init__.py +1 -0
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
- qiskit/transpiler/__init__.py +32 -232
- qiskit/transpiler/basepasses.py +20 -51
- qiskit/transpiler/layout.py +1 -1
- qiskit/transpiler/passes/__init__.py +2 -40
- qiskit/transpiler/passes/basis/basis_translator.py +4 -3
- qiskit/transpiler/passes/basis/decompose.py +1 -15
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
- qiskit/transpiler/passes/layout/apply_layout.py +5 -0
- qiskit/transpiler/passes/layout/dense_layout.py +2 -39
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +4 -4
- qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
- qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
- qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
- qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
- qiskit/transpiler/passes/optimization/__init__.py +1 -3
- qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
- qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
- qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
- qiskit/transpiler/passes/optimization/light_cone.py +135 -0
- qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
- qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
- qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -0
- qiskit/transpiler/passes/routing/__init__.py +0 -1
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
- qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
- qiskit/transpiler/passes/scheduling/__init__.py +1 -7
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +30 -2
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -58
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +11 -3
- qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
- qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +127 -59
- qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
- qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
- qiskit/transpiler/passes/synthesis/plugin.py +4 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
- qiskit/transpiler/passes/utils/__init__.py +0 -1
- qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
- qiskit/transpiler/passes/utils/control_flow.py +2 -6
- qiskit/transpiler/passes/utils/gate_direction.py +7 -0
- qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
- qiskit/transpiler/passmanager.py +13 -0
- qiskit/transpiler/passmanager_config.py +5 -81
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
- qiskit/transpiler/preset_passmanagers/common.py +140 -167
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +101 -322
- qiskit/transpiler/preset_passmanagers/level0.py +2 -11
- qiskit/transpiler/preset_passmanagers/level1.py +2 -14
- qiskit/transpiler/preset_passmanagers/level2.py +2 -12
- qiskit/transpiler/preset_passmanagers/level3.py +2 -11
- qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
- qiskit/transpiler/target.py +67 -524
- qiskit/user_config.py +8 -4
- qiskit/utils/__init__.py +13 -12
- qiskit/utils/deprecation.py +4 -112
- qiskit/utils/optionals.py +11 -4
- qiskit/utils/parallel.py +214 -87
- qiskit/utils/units.py +4 -1
- qiskit/visualization/__init__.py +3 -7
- qiskit/visualization/array.py +4 -1
- qiskit/visualization/bloch.py +1 -1
- qiskit/visualization/circuit/_utils.py +19 -19
- qiskit/visualization/circuit/circuit_visualization.py +11 -4
- qiskit/visualization/circuit/matplotlib.py +13 -23
- qiskit/visualization/circuit/text.py +7 -3
- qiskit/visualization/dag_visualization.py +2 -1
- qiskit/visualization/gate_map.py +39 -154
- qiskit/visualization/pass_manager_visualization.py +6 -2
- qiskit/visualization/state_visualization.py +6 -0
- qiskit/visualization/timeline/core.py +27 -12
- qiskit/visualization/timeline/interface.py +23 -18
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +2 -1
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/entry_points.txt +8 -2
- qiskit/assembler/__init__.py +0 -42
- qiskit/assembler/assemble_circuits.py +0 -451
- qiskit/assembler/assemble_schedules.py +0 -367
- qiskit/assembler/disassemble.py +0 -310
- qiskit/assembler/run_config.py +0 -77
- qiskit/circuit/bit.py +0 -106
- qiskit/circuit/classicalfunction/__init__.py +0 -152
- qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
- qiskit/circuit/classicalfunction/classical_element.py +0 -54
- qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
- qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
- qiskit/circuit/classicalfunction/exceptions.py +0 -41
- qiskit/circuit/classicalfunction/types.py +0 -18
- qiskit/circuit/classicalfunction/utils.py +0 -91
- qiskit/circuit/classicalregister.py +0 -57
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
- qiskit/circuit/quantumregister.py +0 -75
- qiskit/circuit/register.py +0 -246
- qiskit/compiler/assembler.py +0 -689
- qiskit/compiler/scheduler.py +0 -109
- qiskit/compiler/sequencer.py +0 -71
- qiskit/primitives/backend_estimator.py +0 -486
- qiskit/primitives/backend_sampler.py +0 -222
- qiskit/primitives/estimator.py +0 -172
- qiskit/primitives/sampler.py +0 -162
- qiskit/providers/backend_compat.py +0 -507
- qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
- qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
- qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
- qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
- qiskit/providers/fake_provider/fake_1q.py +0 -91
- qiskit/providers/fake_provider/fake_backend.py +0 -165
- qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
- qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
- qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
- qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
- qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
- qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
- qiskit/providers/models/__init__.py +0 -89
- qiskit/providers/models/backendconfiguration.py +0 -1040
- qiskit/providers/models/backendproperties.py +0 -535
- qiskit/providers/models/backendstatus.py +0 -104
- qiskit/providers/models/jobstatus.py +0 -77
- qiskit/providers/models/pulsedefaults.py +0 -305
- qiskit/providers/provider.py +0 -95
- qiskit/pulse/__init__.py +0 -158
- qiskit/pulse/builder.py +0 -2262
- qiskit/pulse/calibration_entries.py +0 -381
- qiskit/pulse/channels.py +0 -227
- qiskit/pulse/configuration.py +0 -245
- qiskit/pulse/exceptions.py +0 -45
- qiskit/pulse/filters.py +0 -309
- qiskit/pulse/instruction_schedule_map.py +0 -424
- qiskit/pulse/instructions/__init__.py +0 -67
- qiskit/pulse/instructions/acquire.py +0 -150
- qiskit/pulse/instructions/delay.py +0 -71
- qiskit/pulse/instructions/directives.py +0 -154
- qiskit/pulse/instructions/frequency.py +0 -135
- qiskit/pulse/instructions/instruction.py +0 -270
- qiskit/pulse/instructions/phase.py +0 -152
- qiskit/pulse/instructions/play.py +0 -99
- qiskit/pulse/instructions/reference.py +0 -100
- qiskit/pulse/instructions/snapshot.py +0 -82
- qiskit/pulse/library/__init__.py +0 -97
- qiskit/pulse/library/continuous.py +0 -430
- qiskit/pulse/library/pulse.py +0 -148
- qiskit/pulse/library/samplers/__init__.py +0 -15
- qiskit/pulse/library/samplers/decorators.py +0 -295
- qiskit/pulse/library/samplers/strategies.py +0 -71
- qiskit/pulse/library/symbolic_pulses.py +0 -1989
- qiskit/pulse/library/waveform.py +0 -136
- qiskit/pulse/macros.py +0 -262
- qiskit/pulse/parameter_manager.py +0 -445
- qiskit/pulse/parser.py +0 -314
- qiskit/pulse/reference_manager.py +0 -58
- qiskit/pulse/schedule.py +0 -1854
- qiskit/pulse/transforms/__init__.py +0 -106
- qiskit/pulse/transforms/alignments.py +0 -406
- qiskit/pulse/transforms/base_transforms.py +0 -71
- qiskit/pulse/transforms/canonicalization.py +0 -498
- qiskit/pulse/transforms/dag.py +0 -122
- qiskit/pulse/utils.py +0 -149
- qiskit/qobj/__init__.py +0 -75
- qiskit/qobj/common.py +0 -81
- qiskit/qobj/converters/__init__.py +0 -18
- qiskit/qobj/converters/lo_config.py +0 -177
- qiskit/qobj/converters/pulse_instruction.py +0 -897
- qiskit/qobj/pulse_qobj.py +0 -709
- qiskit/qobj/qasm_qobj.py +0 -708
- qiskit/qobj/utils.py +0 -46
- qiskit/result/mitigation/base_readout_mitigator.py +0 -79
- qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
- qiskit/result/mitigation/local_readout_mitigator.py +0 -328
- qiskit/result/mitigation/utils.py +0 -217
- qiskit/scheduler/__init__.py +0 -40
- qiskit/scheduler/config.py +0 -37
- qiskit/scheduler/lowering.py +0 -187
- qiskit/scheduler/methods/__init__.py +0 -15
- qiskit/scheduler/methods/basic.py +0 -140
- qiskit/scheduler/schedule_circuit.py +0 -69
- qiskit/scheduler/sequence.py +0 -104
- qiskit/transpiler/passes/calibration/__init__.py +0 -17
- qiskit/transpiler/passes/calibration/base_builder.py +0 -79
- qiskit/transpiler/passes/calibration/builders.py +0 -20
- qiskit/transpiler/passes/calibration/exceptions.py +0 -22
- qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
- qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
- qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
- qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
- qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
- qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
- qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
- qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
- qiskit/transpiler/passes/scheduling/alap.py +0 -153
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
- qiskit/transpiler/passes/scheduling/asap.py +0 -175
- qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
- qiskit/utils/deprecate_pulse.py +0 -119
- qiskit/utils/multiprocessing.py +0 -56
- qiskit/visualization/pulse_v2/__init__.py +0 -21
- qiskit/visualization/pulse_v2/core.py +0 -901
- qiskit/visualization/pulse_v2/device_info.py +0 -173
- qiskit/visualization/pulse_v2/drawings.py +0 -253
- qiskit/visualization/pulse_v2/events.py +0 -254
- qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
- qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
- qiskit/visualization/pulse_v2/generators/chart.py +0 -208
- qiskit/visualization/pulse_v2/generators/frame.py +0 -436
- qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
- qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
- qiskit/visualization/pulse_v2/interface.py +0 -459
- qiskit/visualization/pulse_v2/layouts.py +0 -387
- qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
- qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
- qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
- qiskit/visualization/pulse_v2/stylesheet.py +0 -312
- qiskit/visualization/pulse_v2/types.py +0 -242
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -25,217 +25,8 @@ from __future__ import annotations
|
|
25
25
|
import numpy as np
|
26
26
|
from qiskit.exceptions import QiskitError
|
27
27
|
from qiskit.circuit import QuantumCircuit
|
28
|
-
from qiskit.synthesis.linear.linear_matrix_utils import
|
29
|
-
|
30
|
-
check_invertible_binary_matrix,
|
31
|
-
col_op,
|
32
|
-
row_op,
|
33
|
-
)
|
34
|
-
|
35
|
-
|
36
|
-
def _row_op_update_instructions(cx_instructions, mat, a, b):
|
37
|
-
# Add a cx gate to the instructions and update the matrix mat
|
38
|
-
cx_instructions.append((a, b))
|
39
|
-
row_op(mat, a, b)
|
40
|
-
|
41
|
-
|
42
|
-
def _get_lower_triangular(n, mat, mat_inv):
|
43
|
-
# Get the instructions for a lower triangular basis change of a matrix mat.
|
44
|
-
# See the proof of Proposition 7.3 in [1].
|
45
|
-
mat = mat.copy()
|
46
|
-
mat_t = mat.copy()
|
47
|
-
mat_inv_t = mat_inv.copy()
|
48
|
-
|
49
|
-
cx_instructions_rows = []
|
50
|
-
|
51
|
-
# Use the instructions in U, which contains only gates of the form cx(a,b) a>b
|
52
|
-
# to transform the matrix to a permuted lower-triangular matrix.
|
53
|
-
# The original Matrix is unchanged.
|
54
|
-
for i in reversed(range(0, n)):
|
55
|
-
found_first = False
|
56
|
-
# Find the last "1" in row i, use COL operations to the left in order to
|
57
|
-
# zero out all other "1"s in that row.
|
58
|
-
for j in reversed(range(0, n)):
|
59
|
-
if mat[i, j]:
|
60
|
-
if not found_first:
|
61
|
-
found_first = True
|
62
|
-
first_j = j
|
63
|
-
else:
|
64
|
-
# cx_instructions_cols (L instructions) are not needed
|
65
|
-
col_op(mat, j, first_j)
|
66
|
-
# Use row operations directed upwards to zero out all "1"s above the remaining "1" in row i
|
67
|
-
for k in reversed(range(0, i)):
|
68
|
-
if mat[k, first_j]:
|
69
|
-
_row_op_update_instructions(cx_instructions_rows, mat, i, k)
|
70
|
-
|
71
|
-
# Apply only U instructions to get the permuted L
|
72
|
-
for inst in cx_instructions_rows:
|
73
|
-
row_op(mat_t, inst[0], inst[1])
|
74
|
-
col_op(mat_inv_t, inst[0], inst[1])
|
75
|
-
return mat_t, mat_inv_t
|
76
|
-
|
77
|
-
|
78
|
-
def _get_label_arr(n, mat_t):
|
79
|
-
# For each row in mat_t, save the column index of the last "1"
|
80
|
-
label_arr = []
|
81
|
-
for i in range(n):
|
82
|
-
j = 0
|
83
|
-
while not mat_t[i, n - 1 - j]:
|
84
|
-
j += 1
|
85
|
-
label_arr.append(j)
|
86
|
-
return label_arr
|
87
|
-
|
88
|
-
|
89
|
-
def _in_linear_combination(label_arr_t, mat_inv_t, row, k):
|
90
|
-
# Check if "row" is a linear combination of all rows in mat_inv_t not including the row labeled by k
|
91
|
-
indx_k = label_arr_t[k]
|
92
|
-
w_needed = np.zeros(len(row), dtype=bool)
|
93
|
-
# Find the linear combination of mat_t rows which produces "row"
|
94
|
-
for row_l, _ in enumerate(row):
|
95
|
-
if row[row_l]:
|
96
|
-
# mat_inv_t can be thought of as a set of instructions. Row l in mat_inv_t
|
97
|
-
# indicates which rows from mat_t are necessary to produce the elementary vector e_l
|
98
|
-
w_needed = w_needed ^ mat_inv_t[row_l]
|
99
|
-
# If the linear combination requires the row labeled by k
|
100
|
-
if w_needed[indx_k]:
|
101
|
-
return False
|
102
|
-
return True
|
103
|
-
|
104
|
-
|
105
|
-
def _get_label_arr_t(n, label_arr):
|
106
|
-
# Returns label_arr_t = label_arr^(-1)
|
107
|
-
label_arr_t = [None] * n
|
108
|
-
for i in range(n):
|
109
|
-
label_arr_t[label_arr[i]] = i
|
110
|
-
return label_arr_t
|
111
|
-
|
112
|
-
|
113
|
-
def _matrix_to_north_west(n, mat, mat_inv):
|
114
|
-
# Transform an arbitrary boolean invertible matrix to a north-west triangular matrix
|
115
|
-
# by Proposition 7.3 in [1]
|
116
|
-
|
117
|
-
# The rows of mat_t hold all w_j vectors (see [1]). mat_inv_t is the inverted matrix of mat_t
|
118
|
-
mat_t, mat_inv_t = _get_lower_triangular(n, mat, mat_inv)
|
119
|
-
|
120
|
-
# Get all pi(i) labels
|
121
|
-
label_arr = _get_label_arr(n, mat_t)
|
122
|
-
|
123
|
-
# Save the original labels, exchange index <-> value
|
124
|
-
label_arr_t = _get_label_arr_t(n, label_arr)
|
125
|
-
|
126
|
-
first_qubit = 0
|
127
|
-
empty_layers = 0
|
128
|
-
done = False
|
129
|
-
cx_instructions_rows = []
|
130
|
-
|
131
|
-
while not done:
|
132
|
-
# At each iteration the values of i switch between even and odd
|
133
|
-
at_least_one_needed = False
|
134
|
-
|
135
|
-
for i in range(first_qubit, n - 1, 2):
|
136
|
-
# "If j < k, we do nothing" (see [1])
|
137
|
-
# "If j > k, we swap the two labels, and we also perform a box" (see [1])
|
138
|
-
if label_arr[i] > label_arr[i + 1]:
|
139
|
-
at_least_one_needed = True
|
140
|
-
# "Let W be the span of all w_l for l!=k" (see [1])
|
141
|
-
# " We can perform a box on <i> and <i + 1> that writes a vector in W to wire <i + 1>."
|
142
|
-
# (see [1])
|
143
|
-
if _in_linear_combination(label_arr_t, mat_inv_t, mat[i + 1], label_arr[i + 1]):
|
144
|
-
pass
|
145
|
-
|
146
|
-
elif _in_linear_combination(
|
147
|
-
label_arr_t, mat_inv_t, mat[i + 1] ^ mat[i], label_arr[i + 1]
|
148
|
-
):
|
149
|
-
_row_op_update_instructions(cx_instructions_rows, mat, i, i + 1)
|
150
|
-
|
151
|
-
elif _in_linear_combination(label_arr_t, mat_inv_t, mat[i], label_arr[i + 1]):
|
152
|
-
_row_op_update_instructions(cx_instructions_rows, mat, i + 1, i)
|
153
|
-
_row_op_update_instructions(cx_instructions_rows, mat, i, i + 1)
|
154
|
-
|
155
|
-
label_arr[i], label_arr[i + 1] = label_arr[i + 1], label_arr[i]
|
156
|
-
|
157
|
-
if not at_least_one_needed:
|
158
|
-
empty_layers += 1
|
159
|
-
if empty_layers > 1: # if nothing happened twice in a row, then finished.
|
160
|
-
done = True
|
161
|
-
else:
|
162
|
-
empty_layers = 0
|
163
|
-
|
164
|
-
first_qubit = int(not first_qubit)
|
165
|
-
|
166
|
-
return cx_instructions_rows
|
167
|
-
|
168
|
-
|
169
|
-
def _north_west_to_identity(n, mat):
|
170
|
-
# Transform a north-west triangular matrix to identity in depth 3*n by Proposition 7.4 of [1]
|
171
|
-
|
172
|
-
# At start the labels are in reversed order
|
173
|
-
label_arr = list(reversed(range(n)))
|
174
|
-
first_qubit = 0
|
175
|
-
empty_layers = 0
|
176
|
-
done = False
|
177
|
-
cx_instructions_rows = []
|
178
|
-
|
179
|
-
while not done:
|
180
|
-
at_least_one_needed = False
|
181
|
-
|
182
|
-
for i in range(first_qubit, n - 1, 2):
|
183
|
-
# Exchange the labels if needed
|
184
|
-
if label_arr[i] > label_arr[i + 1]:
|
185
|
-
at_least_one_needed = True
|
186
|
-
|
187
|
-
# If row i has "1" in column i+1, swap and remove the "1" (in depth 2)
|
188
|
-
# otherwise, only do a swap (in depth 3)
|
189
|
-
if not mat[i, label_arr[i + 1]]:
|
190
|
-
# Adding this turns the operation to a SWAP
|
191
|
-
_row_op_update_instructions(cx_instructions_rows, mat, i + 1, i)
|
192
|
-
|
193
|
-
_row_op_update_instructions(cx_instructions_rows, mat, i, i + 1)
|
194
|
-
_row_op_update_instructions(cx_instructions_rows, mat, i + 1, i)
|
195
|
-
|
196
|
-
label_arr[i], label_arr[i + 1] = label_arr[i + 1], label_arr[i]
|
197
|
-
|
198
|
-
if not at_least_one_needed:
|
199
|
-
empty_layers += 1
|
200
|
-
if empty_layers > 1: # if nothing happened twice in a row, then finished.
|
201
|
-
done = True
|
202
|
-
else:
|
203
|
-
empty_layers = 0
|
204
|
-
|
205
|
-
first_qubit = int(not first_qubit)
|
206
|
-
|
207
|
-
return cx_instructions_rows
|
208
|
-
|
209
|
-
|
210
|
-
def _optimize_cx_circ_depth_5n_line(mat):
|
211
|
-
# Optimize CX circuit in depth bounded by 5n for LNN connectivity.
|
212
|
-
# The algorithm [1] has two steps:
|
213
|
-
# a) transform the original matrix to a north-west matrix (m2nw),
|
214
|
-
# b) transform the north-west matrix to identity (nw2id).
|
215
|
-
#
|
216
|
-
# A square n-by-n matrix A is called north-west if A[i][j]=0 for all i+j>=n
|
217
|
-
# For example, the following matrix is north-west:
|
218
|
-
# [[0, 1, 0, 1]
|
219
|
-
# [1, 1, 1, 0]
|
220
|
-
# [0, 1, 0, 0]
|
221
|
-
# [1, 0, 0, 0]]
|
222
|
-
|
223
|
-
# According to [1] the synthesis is done on the inverse matrix
|
224
|
-
# so the matrix mat is inverted at this step
|
225
|
-
mat_inv = mat.astype(bool, copy=True)
|
226
|
-
mat_cpy = calc_inverse_matrix(mat_inv)
|
227
|
-
|
228
|
-
n = len(mat_cpy)
|
229
|
-
|
230
|
-
# Transform an arbitrary invertible matrix to a north-west triangular matrix
|
231
|
-
# by Proposition 7.3 of [1]
|
232
|
-
cx_instructions_rows_m2nw = _matrix_to_north_west(n, mat_cpy, mat_inv)
|
233
|
-
|
234
|
-
# Transform a north-west triangular matrix to identity in depth 3*n
|
235
|
-
# by Proposition 7.4 of [1]
|
236
|
-
cx_instructions_rows_nw2id = _north_west_to_identity(n, mat_cpy)
|
237
|
-
|
238
|
-
return cx_instructions_rows_m2nw, cx_instructions_rows_nw2id
|
28
|
+
from qiskit.synthesis.linear.linear_matrix_utils import check_invertible_binary_matrix
|
29
|
+
from qiskit._accelerate.synthesis.linear import py_synth_cnot_depth_line_kms as fast_kms
|
239
30
|
|
240
31
|
|
241
32
|
def synth_cnot_depth_line_kms(mat: np.ndarray[bool]) -> QuantumCircuit:
|
@@ -264,13 +55,7 @@ def synth_cnot_depth_line_kms(mat: np.ndarray[bool]) -> QuantumCircuit:
|
|
264
55
|
if not check_invertible_binary_matrix(mat):
|
265
56
|
raise QiskitError("The input matrix is not invertible.")
|
266
57
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
qc = QuantumCircuit(num_qubits)
|
272
|
-
for pair in cx_inst[0]:
|
273
|
-
qc.cx(pair[0], pair[1])
|
274
|
-
for pair in cx_inst[1]:
|
275
|
-
qc.cx(pair[0], pair[1])
|
276
|
-
return qc
|
58
|
+
circuit_data = fast_kms(mat)
|
59
|
+
|
60
|
+
# construct circuit from the data
|
61
|
+
return QuantumCircuit._from_circuit_data(circuit_data, add_regs=True)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# This code is part of Qiskit.
|
2
2
|
#
|
3
|
-
# (C) Copyright IBM 2023
|
3
|
+
# (C) Copyright IBM 2023-2025
|
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
|
@@ -28,191 +28,9 @@ References:
|
|
28
28
|
Hadamard-free Clifford transformations they generate," 2022.
|
29
29
|
"""
|
30
30
|
|
31
|
-
from copy import deepcopy
|
32
31
|
import numpy as np
|
33
|
-
|
34
32
|
from qiskit.circuit import QuantumCircuit
|
35
|
-
from qiskit.synthesis.
|
36
|
-
from qiskit.synthesis.linear.linear_depth_lnn import _optimize_cx_circ_depth_5n_line
|
37
|
-
|
38
|
-
|
39
|
-
def _initialize_phase_schedule(mat_z):
|
40
|
-
"""
|
41
|
-
Given a CZ layer (represented as an n*n CZ matrix Mz)
|
42
|
-
Return a schedule of phase gates implementing Mz in a SWAP-only netwrok
|
43
|
-
(c.f. Alg 1, [2])
|
44
|
-
"""
|
45
|
-
n = len(mat_z)
|
46
|
-
phase_schedule = np.zeros((n, n), dtype=int)
|
47
|
-
for i, j in zip(*np.where(mat_z)):
|
48
|
-
if i >= j:
|
49
|
-
continue
|
50
|
-
|
51
|
-
phase_schedule[i, j] = 3
|
52
|
-
phase_schedule[i, i] += 1
|
53
|
-
phase_schedule[j, j] += 1
|
54
|
-
|
55
|
-
return phase_schedule
|
56
|
-
|
57
|
-
|
58
|
-
def _shuffle(labels, odd):
|
59
|
-
"""
|
60
|
-
Args:
|
61
|
-
labels : a list of indices
|
62
|
-
odd : a boolean indicating whether this layer is odd or even,
|
63
|
-
Shuffle the indices in labels by swapping adjacent elements
|
64
|
-
(c.f. Fig.2, [2])
|
65
|
-
"""
|
66
|
-
swapped = [v for p in zip(labels[1::2], labels[::2]) for v in p]
|
67
|
-
return swapped + labels[-1:] if odd else swapped
|
68
|
-
|
69
|
-
|
70
|
-
def _make_seq(n):
|
71
|
-
"""
|
72
|
-
Given the width of the circuit n,
|
73
|
-
Return the labels of the boxes in order from left to right, top to bottom
|
74
|
-
(c.f. Fig.2, [2])
|
75
|
-
"""
|
76
|
-
seq = []
|
77
|
-
wire_labels = list(range(n - 1, -1, -1))
|
78
|
-
|
79
|
-
for i in range(n):
|
80
|
-
wire_labels_new = (
|
81
|
-
_shuffle(wire_labels, n % 2)
|
82
|
-
if i % 2 == 0
|
83
|
-
else wire_labels[0:1] + _shuffle(wire_labels[1:], (n + 1) % 2)
|
84
|
-
)
|
85
|
-
seq += [
|
86
|
-
(min(i), max(i)) for i in zip(wire_labels[::2], wire_labels_new[::2]) if i[0] != i[1]
|
87
|
-
]
|
88
|
-
wire_labels = wire_labels_new
|
89
|
-
|
90
|
-
return seq
|
91
|
-
|
92
|
-
|
93
|
-
def _swap_plus(instructions, seq):
|
94
|
-
"""
|
95
|
-
Given CX instructions (c.f. Thm 7.1, [1]) and the labels of all boxes,
|
96
|
-
Return a list of labels of the boxes that is SWAP+ in descending order
|
97
|
-
* Assumes the instruction gives gates in the order from top to bottom,
|
98
|
-
from left to right
|
99
|
-
* SWAP+ is defined in section 3.A. of [2]. Note the northwest
|
100
|
-
diagonalization procedure of [1] consists exactly n layers of boxes,
|
101
|
-
each being either a SWAP or a SWAP+. That is, each northwest
|
102
|
-
diagonalization circuit can be uniquely represented by which of its
|
103
|
-
n(n-1)/2 boxes are SWAP+ and which are SWAP.
|
104
|
-
"""
|
105
|
-
instr = deepcopy(instructions)
|
106
|
-
swap_plus = set()
|
107
|
-
for i, j in reversed(seq):
|
108
|
-
cnot_1 = instr.pop()
|
109
|
-
instr.pop()
|
110
|
-
|
111
|
-
if instr == [] or instr[-1] != cnot_1:
|
112
|
-
# Only two CNOTs on same set of controls -> this box is SWAP+
|
113
|
-
swap_plus.add((i, j))
|
114
|
-
else:
|
115
|
-
instr.pop()
|
116
|
-
return swap_plus
|
117
|
-
|
118
|
-
|
119
|
-
def _update_phase_schedule(n, phase_schedule, swap_plus):
|
120
|
-
"""
|
121
|
-
Given phase_schedule initialized to induce a CZ circuit in SWAP-only network and list of SWAP+ boxes
|
122
|
-
Update phase_schedule for each SWAP+ according to Algorithm 2, [2]
|
123
|
-
"""
|
124
|
-
layer_order = list(range(n))[-3::-2] + list(range(n))[-2::-2][::-1]
|
125
|
-
order_comp = np.argsort(layer_order[::-1])
|
126
|
-
|
127
|
-
# Go through each box by descending layer order
|
128
|
-
|
129
|
-
for i in layer_order:
|
130
|
-
for j in range(i + 1, n):
|
131
|
-
if (i, j) not in swap_plus:
|
132
|
-
continue
|
133
|
-
# we need to correct for the effected linear functions:
|
134
|
-
|
135
|
-
# We first correct type 1 and type 2 by switching
|
136
|
-
# the phase applied to c_j and c_i+c_j
|
137
|
-
phase_schedule[j, j], phase_schedule[i, j] = phase_schedule[i, j], phase_schedule[j, j]
|
138
|
-
|
139
|
-
# Then, we go through all the boxes that permutes j BEFORE box(i,j) and update:
|
140
|
-
|
141
|
-
for k in range(n): # all boxes that permutes j
|
142
|
-
if k in (i, j):
|
143
|
-
continue
|
144
|
-
if (
|
145
|
-
order_comp[min(k, j)] < order_comp[i]
|
146
|
-
and phase_schedule[min(k, j), max(k, j)] % 4 != 0
|
147
|
-
):
|
148
|
-
phase = phase_schedule[min(k, j), max(k, j)]
|
149
|
-
phase_schedule[min(k, j), max(k, j)] = 0
|
150
|
-
|
151
|
-
# Step 1, apply phase to c_i, c_j, c_k
|
152
|
-
for l_s in (i, j, k):
|
153
|
-
phase_schedule[l_s, l_s] = (phase_schedule[l_s, l_s] + phase * 3) % 4
|
154
|
-
|
155
|
-
# Step 2, apply phase to c_i+ c_j, c_i+c_k, c_j+c_k:
|
156
|
-
for l1, l2 in [(i, j), (i, k), (j, k)]:
|
157
|
-
ls = min(l1, l2)
|
158
|
-
lb = max(l1, l2)
|
159
|
-
phase_schedule[ls, lb] = (phase_schedule[ls, lb] + phase * 3) % 4
|
160
|
-
return phase_schedule
|
161
|
-
|
162
|
-
|
163
|
-
def _apply_phase_to_nw_circuit(n, phase_schedule, seq, swap_plus):
|
164
|
-
"""
|
165
|
-
Given
|
166
|
-
Width of the circuit (int n)
|
167
|
-
A CZ circuit, represented by the n*n phase schedule phase_schedule
|
168
|
-
A CX circuit, represented by box-labels (seq) and whether the box is SWAP+ (swap_plus)
|
169
|
-
* This circuit corresponds to the CX tranformation that tranforms a matrix to
|
170
|
-
a NW matrix (c.f. Prop.7.4, [1])
|
171
|
-
* SWAP+ is defined in section 3.A. of [2].
|
172
|
-
* As previously noted, the northwest diagonalization procedure of [1] consists
|
173
|
-
of exactly n layers of boxes, each being either a SWAP or a SWAP+. That is,
|
174
|
-
each northwest diagonalization circuit can be uniquely represented by which
|
175
|
-
of its n(n-1)/2 boxes are SWAP+ and which are SWAP.
|
176
|
-
Return a QuantumCircuit that computes the phase schedule S inside CX
|
177
|
-
"""
|
178
|
-
cir = QuantumCircuit(n)
|
179
|
-
|
180
|
-
wires = list(zip(range(n), range(1, n)))
|
181
|
-
wires = wires[::2] + wires[1::2]
|
182
|
-
|
183
|
-
for i, (j, k) in zip(range(len(seq) - 1, -1, -1), reversed(seq)):
|
184
|
-
w1, w2 = wires[i % (n - 1)]
|
185
|
-
|
186
|
-
p = phase_schedule[j, k]
|
187
|
-
|
188
|
-
if (j, k) not in swap_plus:
|
189
|
-
cir.cx(w1, w2)
|
190
|
-
|
191
|
-
cir.cx(w2, w1)
|
192
|
-
|
193
|
-
if p % 4 == 0:
|
194
|
-
pass
|
195
|
-
elif p % 4 == 1:
|
196
|
-
cir.sdg(w2)
|
197
|
-
elif p % 4 == 2:
|
198
|
-
cir.z(w2)
|
199
|
-
else:
|
200
|
-
cir.s(w2)
|
201
|
-
|
202
|
-
cir.cx(w1, w2)
|
203
|
-
|
204
|
-
for i in range(n):
|
205
|
-
p = phase_schedule[n - 1 - i, n - 1 - i]
|
206
|
-
if p % 4 == 0:
|
207
|
-
continue
|
208
|
-
if p % 4 == 1:
|
209
|
-
cir.sdg(i)
|
210
|
-
elif p % 4 == 2:
|
211
|
-
cir.z(i)
|
212
|
-
else:
|
213
|
-
cir.s(i)
|
214
|
-
|
215
|
-
return cir
|
33
|
+
from qiskit._accelerate.synthesis.linear_phase import py_synth_cx_cz_depth_line_my
|
216
34
|
|
217
35
|
|
218
36
|
def synth_cx_cz_depth_line_my(mat_x: np.ndarray, mat_z: np.ndarray) -> QuantumCircuit:
|
@@ -239,24 +57,5 @@ def synth_cx_cz_depth_line_my(mat_x: np.ndarray, mat_z: np.ndarray) -> QuantumCi
|
|
239
57
|
Hadamard-free Clifford transformations they generate*,
|
240
58
|
`arXiv:2210.16195 <https://arxiv.org/abs/2210.16195>`_.
|
241
59
|
"""
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
n = len(mat_x)
|
246
|
-
mat_x = calc_inverse_matrix(mat_x)
|
247
|
-
|
248
|
-
cx_instructions_rows_m2nw, cx_instructions_rows_nw2id = _optimize_cx_circ_depth_5n_line(mat_x)
|
249
|
-
|
250
|
-
# Meanwhile, also build the -CZ- circuit via Phase gate insertions as per Algorithm 2 [2]
|
251
|
-
phase_schedule = _initialize_phase_schedule(mat_z)
|
252
|
-
seq = _make_seq(n)
|
253
|
-
swap_plus = _swap_plus(cx_instructions_rows_nw2id, seq)
|
254
|
-
|
255
|
-
_update_phase_schedule(n, phase_schedule, swap_plus)
|
256
|
-
|
257
|
-
qc = _apply_phase_to_nw_circuit(n, phase_schedule, seq, swap_plus)
|
258
|
-
|
259
|
-
for i, j in reversed(cx_instructions_rows_m2nw):
|
260
|
-
qc.cx(i, j)
|
261
|
-
|
262
|
-
return qc
|
60
|
+
circuit_data = py_synth_cx_cz_depth_line_my(mat_x.astype(bool), mat_z.astype(bool))
|
61
|
+
return QuantumCircuit._from_circuit_data(circuit_data, add_regs=True)
|
@@ -15,7 +15,7 @@
|
|
15
15
|
from math import ceil
|
16
16
|
import numpy as np
|
17
17
|
|
18
|
-
from qiskit.circuit
|
18
|
+
from qiskit.circuit import QuantumRegister
|
19
19
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
20
20
|
from qiskit.circuit.library.standard_gates import (
|
21
21
|
HGate,
|
@@ -53,7 +53,10 @@ def synth_mcx_n_dirty_i15(
|
|
53
53
|
`arXiv:1501.06911 <http://arxiv.org/abs/1501.06911>`_
|
54
54
|
"""
|
55
55
|
|
56
|
-
|
56
|
+
if num_ctrl_qubits == 1:
|
57
|
+
num_qubits = 2
|
58
|
+
else:
|
59
|
+
num_qubits = 2 * num_ctrl_qubits - 1
|
57
60
|
q = QuantumRegister(num_qubits, name="q")
|
58
61
|
qc = QuantumCircuit(q, name="mcx_vchain")
|
59
62
|
q_controls = q[:num_ctrl_qubits]
|
@@ -0,0 +1,206 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2018, 2024.
|
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
|
+
Multiple-Controlled U3 gate utilities. Not using ancillary qubits.
|
14
|
+
"""
|
15
|
+
|
16
|
+
import math
|
17
|
+
import numpy as np
|
18
|
+
|
19
|
+
from qiskit.circuit import QuantumCircuit, Gate
|
20
|
+
from qiskit.circuit.library.standard_gates.u3 import _generate_gray_code
|
21
|
+
from qiskit.exceptions import QiskitError
|
22
|
+
|
23
|
+
|
24
|
+
def _apply_cu(circuit, theta, phi, lam, control, target, use_basis_gates=True):
|
25
|
+
if use_basis_gates:
|
26
|
+
# ┌──────────────┐
|
27
|
+
# control: ┤ P(λ/2 + φ/2) ├──■──────────────────────────────────■────────────────
|
28
|
+
# ├──────────────┤┌─┴─┐┌────────────────────────────┐┌─┴─┐┌────────────┐
|
29
|
+
# target: ┤ P(λ/2 - φ/2) ├┤ X ├┤ U(-0.5*0,0,-0.5*λ - 0.5*φ) ├┤ X ├┤ U(0/2,φ,0) ├
|
30
|
+
# └──────────────┘└───┘└────────────────────────────┘└───┘└────────────┘
|
31
|
+
circuit.p((lam + phi) / 2, [control])
|
32
|
+
circuit.p((lam - phi) / 2, [target])
|
33
|
+
circuit.cx(control, target)
|
34
|
+
circuit.u(-theta / 2, 0, -(phi + lam) / 2, [target])
|
35
|
+
circuit.cx(control, target)
|
36
|
+
circuit.u(theta / 2, phi, 0, [target])
|
37
|
+
else:
|
38
|
+
circuit.cu(theta, phi, lam, 0, control, target)
|
39
|
+
|
40
|
+
|
41
|
+
def _apply_mcu_graycode(circuit, theta, phi, lam, ctls, tgt, use_basis_gates):
|
42
|
+
"""Apply multi-controlled u gate from ctls to tgt using graycode
|
43
|
+
pattern with single-step angles theta, phi, lam."""
|
44
|
+
|
45
|
+
n = len(ctls)
|
46
|
+
|
47
|
+
gray_code = _generate_gray_code(n)
|
48
|
+
last_pattern = None
|
49
|
+
|
50
|
+
for pattern in gray_code:
|
51
|
+
if "1" not in pattern:
|
52
|
+
continue
|
53
|
+
if last_pattern is None:
|
54
|
+
last_pattern = pattern
|
55
|
+
# find left most set bit
|
56
|
+
lm_pos = list(pattern).index("1")
|
57
|
+
|
58
|
+
# find changed bit
|
59
|
+
comp = [i != j for i, j in zip(pattern, last_pattern)]
|
60
|
+
if True in comp:
|
61
|
+
pos = comp.index(True)
|
62
|
+
else:
|
63
|
+
pos = None
|
64
|
+
if pos is not None:
|
65
|
+
if pos != lm_pos:
|
66
|
+
circuit.cx(ctls[pos], ctls[lm_pos])
|
67
|
+
else:
|
68
|
+
indices = [i for i, x in enumerate(pattern) if x == "1"]
|
69
|
+
for idx in indices[1:]:
|
70
|
+
circuit.cx(ctls[idx], ctls[lm_pos])
|
71
|
+
# check parity and undo rotation
|
72
|
+
if pattern.count("1") % 2 == 0:
|
73
|
+
# inverse CU: u(theta, phi, lamb)^dagger = u(-theta, -lam, -phi)
|
74
|
+
_apply_cu(
|
75
|
+
circuit, -theta, -lam, -phi, ctls[lm_pos], tgt, use_basis_gates=use_basis_gates
|
76
|
+
)
|
77
|
+
else:
|
78
|
+
_apply_cu(circuit, theta, phi, lam, ctls[lm_pos], tgt, use_basis_gates=use_basis_gates)
|
79
|
+
last_pattern = pattern
|
80
|
+
|
81
|
+
|
82
|
+
def _mcsu2_real_diagonal(
|
83
|
+
gate: Gate,
|
84
|
+
num_controls: int,
|
85
|
+
use_basis_gates: bool = False,
|
86
|
+
) -> QuantumCircuit:
|
87
|
+
"""
|
88
|
+
Return a multi-controlled SU(2) gate [1]_ with a real main diagonal or secondary diagonal.
|
89
|
+
|
90
|
+
Args:
|
91
|
+
gate: SU(2) Gate whose unitary matrix has one real diagonal.
|
92
|
+
num_controls: The number of control qubits.
|
93
|
+
use_basis_gates: If ``True``, use ``[p, u, cx]`` gates to implement the decomposition.
|
94
|
+
|
95
|
+
Returns:
|
96
|
+
A :class:`.QuantumCircuit` implementing the multi-controlled SU(2) gate.
|
97
|
+
|
98
|
+
Raises:
|
99
|
+
QiskitError: If the input matrix is invalid.
|
100
|
+
|
101
|
+
References:
|
102
|
+
|
103
|
+
.. [1]: R. Vale et al. Decomposition of Multi-controlled Special Unitary Single-Qubit Gates
|
104
|
+
`arXiv:2302.06377 (2023) <https://arxiv.org/abs/2302.06377>`__
|
105
|
+
|
106
|
+
"""
|
107
|
+
# pylint: disable=cyclic-import
|
108
|
+
from qiskit.circuit.library.standard_gates import RXGate, RYGate, RZGate
|
109
|
+
from qiskit.circuit.library.generalized_gates import UnitaryGate
|
110
|
+
from qiskit.quantum_info.operators.predicates import is_unitary_matrix
|
111
|
+
from qiskit.compiler import transpile
|
112
|
+
from qiskit.synthesis.multi_controlled import synth_mcx_n_dirty_i15
|
113
|
+
|
114
|
+
if isinstance(gate, RYGate):
|
115
|
+
theta = gate.params[0]
|
116
|
+
s_gate = RYGate(-theta / 4)
|
117
|
+
is_secondary_diag_real = True
|
118
|
+
elif isinstance(gate, RZGate):
|
119
|
+
theta = gate.params[0]
|
120
|
+
s_gate = RZGate(-theta / 4)
|
121
|
+
is_secondary_diag_real = True
|
122
|
+
elif isinstance(gate, RXGate):
|
123
|
+
theta = gate.params[0]
|
124
|
+
s_gate = RZGate(-theta / 4)
|
125
|
+
is_secondary_diag_real = False
|
126
|
+
|
127
|
+
else:
|
128
|
+
unitary = gate.to_matrix()
|
129
|
+
if unitary.shape != (2, 2):
|
130
|
+
raise QiskitError(f"The unitary must be a 2x2 matrix, but has shape {unitary.shape}.")
|
131
|
+
|
132
|
+
if not is_unitary_matrix(unitary):
|
133
|
+
raise QiskitError(f"The unitary in must be an unitary matrix, but is {unitary}.")
|
134
|
+
|
135
|
+
if not np.isclose(1.0, np.linalg.det(unitary)):
|
136
|
+
raise QiskitError(
|
137
|
+
"Invalid Value _mcsu2_real_diagonal requires det(unitary) equal to one."
|
138
|
+
)
|
139
|
+
|
140
|
+
is_main_diag_real = np.isclose(unitary[0, 0].imag, 0.0) and np.isclose(
|
141
|
+
unitary[1, 1].imag, 0.0
|
142
|
+
)
|
143
|
+
is_secondary_diag_real = np.isclose(unitary[0, 1].imag, 0.0) and np.isclose(
|
144
|
+
unitary[1, 0].imag, 0.0
|
145
|
+
)
|
146
|
+
|
147
|
+
if not is_main_diag_real and not is_secondary_diag_real:
|
148
|
+
raise QiskitError("The unitary must have one real diagonal.")
|
149
|
+
|
150
|
+
if is_secondary_diag_real:
|
151
|
+
x = unitary[0, 1]
|
152
|
+
z = unitary[1, 1]
|
153
|
+
else:
|
154
|
+
x = -unitary[0, 1].real
|
155
|
+
z = unitary[1, 1] - unitary[0, 1].imag * 1.0j
|
156
|
+
|
157
|
+
if np.isclose(z, -1):
|
158
|
+
s_op = [[1.0, 0.0], [0.0, 1.0j]]
|
159
|
+
else:
|
160
|
+
alpha_r = math.sqrt((math.sqrt((z.real + 1.0) / 2.0) + 1.0) / 2.0)
|
161
|
+
alpha_i = z.imag / (
|
162
|
+
2.0 * math.sqrt((z.real + 1.0) * (math.sqrt((z.real + 1.0) / 2.0) + 1.0))
|
163
|
+
)
|
164
|
+
alpha = alpha_r + 1.0j * alpha_i
|
165
|
+
beta = x / (2.0 * math.sqrt((z.real + 1.0) * (math.sqrt((z.real + 1.0) / 2.0) + 1.0)))
|
166
|
+
|
167
|
+
# S gate definition
|
168
|
+
s_op = np.array([[alpha, -np.conj(beta)], [beta, np.conj(alpha)]])
|
169
|
+
s_gate = UnitaryGate(s_op)
|
170
|
+
|
171
|
+
k_1 = math.ceil(num_controls / 2.0)
|
172
|
+
k_2 = math.floor(num_controls / 2.0)
|
173
|
+
|
174
|
+
circuit = QuantumCircuit(num_controls + 1, name="MCSU2")
|
175
|
+
controls = list(range(num_controls)) # control indices, defined for code legibility
|
176
|
+
target = num_controls # target index, defined for code legibility
|
177
|
+
|
178
|
+
if not is_secondary_diag_real:
|
179
|
+
circuit.h(target)
|
180
|
+
|
181
|
+
mcx_1 = synth_mcx_n_dirty_i15(num_ctrl_qubits=k_1)
|
182
|
+
circuit.compose(mcx_1, controls[:k_1] + [target] + controls[k_1 : 2 * k_1 - 2], inplace=True)
|
183
|
+
circuit.append(s_gate, [target])
|
184
|
+
|
185
|
+
# TODO: improve CX count by using action_only=True (based on #9687)
|
186
|
+
mcx_2 = synth_mcx_n_dirty_i15(num_ctrl_qubits=k_2).to_gate()
|
187
|
+
circuit.compose(
|
188
|
+
mcx_2.inverse(), controls[k_1:] + [target] + controls[k_1 - k_2 + 2 : k_1], inplace=True
|
189
|
+
)
|
190
|
+
circuit.append(s_gate.inverse(), [target])
|
191
|
+
|
192
|
+
mcx_3 = synth_mcx_n_dirty_i15(num_ctrl_qubits=k_1).to_gate()
|
193
|
+
circuit.compose(mcx_3, controls[:k_1] + [target] + controls[k_1 : 2 * k_1 - 2], inplace=True)
|
194
|
+
circuit.append(s_gate, [target])
|
195
|
+
|
196
|
+
mcx_4 = synth_mcx_n_dirty_i15(num_ctrl_qubits=k_2).to_gate()
|
197
|
+
circuit.compose(mcx_4, controls[k_1:] + [target] + controls[k_1 - k_2 + 2 : k_1], inplace=True)
|
198
|
+
circuit.append(s_gate.inverse(), [target])
|
199
|
+
|
200
|
+
if not is_secondary_diag_real:
|
201
|
+
circuit.h(target)
|
202
|
+
|
203
|
+
if use_basis_gates:
|
204
|
+
circuit = transpile(circuit, basis_gates=["p", "u", "cx"], qubits_initially_zero=False)
|
205
|
+
|
206
|
+
return circuit
|