qiskit 1.4.1__cp39-abi3-win_amd64.whl → 2.0.0__cp39-abi3-win_amd64.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 +3 -9
- qiskit/_accelerate.pyd +0 -0
- qiskit/circuit/__init__.py +35 -10
- 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 +236 -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 +2 -141
- qiskit/circuit/instructionset.py +7 -54
- qiskit/circuit/library/__init__.py +469 -154
- 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/graph_state.py +1 -0
- 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 +7 -10
- 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 +14 -62
- 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 +11 -0
- qiskit/circuit/quantumcircuit.py +890 -564
- 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/circuit/tools/pi_check.py +3 -0
- qiskit/compiler/__init__.py +1 -7
- qiskit/compiler/transpiler.py +38 -196
- qiskit/converters/circuit_to_dag.py +6 -4
- 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 +7 -8
- 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 +5 -82
- 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 +162 -19
- qiskit/qpy/binary_io/__init__.py +0 -1
- qiskit/qpy/binary_io/circuits.py +96 -116
- qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
- qiskit/qpy/binary_io/schedules.py +61 -388
- qiskit/qpy/binary_io/value.py +159 -33
- 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 -11
- qiskit/result/result.py +38 -134
- 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 +4 -40
- qiskit/transpiler/passes/basis/basis_translator.py +5 -4
- 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 +4 -0
- qiskit/transpiler/passes/layout/dense_layout.py +2 -39
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +3 -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 +2 -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 +3 -2
- 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 +32 -4
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +25 -63
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +12 -4
- 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 +134 -62
- 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 +107 -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 +78 -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/counts_visualization.py +4 -0
- qiskit/visualization/dag_visualization.py +2 -1
- qiskit/visualization/gate_map.py +39 -154
- qiskit/visualization/library.py +4 -1
- qiskit/visualization/pass_manager_visualization.py +6 -2
- qiskit/visualization/state_visualization.py +19 -2
- qiskit/visualization/timeline/core.py +19 -13
- qiskit/visualization/timeline/interface.py +19 -18
- qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/METADATA +4 -3
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/RECORD +303 -449
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/WHEEL +1 -1
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.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.1.dist-info → qiskit-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/top_level.txt +0 -0
@@ -17,11 +17,14 @@ from typing import Callable
|
|
17
17
|
import numpy as np
|
18
18
|
from numpy.polynomial.chebyshev import Chebyshev
|
19
19
|
|
20
|
-
from qiskit.circuit import QuantumRegister, AncillaRegister
|
20
|
+
from qiskit.circuit import QuantumCircuit, QuantumRegister, AncillaRegister, Gate
|
21
21
|
from qiskit.circuit.library.blueprintcircuit import BlueprintCircuit
|
22
22
|
from qiskit.circuit.exceptions import CircuitError
|
23
23
|
|
24
|
-
from .piecewise_polynomial_pauli_rotations import
|
24
|
+
from .piecewise_polynomial_pauli_rotations import (
|
25
|
+
PiecewisePolynomialPauliRotations,
|
26
|
+
PiecewisePolynomialPauliRotationsGate,
|
27
|
+
)
|
25
28
|
|
26
29
|
|
27
30
|
class PiecewiseChebyshev(BlueprintCircuit):
|
@@ -346,9 +349,154 @@ class PiecewiseChebyshev(BlueprintCircuit):
|
|
346
349
|
self.num_state_qubits, self.breakpoints, self.polynomials, name=self.name
|
347
350
|
)
|
348
351
|
|
349
|
-
# qr_state = self.qubits[: self.num_state_qubits]
|
350
|
-
# qr_target = [self.qubits[self.num_state_qubits]]
|
351
|
-
# qr_ancillas = self.qubits[self.num_state_qubits + 1 :]
|
352
|
-
|
353
352
|
# Apply polynomial approximation
|
354
353
|
self.append(poly_r.to_gate(), self.qubits)
|
354
|
+
|
355
|
+
|
356
|
+
class PiecewiseChebyshevGate(Gate):
|
357
|
+
r"""Piecewise Chebyshev approximation to an input function.
|
358
|
+
|
359
|
+
For a given function :math:`f(x)` and degree :math:`d`, this class implements a piecewise
|
360
|
+
polynomial Chebyshev approximation on :math:`n` qubits to :math:`f(x)` on the given intervals.
|
361
|
+
All the polynomials in the approximation are of degree :math:`d`.
|
362
|
+
|
363
|
+
The values of the parameters are calculated according to [1] and see [2] for a more
|
364
|
+
detailed explanation of the circuit construction and how it acts on the qubits.
|
365
|
+
|
366
|
+
Examples:
|
367
|
+
|
368
|
+
.. plot::
|
369
|
+
:alt: Example of generating a circuit with the piecewise Chebyshev gate.
|
370
|
+
:include-source:
|
371
|
+
|
372
|
+
import numpy as np
|
373
|
+
from qiskit import QuantumCircuit
|
374
|
+
from qiskit.circuit.library.arithmetic import PiecewiseChebyshevGate
|
375
|
+
|
376
|
+
f_x, num_state_qubits, degree, breakpoints = lambda x: np.arcsin(1 / x), 2, 2, [2, 4]
|
377
|
+
pw_approximation = PiecewiseChebyshevGate(f_x, num_state_qubits, degree, breakpoints)
|
378
|
+
|
379
|
+
qc = QuantumCircuit(pw_approximation.num_qubits)
|
380
|
+
qc.h(list(range(num_state_qubits)))
|
381
|
+
qc.append(pw_approximation, qc.qubits)
|
382
|
+
qc.draw(output="mpl")
|
383
|
+
|
384
|
+
References:
|
385
|
+
|
386
|
+
[1]: Haener, T., Roetteler, M., & Svore, K. M. (2018).
|
387
|
+
Optimizing Quantum Circuits for Arithmetic.
|
388
|
+
`arXiv:1805.12445 <http://arxiv.org/abs/1805.12445>`_
|
389
|
+
[2]: Carrera Vazquez, A., Hiptmair, H., & Woerner, S. (2022).
|
390
|
+
Enhancing the Quantum Linear Systems Algorithm Using Richardson Extrapolation.
|
391
|
+
`ACM Transactions on Quantum Computing 3, 1, Article 2 <https://doi.org/10.1145/3490631>`_
|
392
|
+
"""
|
393
|
+
|
394
|
+
def __init__(
|
395
|
+
self,
|
396
|
+
f_x: float | Callable[[int], float],
|
397
|
+
num_state_qubits: int,
|
398
|
+
degree: int | None = None,
|
399
|
+
breakpoints: list[int] | None = None,
|
400
|
+
label: str | None = None,
|
401
|
+
) -> None:
|
402
|
+
r"""
|
403
|
+
Args:
|
404
|
+
f_x: the function to be approximated. Constant functions should be specified
|
405
|
+
as f_x = constant.
|
406
|
+
num_state_qubits: number of qubits representing the state.
|
407
|
+
degree: the degree of the polynomials.
|
408
|
+
Defaults to ``1``.
|
409
|
+
breakpoints: the breakpoints to define the piecewise-linear function.
|
410
|
+
Defaults to the full interval.
|
411
|
+
label: A label for the gate.
|
412
|
+
"""
|
413
|
+
# Store parameters
|
414
|
+
self.f_x = f_x
|
415
|
+
self.degree = degree if degree is not None else 1
|
416
|
+
self.num_state_qubits = num_state_qubits
|
417
|
+
|
418
|
+
# validate the breakpoints
|
419
|
+
if breakpoints is None:
|
420
|
+
breakpoints = [0]
|
421
|
+
|
422
|
+
# If the last breakpoint is < num_states, add the identity polynomial
|
423
|
+
num_states = 2**num_state_qubits
|
424
|
+
if breakpoints[-1] < num_states:
|
425
|
+
breakpoints = breakpoints + [num_states]
|
426
|
+
|
427
|
+
# If the first breakpoint is > 0, add the identity polynomial
|
428
|
+
if breakpoints[0] > 0:
|
429
|
+
breakpoints = [0] + breakpoints
|
430
|
+
|
431
|
+
self.breakpoints = breakpoints
|
432
|
+
|
433
|
+
num_compare = int(len(breakpoints) > 2)
|
434
|
+
super().__init__("PiecewiseChebyshev", num_state_qubits + num_compare + 1, [], label)
|
435
|
+
|
436
|
+
# after initialization, build the polynomials
|
437
|
+
self.polynomials = self._build_polynomials()
|
438
|
+
|
439
|
+
def _build_polynomials(self):
|
440
|
+
"""The polynomials for the piecewise approximation.
|
441
|
+
|
442
|
+
Returns:
|
443
|
+
The polynomials for the piecewise approximation.
|
444
|
+
|
445
|
+
Raises:
|
446
|
+
TypeError: If the input function is not in the correct format.
|
447
|
+
"""
|
448
|
+
|
449
|
+
# note this must be the private attribute since we handle missing breakpoints at
|
450
|
+
# 0 and 2 ^ num_qubits here (e.g. if the function we approximate is not defined at 0
|
451
|
+
# and the user takes that into account we just add an identity)
|
452
|
+
breakpoints = self.breakpoints
|
453
|
+
|
454
|
+
# Need to take into account the case in which no breakpoints were provided in first place
|
455
|
+
num_state_qubits = self.num_qubits - 1
|
456
|
+
if breakpoints == [0]:
|
457
|
+
breakpoints = [0, 2**num_state_qubits]
|
458
|
+
|
459
|
+
num_intervals = len(breakpoints)
|
460
|
+
|
461
|
+
# Calculate the polynomials
|
462
|
+
polynomials = []
|
463
|
+
for i in range(0, num_intervals - 1):
|
464
|
+
# Calculate the polynomial approximating the function on the current interval
|
465
|
+
try:
|
466
|
+
# If the function is constant don't call Chebyshev (not necessary and gives errors)
|
467
|
+
if isinstance(self.f_x, (float, int)):
|
468
|
+
# Append directly to list of polynomials
|
469
|
+
polynomials.append([self.f_x])
|
470
|
+
else:
|
471
|
+
poly = Chebyshev.interpolate(
|
472
|
+
self.f_x, self.degree, domain=[breakpoints[i], breakpoints[i + 1]]
|
473
|
+
)
|
474
|
+
# Convert polynomial to the standard basis and rescale it for the rotation gates
|
475
|
+
poly = 2 * poly.convert(kind=np.polynomial.Polynomial).coef
|
476
|
+
# Convert to list and append
|
477
|
+
polynomials.append(poly.tolist())
|
478
|
+
except ValueError as err:
|
479
|
+
raise TypeError(
|
480
|
+
" <lambda>() missing 1 required positional argument: '"
|
481
|
+
+ self.f_x.__code__.co_varnames[0]
|
482
|
+
+ "'."
|
483
|
+
+ " Constant functions should be specified as 'f_x = constant'."
|
484
|
+
) from err
|
485
|
+
|
486
|
+
# If the last breakpoint is < 2 ** num_qubits, add the identity polynomial
|
487
|
+
if breakpoints[-1] < 2**num_state_qubits:
|
488
|
+
polynomials = polynomials + [[2 * np.arcsin(1)]]
|
489
|
+
|
490
|
+
# If the first breakpoint is > 0, add the identity polynomial
|
491
|
+
if breakpoints[0] > 0:
|
492
|
+
polynomials = [[2 * np.arcsin(1)]] + polynomials
|
493
|
+
|
494
|
+
return polynomials
|
495
|
+
|
496
|
+
def _define(self):
|
497
|
+
poly_r = PiecewisePolynomialPauliRotationsGate(
|
498
|
+
self.num_state_qubits, self.breakpoints, self.polynomials
|
499
|
+
)
|
500
|
+
|
501
|
+
self.definition = QuantumCircuit(poly_r.num_qubits)
|
502
|
+
self.definition.append(poly_r, self.definition.qubits)
|
@@ -14,14 +14,15 @@
|
|
14
14
|
"""Piecewise-linearly-controlled rotation."""
|
15
15
|
|
16
16
|
from __future__ import annotations
|
17
|
+
from collections.abc import Sequence
|
17
18
|
import numpy as np
|
18
19
|
|
19
|
-
from qiskit.circuit import QuantumRegister, AncillaRegister, QuantumCircuit
|
20
|
+
from qiskit.circuit import QuantumRegister, AncillaRegister, QuantumCircuit, Gate
|
20
21
|
from qiskit.circuit.exceptions import CircuitError
|
21
22
|
|
22
23
|
from .functional_pauli_rotations import FunctionalPauliRotations
|
23
|
-
from .linear_pauli_rotations import LinearPauliRotations
|
24
|
-
from .integer_comparator import IntegerComparator
|
24
|
+
from .linear_pauli_rotations import LinearPauliRotations, LinearPauliRotationsGate
|
25
|
+
from .integer_comparator import IntegerComparator, IntegerComparatorGate
|
25
26
|
|
26
27
|
|
27
28
|
class PiecewiseLinearPauliRotations(FunctionalPauliRotations):
|
@@ -272,6 +273,115 @@ class PiecewiseLinearPauliRotations(FunctionalPauliRotations):
|
|
272
273
|
circuit.append(lin_r.to_gate().control(), qr_compare[:] + qr_state[:] + qr_target)
|
273
274
|
|
274
275
|
# uncompute comparator
|
275
|
-
circuit.append(comp.to_gate()
|
276
|
+
circuit.append(comp.to_gate(), qr[:] + qr_helper[: comp.num_ancillas])
|
276
277
|
|
277
278
|
self.append(circuit.to_gate(), self.qubits)
|
279
|
+
|
280
|
+
|
281
|
+
class PiecewiseLinearPauliRotationsGate(Gate):
|
282
|
+
r"""Piecewise-linearly-controlled Pauli rotations.
|
283
|
+
|
284
|
+
For a piecewise linear (not necessarily continuous) function :math:`f(x)`, which is defined
|
285
|
+
through breakpoints, slopes and offsets as follows.
|
286
|
+
Suppose the breakpoints :math:`(x_0, ..., x_J)` are a subset of :math:`[0, 2^n-1]`, where
|
287
|
+
:math:`n` is the number of state qubits. Further on, denote the corresponding slopes and
|
288
|
+
offsets by :math:`a_j` and :math:`b_j` respectively.
|
289
|
+
Then f(x) is defined as:
|
290
|
+
|
291
|
+
.. math::
|
292
|
+
|
293
|
+
f(x) = \begin{cases}
|
294
|
+
0, x < x_0 \\
|
295
|
+
a_j (x - x_j) + b_j, x_j \leq x < x_{j+1}
|
296
|
+
\end{cases}
|
297
|
+
|
298
|
+
where we implicitly assume :math:`x_{J+1} = 2^n`.
|
299
|
+
"""
|
300
|
+
|
301
|
+
def __init__(
|
302
|
+
self,
|
303
|
+
num_state_qubits: int | None = None,
|
304
|
+
breakpoints: list[int] | None = None,
|
305
|
+
slopes: Sequence[float] | None = None,
|
306
|
+
offsets: Sequence[float] | None = None,
|
307
|
+
basis: str = "Y",
|
308
|
+
label: str | None = None,
|
309
|
+
) -> None:
|
310
|
+
"""Construct piecewise-linearly-controlled Pauli rotations.
|
311
|
+
|
312
|
+
Args:
|
313
|
+
num_state_qubits: The number of qubits representing the state.
|
314
|
+
breakpoints: The breakpoints to define the piecewise-linear function.
|
315
|
+
Defaults to ``[0]``.
|
316
|
+
slopes: The slopes for different segments of the piecewise-linear function.
|
317
|
+
Defaults to ``[1]``.
|
318
|
+
offsets: The offsets for different segments of the piecewise-linear function.
|
319
|
+
Defaults to ``[0]``.
|
320
|
+
basis: The type of Pauli rotation (``'X'``, ``'Y'``, ``'Z'``).
|
321
|
+
label: The label of the gate.
|
322
|
+
"""
|
323
|
+
self.breakpoints = breakpoints if breakpoints is not None else [0]
|
324
|
+
self.slopes = slopes if slopes is not None else [1]
|
325
|
+
self.offsets = offsets if offsets is not None else [0]
|
326
|
+
self.basis = basis
|
327
|
+
|
328
|
+
num_compare_bits = 1 if len(self.breakpoints) > 1 else 0
|
329
|
+
super().__init__("PwLinPauliRot", num_state_qubits + 1 + num_compare_bits, [], label=label)
|
330
|
+
|
331
|
+
def _define(self):
|
332
|
+
circuit = QuantumCircuit(self.num_qubits, name=self.name)
|
333
|
+
|
334
|
+
if len(self.breakpoints) == 1:
|
335
|
+
qr_state = circuit.qubits[: self.num_qubits - 1]
|
336
|
+
qr_target = [circuit.qubits[-1]]
|
337
|
+
qr_compare = []
|
338
|
+
else:
|
339
|
+
qr_state = circuit.qubits[: self.num_qubits - 2]
|
340
|
+
qr_target = [circuit.qubits[-2]]
|
341
|
+
qr_compare = [circuit.qubits[-1]]
|
342
|
+
|
343
|
+
num_state_qubits = len(qr_state)
|
344
|
+
|
345
|
+
mapped_slopes = np.zeros_like(self.slopes)
|
346
|
+
for i, slope in enumerate(self.slopes):
|
347
|
+
mapped_slopes[i] = slope - sum(mapped_slopes[:i])
|
348
|
+
|
349
|
+
mapped_offsets = np.zeros_like(self.offsets)
|
350
|
+
for i, (offset, slope, point) in enumerate(
|
351
|
+
zip(self.offsets, self.slopes, self.breakpoints)
|
352
|
+
):
|
353
|
+
mapped_offsets[i] = offset - slope * point - sum(mapped_offsets[:i])
|
354
|
+
|
355
|
+
# apply comparators and controlled linear rotations
|
356
|
+
contains_zero_breakpoint = np.isclose(self.breakpoints[0], 0)
|
357
|
+
for i, point in enumerate(self.breakpoints):
|
358
|
+
if i == 0 and contains_zero_breakpoint:
|
359
|
+
# apply rotation
|
360
|
+
lin_r = LinearPauliRotationsGate(
|
361
|
+
num_state_qubits=num_state_qubits,
|
362
|
+
slope=mapped_slopes[i],
|
363
|
+
offset=mapped_offsets[i],
|
364
|
+
basis=self.basis,
|
365
|
+
)
|
366
|
+
circuit.append(lin_r, qr_state[:] + qr_target)
|
367
|
+
|
368
|
+
else:
|
369
|
+
# apply Comparator
|
370
|
+
comp = IntegerComparatorGate(num_state_qubits=num_state_qubits, value=point)
|
371
|
+
qr = qr_state[:] + qr_compare[:] # add ancilla as compare qubit
|
372
|
+
|
373
|
+
circuit.append(comp, qr[:])
|
374
|
+
|
375
|
+
# apply controlled rotation
|
376
|
+
lin_r = LinearPauliRotationsGate(
|
377
|
+
num_state_qubits=num_state_qubits,
|
378
|
+
slope=mapped_slopes[i],
|
379
|
+
offset=mapped_offsets[i],
|
380
|
+
basis=self.basis,
|
381
|
+
)
|
382
|
+
circuit.append(lin_r.control(), qr_compare[:] + qr_state[:] + qr_target)
|
383
|
+
|
384
|
+
# uncompute comparator (which is its self-inverse)
|
385
|
+
circuit.append(comp, qr[:])
|
386
|
+
|
387
|
+
self.definition = circuit
|
@@ -16,12 +16,12 @@ from __future__ import annotations
|
|
16
16
|
from typing import List, Optional
|
17
17
|
import numpy as np
|
18
18
|
|
19
|
-
from qiskit.circuit import QuantumRegister, AncillaRegister, QuantumCircuit
|
19
|
+
from qiskit.circuit import QuantumRegister, AncillaRegister, QuantumCircuit, Gate
|
20
20
|
from qiskit.circuit.exceptions import CircuitError
|
21
21
|
|
22
22
|
from .functional_pauli_rotations import FunctionalPauliRotations
|
23
|
-
from .polynomial_pauli_rotations import PolynomialPauliRotations
|
24
|
-
from .integer_comparator import IntegerComparator
|
23
|
+
from .polynomial_pauli_rotations import PolynomialPauliRotations, PolynomialPauliRotationsGate
|
24
|
+
from .integer_comparator import IntegerComparator, IntegerComparatorGate
|
25
25
|
|
26
26
|
|
27
27
|
class PiecewisePolynomialPauliRotations(FunctionalPauliRotations):
|
@@ -101,8 +101,8 @@ class PiecewisePolynomialPauliRotations(FunctionalPauliRotations):
|
|
101
101
|
breakpoints: The breakpoints to define the piecewise-linear function.
|
102
102
|
Defaults to ``[0]``.
|
103
103
|
coeffs: The coefficients of the polynomials for different segments of the
|
104
|
-
|
105
|
-
|
104
|
+
piecewise-linear function. ``coeffs[j][i]`` is the coefficient of the i-th power of x
|
105
|
+
for the j-th polynomial.
|
106
106
|
Defaults to linear: ``[[1]]``.
|
107
107
|
basis: The type of Pauli rotation (``'X'``, ``'Y'``, ``'Z'``).
|
108
108
|
name: The name of the circuit.
|
@@ -187,16 +187,7 @@ class PiecewisePolynomialPauliRotations(FunctionalPauliRotations):
|
|
187
187
|
Returns:
|
188
188
|
The mapped coefficients.
|
189
189
|
"""
|
190
|
-
|
191
|
-
|
192
|
-
# First polynomial
|
193
|
-
mapped_coeffs.append(self._hom_coeffs[0])
|
194
|
-
for i in range(1, len(self._hom_coeffs)):
|
195
|
-
mapped_coeffs.append([])
|
196
|
-
for j in range(0, self._degree + 1):
|
197
|
-
mapped_coeffs[i].append(self._hom_coeffs[i][j] - self._hom_coeffs[i - 1][j])
|
198
|
-
|
199
|
-
return mapped_coeffs
|
190
|
+
return _map_coeffs(self._hom_coeffs)
|
200
191
|
|
201
192
|
@property
|
202
193
|
def contains_zero_breakpoint(self) -> bool | np.bool_:
|
@@ -315,3 +306,188 @@ class PiecewisePolynomialPauliRotations(FunctionalPauliRotations):
|
|
315
306
|
)
|
316
307
|
|
317
308
|
self.append(circuit.to_gate(), self.qubits)
|
309
|
+
|
310
|
+
|
311
|
+
class PiecewisePolynomialPauliRotationsGate(Gate):
|
312
|
+
r"""Piecewise-polynomially-controlled Pauli rotations.
|
313
|
+
|
314
|
+
This class implements a piecewise polynomial (not necessarily continuous) function,
|
315
|
+
:math:`f(x)`, on qubit amplitudes, which is defined through breakpoints and coefficients as
|
316
|
+
follows.
|
317
|
+
Suppose the breakpoints :math:`(x_0, ..., x_J)` are a subset of :math:`[0, 2^n-1]`, where
|
318
|
+
:math:`n` is the number of state qubits. Further on, denote the corresponding coefficients by
|
319
|
+
:math:`[a_{j,1},...,a_{j,d}]`, where :math:`d` is the highest degree among all polynomials.
|
320
|
+
|
321
|
+
Then :math:`f(x)` is defined as:
|
322
|
+
|
323
|
+
.. math::
|
324
|
+
|
325
|
+
f(x) = \begin{cases}
|
326
|
+
0, x < x_0 \\
|
327
|
+
\sum_{i=0}^{i=d}a_{j,i}/2 x^i, x_j \leq x < x_{j+1}
|
328
|
+
\end{cases}
|
329
|
+
|
330
|
+
where if given the same number of breakpoints as polynomials, we implicitly assume
|
331
|
+
:math:`x_{J+1} = 2^n`.
|
332
|
+
|
333
|
+
.. note::
|
334
|
+
|
335
|
+
Note the :math:`1/2` factor in the coefficients of :math:`f(x)`, this is consistent with
|
336
|
+
Qiskit's Pauli rotations.
|
337
|
+
|
338
|
+
Examples:
|
339
|
+
>>> from qiskit import QuantumCircuit
|
340
|
+
>>> from qiskit.circuit.library.arithmetic.piecewise_polynomial_pauli_rotations import\
|
341
|
+
... PiecewisePolynomialPauliRotations
|
342
|
+
>>> qubits, breakpoints, coeffs = (2, [0, 2], [[0, -1.2],[-1, 1, 3]])
|
343
|
+
>>> poly_r = PiecewisePolynomialPauliRotations(num_state_qubits=qubits,
|
344
|
+
...breakpoints=breakpoints, coeffs=coeffs)
|
345
|
+
>>>
|
346
|
+
>>> qc = QuantumCircuit(poly_r.num_qubits)
|
347
|
+
>>> qc.h(list(range(qubits)));
|
348
|
+
>>> qc.append(poly_r.to_instruction(), list(range(qc.num_qubits)));
|
349
|
+
>>> qc.draw()
|
350
|
+
┌───┐┌──────────┐
|
351
|
+
q_0: ┤ H ├┤0 ├
|
352
|
+
├───┤│ │
|
353
|
+
q_1: ┤ H ├┤1 ├
|
354
|
+
└───┘│ │
|
355
|
+
q_2: ─────┤2 ├
|
356
|
+
│ pw_poly │
|
357
|
+
q_3: ─────┤3 ├
|
358
|
+
│ │
|
359
|
+
q_4: ─────┤4 ├
|
360
|
+
│ │
|
361
|
+
q_5: ─────┤5 ├
|
362
|
+
└──────────┘
|
363
|
+
|
364
|
+
References:
|
365
|
+
[1]: Haener, T., Roetteler, M., & Svore, K. M. (2018).
|
366
|
+
Optimizing Quantum Circuits for Arithmetic.
|
367
|
+
`arXiv:1805.12445 <http://arxiv.org/abs/1805.12445>`_
|
368
|
+
|
369
|
+
[2]: Carrera Vazquez, A., Hiptmair, R., & Woerner, S. (2022).
|
370
|
+
Enhancing the Quantum Linear Systems Algorithm using Richardson Extrapolation.
|
371
|
+
`ACM Transactions on Quantum Computing 3, 1, Article 2 <https://doi.org/10.1145/3490631>`_
|
372
|
+
"""
|
373
|
+
|
374
|
+
def __init__(
|
375
|
+
self,
|
376
|
+
num_state_qubits: int,
|
377
|
+
breakpoints: list[int] | None = None,
|
378
|
+
coeffs: list[list[float]] | None = None,
|
379
|
+
basis: str = "Y",
|
380
|
+
label: str | None = None,
|
381
|
+
) -> None:
|
382
|
+
"""
|
383
|
+
Args:
|
384
|
+
num_state_qubits: The number of qubits representing the state.
|
385
|
+
breakpoints: The breakpoints to define the piecewise-linear function.
|
386
|
+
Defaults to ``[0]``.
|
387
|
+
coeffs: The coefficients of the polynomials for different segments of the
|
388
|
+
piecewise-linear function. ``coeffs[j][i]`` is the coefficient of the i-th power of x
|
389
|
+
for the j-th polynomial.
|
390
|
+
Defaults to linear: ``[[1]]``.
|
391
|
+
basis: The type of Pauli rotation (``'X'``, ``'Y'``, ``'Z'``).
|
392
|
+
label: An optional label for the gate.
|
393
|
+
"""
|
394
|
+
|
395
|
+
if coeffs is None:
|
396
|
+
degree = 0
|
397
|
+
coeffs = [[1]]
|
398
|
+
else:
|
399
|
+
# store a list of coefficients as homogeneous polynomials adding 0's where necessary
|
400
|
+
degree = len(max(coeffs, key=len)) - 1
|
401
|
+
coeffs = [poly + [0] * (degree + 1 - len(poly)) for poly in coeffs]
|
402
|
+
|
403
|
+
# ensure the breakpoint contains 2 ** num_state_qubits
|
404
|
+
breakpoints = breakpoints.copy()
|
405
|
+
if breakpoints is None:
|
406
|
+
breakpoints = [0, 2**num_state_qubits]
|
407
|
+
elif breakpoints[-1] < 2**num_state_qubits:
|
408
|
+
breakpoints.append(2**num_state_qubits)
|
409
|
+
|
410
|
+
self.coeffs = coeffs
|
411
|
+
self.breakpoints = breakpoints
|
412
|
+
self.basis = basis
|
413
|
+
|
414
|
+
self.num_compare = int(len(self.breakpoints) > 2)
|
415
|
+
super().__init__(
|
416
|
+
"PiecewisePolyPauli", num_state_qubits + self.num_compare + 1, [], label=label
|
417
|
+
)
|
418
|
+
|
419
|
+
def evaluate(self, x: float) -> float:
|
420
|
+
"""Classically evaluate the piecewise polynomial rotation.
|
421
|
+
|
422
|
+
Args:
|
423
|
+
x: Value to be evaluated at.
|
424
|
+
|
425
|
+
Returns:
|
426
|
+
Value of piecewise polynomial function at x.
|
427
|
+
"""
|
428
|
+
mapped_coeffs = _map_coeffs(self.coeffs)
|
429
|
+
|
430
|
+
y = 0
|
431
|
+
for i, breakpt in enumerate(self.breakpoints):
|
432
|
+
y = y + (x >= breakpt) * (np.poly1d(mapped_coeffs[i][::-1])(x))
|
433
|
+
|
434
|
+
return y
|
435
|
+
|
436
|
+
def _define(self):
|
437
|
+
num_state_qubits = self.num_qubits - self.num_compare - 1
|
438
|
+
circuit = QuantumCircuit(self.num_qubits, name=self.name)
|
439
|
+
qr_state = circuit.qubits[:num_state_qubits]
|
440
|
+
|
441
|
+
if len(self.breakpoints) > 2:
|
442
|
+
qr_target = [circuit.qubits[-2]]
|
443
|
+
qr_compare = [circuit.qubits[-1]]
|
444
|
+
else:
|
445
|
+
qr_target = [circuit.qubits[-1]]
|
446
|
+
qr_compare = []
|
447
|
+
|
448
|
+
# apply comparators and controlled linear rotations
|
449
|
+
contains_zero_breakpoint = np.isclose(self.breakpoints[0], 0)
|
450
|
+
mapped_coeffs = _map_coeffs(self.coeffs)
|
451
|
+
|
452
|
+
for i, point in enumerate(self.breakpoints[:-1]):
|
453
|
+
if i == 0 and contains_zero_breakpoint:
|
454
|
+
# apply rotation
|
455
|
+
poly_r = PolynomialPauliRotationsGate(
|
456
|
+
num_state_qubits=num_state_qubits,
|
457
|
+
coeffs=mapped_coeffs[i],
|
458
|
+
basis=self.basis,
|
459
|
+
)
|
460
|
+
circuit.append(poly_r, qr_state[:] + qr_target)
|
461
|
+
|
462
|
+
else:
|
463
|
+
# apply Comparator
|
464
|
+
comp = IntegerComparatorGate(num_state_qubits=num_state_qubits, value=point)
|
465
|
+
qr_state_full = qr_state[:] + qr_compare # add compare qubit
|
466
|
+
|
467
|
+
circuit.append(comp, qr_state_full[:])
|
468
|
+
|
469
|
+
# apply controlled rotation
|
470
|
+
poly_r = PolynomialPauliRotationsGate(
|
471
|
+
num_state_qubits=num_state_qubits,
|
472
|
+
coeffs=mapped_coeffs[i],
|
473
|
+
basis=self.basis,
|
474
|
+
)
|
475
|
+
circuit.append(poly_r.control(), qr_compare + qr_state[:] + qr_target)
|
476
|
+
|
477
|
+
# uncompute comparator
|
478
|
+
circuit.append(comp, qr_state_full[:])
|
479
|
+
|
480
|
+
self.definition = circuit
|
481
|
+
|
482
|
+
|
483
|
+
def _map_coeffs(coeffs):
|
484
|
+
mapped_coeffs = []
|
485
|
+
mapped_coeffs.append(coeffs[0])
|
486
|
+
|
487
|
+
degree = len(coeffs[0]) - 1 # all coeffs should have the same length by now
|
488
|
+
for i in range(1, len(coeffs)):
|
489
|
+
mapped_coeffs.append([])
|
490
|
+
for j in range(0, degree + 1):
|
491
|
+
mapped_coeffs[i].append(coeffs[i][j] - coeffs[i - 1][j])
|
492
|
+
|
493
|
+
return mapped_coeffs
|