qiskit 1.4.1__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 +2 -141
- 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 +154 -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 +4 -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 +18 -12
- qiskit/visualization/timeline/interface.py +19 -18
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +2 -1
- {qiskit-1.4.1.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.1.dist-info → qiskit-2.0.0rc1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -14,11 +14,13 @@
|
|
14
14
|
"""Integer Comparator."""
|
15
15
|
|
16
16
|
from __future__ import annotations
|
17
|
-
import math
|
18
17
|
|
19
|
-
from qiskit.circuit import
|
18
|
+
from qiskit.circuit import QuantumRegister, AncillaRegister, Gate
|
20
19
|
from qiskit.circuit.exceptions import CircuitError
|
21
|
-
from
|
20
|
+
from qiskit.synthesis.arithmetic.comparators import (
|
21
|
+
synth_integer_comparator_2s,
|
22
|
+
synth_integer_comparator_greedy,
|
23
|
+
)
|
22
24
|
from ..blueprintcircuit import BlueprintCircuit
|
23
25
|
|
24
26
|
|
@@ -134,19 +136,6 @@ class IntegerComparator(BlueprintCircuit):
|
|
134
136
|
qr_ancilla = AncillaRegister(num_ancillas)
|
135
137
|
self.add_register(qr_ancilla)
|
136
138
|
|
137
|
-
def _get_twos_complement(self) -> list[int]:
|
138
|
-
"""Returns the 2's complement of ``self.value`` as array.
|
139
|
-
|
140
|
-
Returns:
|
141
|
-
The 2's complement of ``self.value``.
|
142
|
-
"""
|
143
|
-
twos_complement = pow(2, self.num_state_qubits) - math.ceil(self.value)
|
144
|
-
twos_complement = f"{twos_complement:b}".rjust(self.num_state_qubits, "0")
|
145
|
-
twos_complement = [
|
146
|
-
1 if twos_complement[i] == "1" else 0 for i in reversed(range(len(twos_complement)))
|
147
|
-
]
|
148
|
-
return twos_complement
|
149
|
-
|
150
139
|
def _check_configuration(self, raise_on_failure: bool = True) -> bool:
|
151
140
|
"""Check if the current configuration is valid."""
|
152
141
|
valid = True
|
@@ -176,68 +165,36 @@ class IntegerComparator(BlueprintCircuit):
|
|
176
165
|
|
177
166
|
super()._build()
|
178
167
|
|
179
|
-
|
180
|
-
q_compare = self.qubits[self.num_state_qubits]
|
181
|
-
qr_ancilla = self.qubits[self.num_state_qubits + 1 :]
|
182
|
-
|
183
|
-
circuit = QuantumCircuit(*self.qregs, name=self.name)
|
184
|
-
|
185
|
-
if self.value <= 0: # condition always satisfied for non-positive values
|
186
|
-
if self._geq: # otherwise the condition is never satisfied
|
187
|
-
circuit.x(q_compare)
|
188
|
-
# condition never satisfied for values larger than or equal to 2^n
|
189
|
-
elif self.value < pow(2, self.num_state_qubits):
|
190
|
-
|
191
|
-
if self.num_state_qubits > 1:
|
192
|
-
twos = self._get_twos_complement()
|
193
|
-
for i in range(self.num_state_qubits):
|
194
|
-
if i == 0:
|
195
|
-
if twos[i] == 1:
|
196
|
-
circuit.cx(qr_state[i], qr_ancilla[i])
|
197
|
-
elif i < self.num_state_qubits - 1:
|
198
|
-
if twos[i] == 1:
|
199
|
-
circuit.compose(
|
200
|
-
OR(2), [qr_state[i], qr_ancilla[i - 1], qr_ancilla[i]], inplace=True
|
201
|
-
)
|
202
|
-
else:
|
203
|
-
circuit.ccx(qr_state[i], qr_ancilla[i - 1], qr_ancilla[i])
|
204
|
-
else:
|
205
|
-
if twos[i] == 1:
|
206
|
-
# OR needs the result argument as qubit not register, thus
|
207
|
-
# access the index [0]
|
208
|
-
circuit.compose(
|
209
|
-
OR(2), [qr_state[i], qr_ancilla[i - 1], q_compare], inplace=True
|
210
|
-
)
|
211
|
-
else:
|
212
|
-
circuit.ccx(qr_state[i], qr_ancilla[i - 1], q_compare)
|
213
|
-
|
214
|
-
# flip result bit if geq flag is false
|
215
|
-
if not self._geq:
|
216
|
-
circuit.x(q_compare)
|
217
|
-
|
218
|
-
# uncompute ancillas state
|
219
|
-
for i in reversed(range(self.num_state_qubits - 1)):
|
220
|
-
if i == 0:
|
221
|
-
if twos[i] == 1:
|
222
|
-
circuit.cx(qr_state[i], qr_ancilla[i])
|
223
|
-
else:
|
224
|
-
if twos[i] == 1:
|
225
|
-
circuit.compose(
|
226
|
-
OR(2), [qr_state[i], qr_ancilla[i - 1], qr_ancilla[i]], inplace=True
|
227
|
-
)
|
228
|
-
else:
|
229
|
-
circuit.ccx(qr_state[i], qr_ancilla[i - 1], qr_ancilla[i])
|
230
|
-
else:
|
231
|
-
|
232
|
-
# num_state_qubits == 1 and value == 1:
|
233
|
-
circuit.cx(qr_state[0], q_compare)
|
234
|
-
|
235
|
-
# flip result bit if geq flag is false
|
236
|
-
if not self._geq:
|
237
|
-
circuit.x(q_compare)
|
238
|
-
|
239
|
-
else:
|
240
|
-
if not self._geq: # otherwise the condition is never satisfied
|
241
|
-
circuit.x(q_compare)
|
242
|
-
|
168
|
+
circuit = synth_integer_comparator_2s(self.num_state_qubits, self.value, self.geq)
|
243
169
|
self.append(circuit.to_gate(), self.qubits)
|
170
|
+
|
171
|
+
|
172
|
+
class IntegerComparatorGate(Gate):
|
173
|
+
r"""Perform a :math:`\geq` (or :math:`<`) on a qubit register against a classical integer.
|
174
|
+
|
175
|
+
This operator compares basis states :math:`|i\rangle_n` against a classically given integer
|
176
|
+
:math:`L` of fixed value and flips a target qubit if :math:`i \geq L`
|
177
|
+
(or :math:`<` depending on the parameter ``geq``):
|
178
|
+
|
179
|
+
.. math::
|
180
|
+
|
181
|
+
|i\rangle_n |0\rangle \mapsto |i\rangle_n |i \geq L\rangle
|
182
|
+
|
183
|
+
"""
|
184
|
+
|
185
|
+
def __init__(
|
186
|
+
self, num_state_qubits: int, value: int, geq: bool = True, label: str | None = None
|
187
|
+
):
|
188
|
+
r"""
|
189
|
+
Args:
|
190
|
+
num_state_qubits: The number of qubits in the registers.
|
191
|
+
value: The value :math:`L` to compre to.
|
192
|
+
geq: If ``True`` compute :math:`i \geq L`, otherwise compute :math:`i < L`.
|
193
|
+
label: An optional label for the gate.
|
194
|
+
"""
|
195
|
+
super().__init__("IntComp", num_state_qubits + 1, [], label=label)
|
196
|
+
self.value = value
|
197
|
+
self.geq = geq
|
198
|
+
|
199
|
+
def _define(self):
|
200
|
+
self.definition = synth_integer_comparator_greedy(self.num_qubits - 1, self.value, self.geq)
|
@@ -14,9 +14,12 @@
|
|
14
14
|
|
15
15
|
from __future__ import annotations
|
16
16
|
import numpy as np
|
17
|
-
from qiskit.circuit import QuantumCircuit
|
17
|
+
from qiskit.circuit import QuantumCircuit, Gate
|
18
18
|
|
19
|
-
from .piecewise_linear_pauli_rotations import
|
19
|
+
from .piecewise_linear_pauli_rotations import (
|
20
|
+
PiecewiseLinearPauliRotations,
|
21
|
+
PiecewiseLinearPauliRotationsGate,
|
22
|
+
)
|
20
23
|
|
21
24
|
|
22
25
|
class LinearAmplitudeFunction(QuantumCircuit):
|
@@ -173,6 +176,170 @@ class LinearAmplitudeFunction(QuantumCircuit):
|
|
173
176
|
return value
|
174
177
|
|
175
178
|
|
179
|
+
class LinearAmplitudeFunctionGate(Gate):
|
180
|
+
r"""A circuit implementing a (piecewise) linear function on qubit amplitudes.
|
181
|
+
|
182
|
+
An amplitude function :math:`F` of a function :math:`f` is a mapping
|
183
|
+
|
184
|
+
.. math::
|
185
|
+
|
186
|
+
F|x\rangle|0\rangle = \sqrt{1 - \hat{f}(x)} |x\rangle|0\rangle + \sqrt{\hat{f}(x)}
|
187
|
+
|x\rangle|1\rangle.
|
188
|
+
|
189
|
+
for a function :math:`\hat{f}: \{ 0, ..., 2^n - 1 \} \rightarrow [0, 1]`, where
|
190
|
+
:math:`|x\rangle` is a :math:`n` qubit state.
|
191
|
+
|
192
|
+
This circuit implements :math:`F` for piecewise linear functions :math:`\hat{f}`.
|
193
|
+
In this case, the mapping :math:`F` can be approximately implemented using a Taylor expansion
|
194
|
+
and linearly controlled Pauli-Y rotations, see [1, 2] for more detail. This approximation
|
195
|
+
uses a ``rescaling_factor`` to determine the accuracy of the Taylor expansion.
|
196
|
+
|
197
|
+
In general, the function of interest :math:`f` is defined from some interval :math:`[a,b]`,
|
198
|
+
the ``domain`` to :math:`[c,d]`, the ``image``, instead of :math:`\{ 1, ..., N \}` to
|
199
|
+
:math:`[0, 1]`. Using an affine transformation we can rescale :math:`f` to :math:`\hat{f}`:
|
200
|
+
|
201
|
+
.. math::
|
202
|
+
|
203
|
+
\hat{f}(x) = \frac{f(\phi(x)) - c}{d - c}
|
204
|
+
|
205
|
+
with
|
206
|
+
|
207
|
+
.. math::
|
208
|
+
|
209
|
+
\phi(x) = a + \frac{b - a}{2^n - 1} x.
|
210
|
+
|
211
|
+
If :math:`f` is a piecewise linear function on :math:`m` intervals
|
212
|
+
:math:`[p_{i-1}, p_i], i \in \{1, ..., m\}` with slopes :math:`\alpha_i` and
|
213
|
+
offsets :math:`\beta_i` it can be written as
|
214
|
+
|
215
|
+
.. math::
|
216
|
+
|
217
|
+
f(x) = \sum_{i=1}^m 1_{[p_{i-1}, p_i]}(x) (\alpha_i x + \beta_i)
|
218
|
+
|
219
|
+
where :math:`1_{[a, b]}` is an indication function that is 1 if the argument is in the interval
|
220
|
+
:math:`[a, b]` and otherwise 0. The breakpoints :math:`p_i` can be specified by the
|
221
|
+
``breakpoints`` argument.
|
222
|
+
|
223
|
+
References:
|
224
|
+
|
225
|
+
[1]: Woerner, S., & Egger, D. J. (2018).
|
226
|
+
Quantum Risk Analysis.
|
227
|
+
`arXiv:1806.06893 <http://arxiv.org/abs/1806.06893>`_
|
228
|
+
|
229
|
+
[2]: Gacon, J., Zoufal, C., & Woerner, S. (2020).
|
230
|
+
Quantum-Enhanced Simulation-Based Optimization.
|
231
|
+
`arXiv:2005.10780 <http://arxiv.org/abs/2005.10780>`_
|
232
|
+
"""
|
233
|
+
|
234
|
+
def __init__(
|
235
|
+
self,
|
236
|
+
num_state_qubits: int,
|
237
|
+
slope: float | list[float],
|
238
|
+
offset: float | list[float],
|
239
|
+
domain: tuple[float, float],
|
240
|
+
image: tuple[float, float],
|
241
|
+
rescaling_factor: float = 1,
|
242
|
+
breakpoints: list[float] | None = None,
|
243
|
+
label: str = "F",
|
244
|
+
) -> None:
|
245
|
+
r"""
|
246
|
+
Args:
|
247
|
+
num_state_qubits: The number of qubits used to encode the variable :math:`x`.
|
248
|
+
slope: The slope of the linear function. Can be a list of slopes if it is a piecewise
|
249
|
+
linear function.
|
250
|
+
offset: The offset of the linear function. Can be a list of offsets if it is a piecewise
|
251
|
+
linear function.
|
252
|
+
domain: The domain of the function as tuple :math:`(x_\min{}, x_\max{})`.
|
253
|
+
image: The image of the function as tuple :math:`(f_\min{}, f_\max{})`.
|
254
|
+
rescaling_factor: The rescaling factor to adjust the accuracy in the Taylor
|
255
|
+
approximation.
|
256
|
+
breakpoints: The breakpoints if the function is piecewise linear. If None, the function
|
257
|
+
is not piecewise.
|
258
|
+
label: A label for the gate.
|
259
|
+
"""
|
260
|
+
if not hasattr(slope, "__len__"):
|
261
|
+
slope = [slope]
|
262
|
+
if not hasattr(offset, "__len__"):
|
263
|
+
offset = [offset]
|
264
|
+
|
265
|
+
# ensure that the breakpoints include the first point of the domain
|
266
|
+
if breakpoints is None:
|
267
|
+
breakpoints = [domain[0]]
|
268
|
+
else:
|
269
|
+
if not np.isclose(breakpoints[0], domain[0]):
|
270
|
+
breakpoints = [domain[0]] + breakpoints
|
271
|
+
|
272
|
+
_check_sizes_match(slope, offset, breakpoints)
|
273
|
+
_check_sorted_and_in_range(breakpoints, domain)
|
274
|
+
|
275
|
+
self.slope = slope
|
276
|
+
self.offset = offset
|
277
|
+
self.domain = domain
|
278
|
+
self.image = image
|
279
|
+
self.rescaling_factor = rescaling_factor
|
280
|
+
self.breakpoints = breakpoints
|
281
|
+
|
282
|
+
num_compare = int(len(breakpoints) > 1)
|
283
|
+
super().__init__("LinFunction", num_state_qubits + num_compare + 1, [], label=label)
|
284
|
+
|
285
|
+
def _define(self):
|
286
|
+
num_compare = int(len(self.breakpoints) > 1)
|
287
|
+
num_state_qubits = self.num_qubits - num_compare - 1
|
288
|
+
|
289
|
+
# do rescaling
|
290
|
+
a, b = self.domain
|
291
|
+
c, d = self.image
|
292
|
+
|
293
|
+
mapped_breakpoints = []
|
294
|
+
mapped_slope = []
|
295
|
+
mapped_offset = []
|
296
|
+
for i, point in enumerate(self.breakpoints):
|
297
|
+
mapped_breakpoint = (point - a) / (b - a) * (2**num_state_qubits - 1)
|
298
|
+
mapped_breakpoints += [mapped_breakpoint]
|
299
|
+
|
300
|
+
# factor (upper - lower) / (2^n - 1) is for the scaling of x to [l,u]
|
301
|
+
# note that the +l for mapping to [l,u] is already included in
|
302
|
+
# the offsets given as parameters
|
303
|
+
mapped_slope += [self.slope[i] * (b - a) / (2**num_state_qubits - 1)]
|
304
|
+
mapped_offset += [self.offset[i]]
|
305
|
+
|
306
|
+
# approximate linear behavior by scaling and contracting around pi/4
|
307
|
+
slope_angles = np.zeros(len(self.breakpoints))
|
308
|
+
offset_angles = np.pi / 4 * (1 - self.rescaling_factor) * np.ones_like(slope_angles)
|
309
|
+
for i, (slope_i, offset_i) in enumerate(zip(mapped_slope, mapped_offset)):
|
310
|
+
slope_angles[i] = np.pi * self.rescaling_factor * slope_i / 2 / (d - c)
|
311
|
+
offset_angles[i] += np.pi * self.rescaling_factor * (offset_i - c) / 2 / (d - c)
|
312
|
+
|
313
|
+
# use PWLPauliRotations to implement the function
|
314
|
+
pwl_pauli_rotation = PiecewiseLinearPauliRotationsGate(
|
315
|
+
num_state_qubits, mapped_breakpoints, 2 * slope_angles, 2 * offset_angles
|
316
|
+
)
|
317
|
+
|
318
|
+
self.definition = QuantumCircuit(pwl_pauli_rotation.num_qubits)
|
319
|
+
self.definition.append(pwl_pauli_rotation, self.definition.qubits)
|
320
|
+
|
321
|
+
def post_processing(self, scaled_value: float) -> float:
|
322
|
+
r"""Map the function value of the approximated :math:`\hat{f}` to :math:`f`.
|
323
|
+
|
324
|
+
Args:
|
325
|
+
scaled_value: A function value from the Taylor expansion of :math:`\hat{f}(x)`.
|
326
|
+
|
327
|
+
Returns:
|
328
|
+
The ``scaled_value`` mapped back to the domain of :math:`f`, by first inverting
|
329
|
+
the transformation used for the Taylor approximation and then mapping back from
|
330
|
+
:math:`[0, 1]` to the original domain.
|
331
|
+
"""
|
332
|
+
# revert the mapping applied in the Taylor approximation
|
333
|
+
value = scaled_value - 1 / 2 + np.pi / 4 * self.rescaling_factor
|
334
|
+
value *= 2 / np.pi / self.rescaling_factor
|
335
|
+
|
336
|
+
# map the value from [0, 1] back to the original domain
|
337
|
+
value *= self.image[1] - self.image[0]
|
338
|
+
value += self.image[0]
|
339
|
+
|
340
|
+
return value
|
341
|
+
|
342
|
+
|
176
343
|
def _check_sorted_and_in_range(breakpoints, domain):
|
177
344
|
if breakpoints is None:
|
178
345
|
return
|
@@ -13,9 +13,10 @@
|
|
13
13
|
|
14
14
|
"""Linearly-controlled X, Y or Z rotation."""
|
15
15
|
|
16
|
+
from __future__ import annotations
|
16
17
|
from typing import Optional
|
17
18
|
|
18
|
-
from qiskit.circuit import QuantumRegister, QuantumCircuit
|
19
|
+
from qiskit.circuit import QuantumRegister, QuantumCircuit, Gate
|
19
20
|
from qiskit.circuit.exceptions import CircuitError
|
20
21
|
|
21
22
|
from .functional_pauli_rotations import FunctionalPauliRotations
|
@@ -164,12 +165,65 @@ class LinearPauliRotations(FunctionalPauliRotations):
|
|
164
165
|
return
|
165
166
|
|
166
167
|
super()._build()
|
168
|
+
gate = LinearPauliRotationsGate(self.num_state_qubits, self.slope, self.offset, self.basis)
|
169
|
+
self.append(gate, self.qubits)
|
167
170
|
|
168
|
-
|
171
|
+
|
172
|
+
class LinearPauliRotationsGate(Gate):
|
173
|
+
r"""Linearly-controlled X, Y or Z rotation.
|
174
|
+
|
175
|
+
For a register of state qubits :math:`|x\rangle`, a target qubit :math:`|0\rangle` and the
|
176
|
+
basis ``'Y'`` this circuit acts as:
|
177
|
+
|
178
|
+
.. parsed-literal::
|
179
|
+
|
180
|
+
q_0: ─────────────────────────■───────── ... ──────────────────────
|
181
|
+
│
|
182
|
+
.
|
183
|
+
│
|
184
|
+
q_(n-1): ─────────────────────────┼───────── ... ───────────■──────────
|
185
|
+
┌────────────┐ ┌───────┴───────┐ ┌─────────┴─────────┐
|
186
|
+
q_n: ─┤ RY(offset) ├──┤ RY(2^0 slope) ├ ... ┤ RY(2^(n-1) slope) ├
|
187
|
+
└────────────┘ └───────────────┘ └───────────────────┘
|
188
|
+
|
189
|
+
This can for example be used to approximate linear functions, with :math:`a =` ``slope``:math:`/2`
|
190
|
+
and :math:`b =` ``offset``:math:`/2` and the basis ``'Y'``:
|
191
|
+
|
192
|
+
.. math::
|
193
|
+
|
194
|
+
|x\rangle |0\rangle \mapsto \cos(ax + b)|x\rangle|0\rangle + \sin(ax + b)|x\rangle |1\rangle
|
195
|
+
|
196
|
+
Since for small arguments :math:`\sin(x) \approx x` this operator can be used to approximate
|
197
|
+
linear functions.
|
198
|
+
"""
|
199
|
+
|
200
|
+
def __init__(
|
201
|
+
self,
|
202
|
+
num_state_qubits: int,
|
203
|
+
slope: float = 1,
|
204
|
+
offset: float = 0,
|
205
|
+
basis: str = "Y",
|
206
|
+
label: str | None = None,
|
207
|
+
) -> None:
|
208
|
+
r"""
|
209
|
+
Args:
|
210
|
+
num_state_qubits: The number of qubits representing the state :math:`|x\rangle`.
|
211
|
+
slope: The slope of the controlled rotation.
|
212
|
+
offset: The offset of the controlled rotation.
|
213
|
+
basis: The type of Pauli rotation ('X', 'Y', 'Z').
|
214
|
+
label: The label of the gate.
|
215
|
+
"""
|
216
|
+
super().__init__("LinPauliRot", num_state_qubits + 1, [], label=label)
|
217
|
+
self.slope = slope
|
218
|
+
self.offset = offset
|
219
|
+
self.basis = basis.lower()
|
220
|
+
|
221
|
+
def _define(self):
|
222
|
+
circuit = QuantumCircuit(self.num_qubits, name=self.name)
|
169
223
|
|
170
224
|
# build the circuit
|
171
|
-
qr_state =
|
172
|
-
qr_target =
|
225
|
+
qr_state = circuit.qubits[: self.num_qubits - 1]
|
226
|
+
qr_target = circuit.qubits[-1]
|
173
227
|
|
174
228
|
if self.basis == "x":
|
175
229
|
circuit.rx(self.offset, qr_target)
|
@@ -186,4 +240,4 @@ class LinearPauliRotations(FunctionalPauliRotations):
|
|
186
240
|
else: # 'Z'
|
187
241
|
circuit.crz(self.slope * pow(2, i), q_i, qr_target)
|
188
242
|
|
189
|
-
self.
|
243
|
+
self.definition = circuit
|
@@ -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)
|