qiskit 1.1.2__cp38-abi3-win32.whl → 1.2.0rc1__cp38-abi3-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/__init__.py +27 -24
- qiskit/_accelerate.pyd +0 -0
- qiskit/_numpy_compat.py +1 -1
- qiskit/assembler/assemble_circuits.py +107 -64
- qiskit/assembler/assemble_schedules.py +5 -12
- qiskit/assembler/disassemble.py +10 -1
- qiskit/circuit/__init__.py +1 -1
- qiskit/circuit/_classical_resource_map.py +5 -5
- qiskit/circuit/_utils.py +0 -13
- qiskit/circuit/add_control.py +1 -1
- qiskit/circuit/annotated_operation.py +23 -1
- qiskit/circuit/classical/expr/expr.py +4 -4
- qiskit/circuit/classical/expr/visitors.py +1 -1
- qiskit/circuit/classical/types/__init__.py +1 -1
- qiskit/circuit/classical/types/types.py +2 -2
- qiskit/circuit/classicalfunction/boolean_expression.py +1 -1
- qiskit/circuit/classicalfunction/classical_function_visitor.py +5 -5
- qiskit/circuit/classicalfunction/utils.py +1 -1
- qiskit/circuit/classicalregister.py +1 -1
- qiskit/circuit/commutation_checker.py +83 -35
- qiskit/circuit/controlflow/_builder_utils.py +1 -1
- qiskit/circuit/controlflow/builder.py +10 -6
- qiskit/circuit/controlflow/if_else.py +2 -2
- qiskit/circuit/controlflow/switch_case.py +1 -1
- qiskit/circuit/delay.py +1 -1
- qiskit/circuit/duration.py +2 -2
- qiskit/circuit/equivalence.py +5 -7
- qiskit/circuit/gate.py +11 -8
- qiskit/circuit/instruction.py +31 -13
- qiskit/circuit/instructionset.py +2 -5
- qiskit/circuit/library/__init__.py +2 -1
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +1 -1
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +3 -3
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +1 -1
- qiskit/circuit/library/basis_change/__init__.py +1 -1
- qiskit/circuit/library/basis_change/qft.py +40 -6
- qiskit/circuit/library/blueprintcircuit.py +3 -5
- qiskit/circuit/library/data_preparation/__init__.py +9 -2
- qiskit/circuit/library/data_preparation/initializer.py +8 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +98 -178
- qiskit/circuit/library/generalized_gates/isometry.py +8 -8
- qiskit/circuit/library/generalized_gates/linear_function.py +3 -2
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +4 -4
- qiskit/circuit/library/generalized_gates/permutation.py +8 -9
- qiskit/circuit/library/generalized_gates/uc.py +3 -3
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +2 -2
- qiskit/circuit/library/generalized_gates/unitary.py +13 -11
- qiskit/circuit/library/graph_state.py +1 -1
- qiskit/circuit/library/hamiltonian_gate.py +1 -2
- qiskit/circuit/library/hidden_linear_function.py +1 -1
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +3 -2
- qiskit/circuit/library/n_local/n_local.py +4 -5
- qiskit/circuit/library/n_local/pauli_two_design.py +1 -1
- qiskit/circuit/library/n_local/qaoa_ansatz.py +6 -8
- qiskit/circuit/library/n_local/two_local.py +1 -1
- qiskit/circuit/library/overlap.py +11 -5
- qiskit/circuit/library/pauli_evolution.py +7 -3
- qiskit/circuit/library/standard_gates/dcx.py +3 -0
- qiskit/circuit/library/standard_gates/ecr.py +3 -0
- qiskit/circuit/library/standard_gates/global_phase.py +3 -0
- qiskit/circuit/library/standard_gates/h.py +13 -5
- qiskit/circuit/library/standard_gates/i.py +3 -0
- qiskit/circuit/library/standard_gates/iswap.py +3 -0
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +19 -10
- qiskit/circuit/library/standard_gates/p.py +14 -9
- qiskit/circuit/library/standard_gates/r.py +3 -0
- qiskit/circuit/library/standard_gates/rx.py +21 -6
- qiskit/circuit/library/standard_gates/rxx.py +40 -1
- qiskit/circuit/library/standard_gates/ry.py +21 -6
- qiskit/circuit/library/standard_gates/ryy.py +40 -1
- qiskit/circuit/library/standard_gates/rz.py +22 -6
- qiskit/circuit/library/standard_gates/rzx.py +40 -1
- qiskit/circuit/library/standard_gates/rzz.py +41 -2
- qiskit/circuit/library/standard_gates/s.py +77 -0
- qiskit/circuit/library/standard_gates/swap.py +12 -5
- qiskit/circuit/library/standard_gates/sx.py +14 -5
- qiskit/circuit/library/standard_gates/t.py +5 -0
- qiskit/circuit/library/standard_gates/u.py +22 -7
- qiskit/circuit/library/standard_gates/u1.py +8 -3
- qiskit/circuit/library/standard_gates/u2.py +3 -0
- qiskit/circuit/library/standard_gates/u3.py +22 -7
- qiskit/circuit/library/standard_gates/x.py +156 -92
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +40 -1
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +52 -11
- qiskit/circuit/library/standard_gates/y.py +6 -1
- qiskit/circuit/library/standard_gates/z.py +8 -1
- qiskit/circuit/operation.py +1 -1
- qiskit/circuit/parameter.py +9 -10
- qiskit/circuit/parameterexpression.py +16 -13
- qiskit/circuit/parametertable.py +1 -190
- qiskit/circuit/parametervector.py +1 -1
- qiskit/circuit/quantumcircuit.py +392 -384
- qiskit/circuit/quantumcircuitdata.py +3 -5
- qiskit/circuit/quantumregister.py +1 -1
- qiskit/circuit/random/__init__.py +1 -1
- qiskit/circuit/random/utils.py +175 -26
- qiskit/circuit/register.py +5 -7
- qiskit/circuit/singleton.py +3 -3
- qiskit/circuit/tools/pi_check.py +4 -4
- qiskit/compiler/assembler.py +95 -24
- qiskit/compiler/scheduler.py +2 -2
- qiskit/compiler/transpiler.py +41 -127
- qiskit/converters/circuit_to_dag.py +4 -6
- qiskit/converters/circuit_to_gate.py +4 -8
- qiskit/converters/circuit_to_instruction.py +5 -17
- qiskit/converters/dag_to_circuit.py +2 -6
- qiskit/dagcircuit/collect_blocks.py +2 -2
- qiskit/dagcircuit/dagcircuit.py +190 -187
- qiskit/dagcircuit/dagdependency.py +4 -4
- qiskit/dagcircuit/dagdependency_v2.py +4 -4
- qiskit/dagcircuit/dagdepnode.py +1 -1
- qiskit/dagcircuit/dagnode.py +66 -157
- qiskit/passmanager/flow_controllers.py +1 -1
- qiskit/passmanager/passmanager.py +3 -3
- qiskit/primitives/__init__.py +1 -5
- qiskit/primitives/backend_estimator.py +25 -15
- qiskit/primitives/backend_estimator_v2.py +31 -7
- qiskit/primitives/backend_sampler.py +21 -12
- qiskit/primitives/backend_sampler_v2.py +12 -3
- qiskit/primitives/base/base_estimator.py +31 -4
- qiskit/primitives/base/base_primitive.py +2 -2
- qiskit/primitives/base/base_result.py +2 -2
- qiskit/primitives/base/base_sampler.py +26 -2
- qiskit/primitives/base/estimator_result.py +2 -2
- qiskit/primitives/base/sampler_result.py +2 -2
- qiskit/primitives/containers/__init__.py +0 -1
- qiskit/primitives/containers/bindings_array.py +2 -2
- qiskit/primitives/containers/bit_array.py +108 -10
- qiskit/primitives/containers/shape.py +3 -3
- qiskit/primitives/estimator.py +9 -2
- qiskit/primitives/primitive_job.py +1 -1
- qiskit/primitives/sampler.py +10 -3
- qiskit/primitives/statevector_estimator.py +5 -3
- qiskit/primitives/statevector_sampler.py +11 -5
- qiskit/primitives/utils.py +16 -0
- qiskit/providers/backend.py +15 -6
- qiskit/providers/backend_compat.py +7 -4
- qiskit/providers/basic_provider/basic_provider_tools.py +1 -1
- qiskit/providers/basic_provider/basic_simulator.py +32 -24
- qiskit/providers/fake_provider/fake_backend.py +10 -3
- qiskit/providers/fake_provider/fake_openpulse_2q.py +154 -146
- qiskit/providers/fake_provider/fake_openpulse_3q.py +226 -217
- qiskit/providers/fake_provider/fake_qasm_backend.py +5 -1
- qiskit/providers/fake_provider/generic_backend_v2.py +80 -50
- qiskit/providers/models/__init__.py +11 -0
- qiskit/providers/models/backendconfiguration.py +50 -4
- qiskit/providers/models/backendproperties.py +13 -2
- qiskit/providers/models/pulsedefaults.py +10 -11
- qiskit/providers/options.py +13 -13
- qiskit/providers/providerutils.py +3 -1
- qiskit/pulse/configuration.py +8 -12
- qiskit/pulse/instruction_schedule_map.py +3 -5
- qiskit/pulse/instructions/acquire.py +7 -8
- qiskit/pulse/instructions/instruction.py +2 -3
- qiskit/pulse/library/samplers/decorators.py +5 -9
- qiskit/pulse/library/symbolic_pulses.py +4 -7
- qiskit/pulse/library/waveform.py +2 -5
- qiskit/pulse/macros.py +11 -6
- qiskit/pulse/parser.py +8 -10
- qiskit/pulse/schedule.py +9 -17
- qiskit/pulse/transforms/alignments.py +1 -3
- qiskit/pulse/utils.py +1 -2
- qiskit/qasm/libs/stdgates.inc +35 -28
- qiskit/qasm2/__init__.py +7 -7
- qiskit/qasm2/export.py +5 -9
- qiskit/qasm2/parse.py +1 -1
- qiskit/qasm3/ast.py +9 -25
- qiskit/qasm3/exporter.py +578 -481
- qiskit/qasm3/printer.py +7 -16
- qiskit/qobj/common.py +10 -0
- qiskit/qobj/converters/lo_config.py +9 -0
- qiskit/qobj/converters/pulse_instruction.py +13 -6
- qiskit/qobj/pulse_qobj.py +69 -15
- qiskit/qobj/qasm_qobj.py +72 -20
- qiskit/qobj/utils.py +9 -0
- qiskit/qpy/binary_io/circuits.py +8 -5
- qiskit/qpy/binary_io/schedules.py +1 -1
- qiskit/qpy/binary_io/value.py +3 -3
- qiskit/qpy/interface.py +3 -2
- qiskit/qpy/type_keys.py +2 -2
- qiskit/quantum_info/operators/channel/quantum_channel.py +3 -6
- qiskit/quantum_info/operators/channel/superop.py +2 -2
- qiskit/quantum_info/operators/channel/transformations.py +1 -1
- qiskit/quantum_info/operators/dihedral/dihedral.py +3 -4
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +1 -3
- qiskit/quantum_info/operators/dihedral/random.py +6 -3
- qiskit/quantum_info/operators/measures.py +2 -2
- qiskit/quantum_info/operators/op_shape.py +12 -20
- qiskit/quantum_info/operators/operator.py +14 -21
- qiskit/quantum_info/operators/predicates.py +1 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +7 -11
- qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
- qiskit/quantum_info/operators/symplectic/pauli.py +3 -3
- qiskit/quantum_info/operators/symplectic/pauli_list.py +9 -10
- qiskit/quantum_info/operators/symplectic/random.py +1 -1
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +14 -16
- qiskit/quantum_info/quaternion.py +1 -1
- qiskit/quantum_info/states/densitymatrix.py +5 -8
- qiskit/quantum_info/states/stabilizerstate.py +128 -37
- qiskit/quantum_info/states/statevector.py +4 -8
- qiskit/result/counts.py +2 -2
- qiskit/result/mitigation/correlated_readout_mitigator.py +2 -2
- qiskit/result/mitigation/local_readout_mitigator.py +2 -2
- qiskit/result/mitigation/utils.py +1 -3
- qiskit/result/models.py +17 -16
- qiskit/result/result.py +15 -20
- qiskit/scheduler/lowering.py +2 -2
- qiskit/synthesis/__init__.py +2 -1
- qiskit/synthesis/clifford/__init__.py +1 -1
- qiskit/synthesis/clifford/clifford_decompose_ag.py +2 -2
- qiskit/synthesis/clifford/clifford_decompose_bm.py +10 -240
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +9 -303
- qiskit/synthesis/clifford/clifford_decompose_layers.py +25 -23
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +1 -1
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +1 -1
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +1 -1
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +2 -2
- qiskit/synthesis/evolution/evolution_synthesis.py +4 -2
- qiskit/synthesis/evolution/lie_trotter.py +46 -19
- qiskit/synthesis/evolution/product_formula.py +111 -55
- qiskit/synthesis/evolution/qdrift.py +40 -10
- qiskit/synthesis/evolution/suzuki_trotter.py +43 -33
- qiskit/synthesis/linear/__init__.py +1 -0
- qiskit/synthesis/linear/cnot_synth.py +22 -96
- qiskit/synthesis/linear/linear_depth_lnn.py +8 -8
- qiskit/synthesis/linear/linear_matrix_utils.py +13 -161
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +1 -1
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +3 -3
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +1 -1
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +29 -29
- qiskit/synthesis/permutation/permutation_full.py +5 -29
- qiskit/synthesis/permutation/permutation_lnn.py +2 -24
- qiskit/synthesis/permutation/permutation_utils.py +2 -59
- qiskit/synthesis/qft/__init__.py +1 -0
- qiskit/synthesis/qft/qft_decompose_full.py +79 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +17 -9
- qiskit/synthesis/stabilizer/stabilizer_circuit.py +6 -6
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -2
- qiskit/synthesis/two_qubit/local_invariance.py +8 -38
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +48 -129
- qiskit/synthesis/unitary/aqc/cnot_structures.py +1 -1
- qiskit/synthesis/unitary/qsd.py +5 -3
- qiskit/transpiler/__init__.py +1 -0
- qiskit/transpiler/basepasses.py +1 -1
- qiskit/transpiler/coupling.py +3 -3
- qiskit/transpiler/instruction_durations.py +1 -2
- qiskit/transpiler/layout.py +3 -3
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +82 -63
- qiskit/transpiler/passes/basis/translate_parameterized.py +3 -5
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +10 -10
- qiskit/transpiler/passes/calibration/rx_builder.py +3 -3
- qiskit/transpiler/passes/calibration/rzx_builder.py +3 -3
- qiskit/transpiler/passes/layout/apply_layout.py +13 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +10 -8
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +4 -1
- qiskit/transpiler/passes/layout/set_layout.py +2 -2
- qiskit/transpiler/passes/layout/vf2_layout.py +1 -1
- qiskit/transpiler/passes/layout/vf2_utils.py +3 -3
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
- qiskit/transpiler/passes/optimization/commutation_analysis.py +7 -10
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +35 -19
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +11 -8
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +6 -6
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +64 -41
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +83 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +1 -1
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +2 -2
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -1
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
- qiskit/transpiler/passes/routing/layout_transformation.py +2 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +35 -26
- qiskit/transpiler/passes/routing/star_prerouting.py +80 -105
- qiskit/transpiler/passes/routing/stochastic_swap.py +1 -3
- qiskit/transpiler/passes/scheduling/alap.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +1 -1
- qiskit/transpiler/passes/scheduling/asap.py +1 -2
- qiskit/transpiler/passes/scheduling/base_scheduler.py +5 -5
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +3 -3
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +11 -11
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +7 -6
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -3
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +211 -36
- qiskit/transpiler/passes/synthesis/plugin.py +2 -2
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +80 -40
- qiskit/transpiler/passes/utils/__init__.py +0 -1
- qiskit/transpiler/passes/utils/check_gate_direction.py +4 -4
- qiskit/transpiler/passes/utils/check_map.py +3 -6
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +3 -4
- qiskit/transpiler/passes/utils/error.py +2 -2
- qiskit/transpiler/passes/utils/fixed_point.py +3 -3
- qiskit/transpiler/passes/utils/gate_direction.py +1 -1
- qiskit/transpiler/passes/utils/gates_basis.py +1 -2
- qiskit/transpiler/passmanager.py +7 -6
- qiskit/transpiler/preset_passmanagers/__init__.py +4 -228
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +117 -18
- qiskit/transpiler/preset_passmanagers/common.py +3 -6
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +518 -0
- qiskit/transpiler/preset_passmanagers/level0.py +1 -1
- qiskit/transpiler/target.py +27 -8
- qiskit/user_config.py +29 -6
- qiskit/utils/classtools.py +3 -3
- qiskit/utils/deprecation.py +3 -2
- qiskit/utils/lazy_tester.py +2 -2
- qiskit/utils/optionals.py +8 -8
- qiskit/visualization/bloch.py +19 -67
- qiskit/visualization/circuit/_utils.py +34 -10
- qiskit/visualization/circuit/circuit_visualization.py +23 -16
- qiskit/visualization/circuit/latex.py +29 -27
- qiskit/visualization/circuit/matplotlib.py +4 -2
- qiskit/visualization/circuit/qcstyle.py +2 -2
- qiskit/visualization/circuit/text.py +9 -15
- qiskit/visualization/dag_visualization.py +5 -12
- qiskit/visualization/pulse_v2/core.py +1 -1
- qiskit/visualization/pulse_v2/events.py +1 -1
- qiskit/visualization/pulse_v2/generators/frame.py +3 -4
- qiskit/visualization/pulse_v2/generators/waveform.py +5 -9
- qiskit/visualization/pulse_v2/layouts.py +1 -5
- qiskit/visualization/pulse_v2/plotters/matplotlib.py +1 -2
- qiskit/visualization/state_visualization.py +5 -6
- qiskit/visualization/timeline/plotters/matplotlib.py +1 -2
- qiskit/visualization/transition_visualization.py +7 -2
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/METADATA +26 -26
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/RECORD +340 -338
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/WHEEL +1 -1
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/entry_points.txt +3 -0
- qiskit/transpiler/passes/utils/block_to_matrix.py +0 -47
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.1.2.dist-info → qiskit-1.2.0rc1.dist-info}/top_level.txt +0 -0
@@ -202,7 +202,7 @@ class PiecewiseLinearPauliRotations(FunctionalPauliRotations):
|
|
202
202
|
if raise_on_failure:
|
203
203
|
raise CircuitError(
|
204
204
|
"Not enough qubits in the circuit, need at least "
|
205
|
-
"{
|
205
|
+
f"{self.num_state_qubits + 1}."
|
206
206
|
)
|
207
207
|
|
208
208
|
if len(self.breakpoints) != len(self.slopes) or len(self.breakpoints) != len(self.offsets):
|
@@ -218,8 +218,8 @@ class PiecewisePolynomialPauliRotations(FunctionalPauliRotations):
|
|
218
218
|
"""
|
219
219
|
|
220
220
|
y = 0
|
221
|
-
for i in
|
222
|
-
y = y + (x >=
|
221
|
+
for i, breakpt in enumerate(self.breakpoints):
|
222
|
+
y = y + (x >= breakpt) * (np.poly1d(self.mapped_coeffs[i][::-1])(x))
|
223
223
|
|
224
224
|
return y
|
225
225
|
|
@@ -237,7 +237,7 @@ class PiecewisePolynomialPauliRotations(FunctionalPauliRotations):
|
|
237
237
|
if raise_on_failure:
|
238
238
|
raise CircuitError(
|
239
239
|
"Not enough qubits in the circuit, need at least "
|
240
|
-
"{
|
240
|
+
f"{self.num_state_qubits + 1}."
|
241
241
|
)
|
242
242
|
|
243
243
|
if len(self.breakpoints) != len(self.coeffs) + 1:
|
@@ -248,7 +248,7 @@ class PolynomialPauliRotations(FunctionalPauliRotations):
|
|
248
248
|
if raise_on_failure:
|
249
249
|
raise CircuitError(
|
250
250
|
"Not enough qubits in the circuit, need at least "
|
251
|
-
"{
|
251
|
+
f"{self.num_state_qubits + 1}."
|
252
252
|
)
|
253
253
|
|
254
254
|
return valid
|
@@ -10,14 +10,13 @@
|
|
10
10
|
# copyright notice, and modified files need to carry a notice indicating
|
11
11
|
# that they have been altered from the originals.
|
12
12
|
|
13
|
-
"""Quantum Fourier Transform
|
13
|
+
"""Define a Quantum Fourier Transform circuit (QFT) and a native gate (QFTGate)."""
|
14
14
|
|
15
|
-
from
|
15
|
+
from __future__ import annotations
|
16
16
|
import warnings
|
17
17
|
import numpy as np
|
18
18
|
|
19
|
-
from qiskit.circuit import QuantumCircuit, QuantumRegister, CircuitInstruction
|
20
|
-
|
19
|
+
from qiskit.circuit.quantumcircuit import QuantumCircuit, QuantumRegister, CircuitInstruction, Gate
|
21
20
|
from ..blueprintcircuit import BlueprintCircuit
|
22
21
|
|
23
22
|
|
@@ -75,12 +74,12 @@ class QFT(BlueprintCircuit):
|
|
75
74
|
|
76
75
|
def __init__(
|
77
76
|
self,
|
78
|
-
num_qubits:
|
77
|
+
num_qubits: int | None = None,
|
79
78
|
approximation_degree: int = 0,
|
80
79
|
do_swaps: bool = True,
|
81
80
|
inverse: bool = False,
|
82
81
|
insert_barriers: bool = False,
|
83
|
-
name:
|
82
|
+
name: str | None = None,
|
84
83
|
) -> None:
|
85
84
|
"""Construct a new QFT circuit.
|
86
85
|
|
@@ -293,3 +292,38 @@ class QFT(BlueprintCircuit):
|
|
293
292
|
|
294
293
|
wrapped = circuit.to_instruction() if self.insert_barriers else circuit.to_gate()
|
295
294
|
self.compose(wrapped, qubits=self.qubits, inplace=True)
|
295
|
+
|
296
|
+
|
297
|
+
class QFTGate(Gate):
|
298
|
+
r"""Quantum Fourier Transform Gate.
|
299
|
+
|
300
|
+
The Quantum Fourier Transform (QFT) on :math:`n` qubits is the operation
|
301
|
+
|
302
|
+
.. math::
|
303
|
+
|
304
|
+
|j\rangle \mapsto \frac{1}{2^{n/2}} \sum_{k=0}^{2^n - 1} e^{2\pi ijk / 2^n} |k\rangle
|
305
|
+
|
306
|
+
"""
|
307
|
+
|
308
|
+
def __init__(
|
309
|
+
self,
|
310
|
+
num_qubits: int,
|
311
|
+
):
|
312
|
+
"""
|
313
|
+
Args:
|
314
|
+
num_qubits: The number of qubits on which the QFT acts.
|
315
|
+
"""
|
316
|
+
super().__init__(name="qft", num_qubits=num_qubits, params=[])
|
317
|
+
|
318
|
+
def __array__(self, dtype=complex):
|
319
|
+
"""Return a numpy array for the QFTGate."""
|
320
|
+
n = self.num_qubits
|
321
|
+
nums = np.arange(2**n)
|
322
|
+
outer = np.outer(nums, nums)
|
323
|
+
return np.exp(2j * np.pi * outer * (0.5**n), dtype=dtype) * (0.5 ** (n / 2))
|
324
|
+
|
325
|
+
def _define(self):
|
326
|
+
"""Provide a specific decomposition of the QFTGate into a quantum circuit."""
|
327
|
+
from qiskit.synthesis.qft import synth_qft_full
|
328
|
+
|
329
|
+
self.definition = synth_qft_full(num_qubits=self.num_qubits)
|
@@ -17,7 +17,7 @@ from abc import ABC, abstractmethod
|
|
17
17
|
|
18
18
|
from qiskit._accelerate.circuit import CircuitData
|
19
19
|
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
|
20
|
-
from qiskit.circuit.parametertable import
|
20
|
+
from qiskit.circuit.parametertable import ParameterView
|
21
21
|
|
22
22
|
|
23
23
|
class BlueprintCircuit(QuantumCircuit, ABC):
|
@@ -68,7 +68,6 @@ class BlueprintCircuit(QuantumCircuit, ABC):
|
|
68
68
|
def _invalidate(self) -> None:
|
69
69
|
"""Invalidate the current circuit build."""
|
70
70
|
self._data = CircuitData(self._data.qubits, self._data.clbits)
|
71
|
-
self._parameter_table = ParameterTable()
|
72
71
|
self.global_phase = 0
|
73
72
|
self._is_built = False
|
74
73
|
|
@@ -88,7 +87,6 @@ class BlueprintCircuit(QuantumCircuit, ABC):
|
|
88
87
|
self._ancillas = []
|
89
88
|
self._qubit_indices = {}
|
90
89
|
self._data = CircuitData(clbits=self._data.clbits)
|
91
|
-
self._parameter_table = ParameterTable()
|
92
90
|
self.global_phase = 0
|
93
91
|
self._is_built = False
|
94
92
|
|
@@ -122,10 +120,10 @@ class BlueprintCircuit(QuantumCircuit, ABC):
|
|
122
120
|
self._build()
|
123
121
|
return super().parameters
|
124
122
|
|
125
|
-
def _append(self, instruction, _qargs=None, _cargs=None):
|
123
|
+
def _append(self, instruction, _qargs=None, _cargs=None, *, _standard_gate=False):
|
126
124
|
if not self._is_built:
|
127
125
|
self._build()
|
128
|
-
return super()._append(instruction, _qargs, _cargs)
|
126
|
+
return super()._append(instruction, _qargs, _cargs, _standard_gate=_standard_gate)
|
129
127
|
|
130
128
|
def compose(
|
131
129
|
self,
|
@@ -41,7 +41,14 @@ of the complete initial data.
|
|
41
41
|
from .pauli_feature_map import PauliFeatureMap
|
42
42
|
from .z_feature_map import ZFeatureMap
|
43
43
|
from .zz_feature_map import ZZFeatureMap
|
44
|
-
from .state_preparation import StatePreparation
|
44
|
+
from .state_preparation import StatePreparation, UniformSuperpositionGate
|
45
45
|
from .initializer import Initialize
|
46
46
|
|
47
|
-
__all__ = [
|
47
|
+
__all__ = [
|
48
|
+
"PauliFeatureMap",
|
49
|
+
"ZFeatureMap",
|
50
|
+
"ZZFeatureMap",
|
51
|
+
"StatePreparation",
|
52
|
+
"UniformSuperpositionGate",
|
53
|
+
"Initialize",
|
54
|
+
]
|
@@ -36,6 +36,14 @@ class Initialize(Instruction):
|
|
36
36
|
the :class:`~.library.StatePreparation` class.
|
37
37
|
Note that ``Initialize`` is an :class:`~.circuit.Instruction` and not a :class:`.Gate` since it
|
38
38
|
contains a reset instruction, which is not unitary.
|
39
|
+
|
40
|
+
The initial state is prepared based on the :class:`~.library.Isometry` synthesis described in [1].
|
41
|
+
|
42
|
+
References:
|
43
|
+
1. Iten et al., Quantum circuits for isometries (2016).
|
44
|
+
`Phys. Rev. A 93, 032318
|
45
|
+
<https://journals.aps.org/pra/abstract/10.1103/PhysRevA.93.032318>`__.
|
46
|
+
|
39
47
|
"""
|
40
48
|
|
41
49
|
def __init__(
|
@@ -11,7 +11,6 @@
|
|
11
11
|
# that they have been altered from the originals.
|
12
12
|
"""Prepare a quantum state from the state where all qubits are 0."""
|
13
13
|
|
14
|
-
import cmath
|
15
14
|
from typing import Union, Optional
|
16
15
|
|
17
16
|
import math
|
@@ -21,13 +20,14 @@ from qiskit.exceptions import QiskitError
|
|
21
20
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
22
21
|
from qiskit.circuit.quantumregister import QuantumRegister
|
23
22
|
from qiskit.circuit.gate import Gate
|
24
|
-
from qiskit.circuit.library.standard_gates.x import
|
23
|
+
from qiskit.circuit.library.standard_gates.x import XGate
|
25
24
|
from qiskit.circuit.library.standard_gates.h import HGate
|
26
25
|
from qiskit.circuit.library.standard_gates.s import SGate, SdgGate
|
27
|
-
from qiskit.circuit.library.
|
28
|
-
from qiskit.circuit.library.standard_gates.rz import RZGate
|
26
|
+
from qiskit.circuit.library.generalized_gates import Isometry
|
29
27
|
from qiskit.circuit.exceptions import CircuitError
|
30
|
-
from qiskit.quantum_info.states.statevector import
|
28
|
+
from qiskit.quantum_info.states.statevector import (
|
29
|
+
Statevector,
|
30
|
+
) # pylint: disable=cyclic-import
|
31
31
|
|
32
32
|
_EPS = 1e-10 # global variable used to chop very small numbers to zero
|
33
33
|
|
@@ -71,13 +71,13 @@ class StatePreparation(Gate):
|
|
71
71
|
Raises:
|
72
72
|
QiskitError: ``num_qubits`` parameter used when ``params`` is not an integer
|
73
73
|
|
74
|
-
When a Statevector argument is passed the state is prepared
|
75
|
-
|
76
|
-
as some additional optimizations including removing zero rotations and double cnots.
|
74
|
+
When a Statevector argument is passed the state is prepared based on the
|
75
|
+
:class:`~.library.Isometry` synthesis described in [1].
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
References:
|
78
|
+
1. Iten et al., Quantum circuits for isometries (2016).
|
79
|
+
`Phys. Rev. A 93, 032318
|
80
|
+
<https://journals.aps.org/pra/abstract/10.1103/PhysRevA.93.032318>`__.
|
81
81
|
|
82
82
|
"""
|
83
83
|
self._params_arg = params
|
@@ -119,7 +119,7 @@ class StatePreparation(Gate):
|
|
119
119
|
elif self._from_int:
|
120
120
|
self.definition = self._define_from_int()
|
121
121
|
else:
|
122
|
-
self.definition = self.
|
122
|
+
self.definition = self._define_synthesis_isom()
|
123
123
|
|
124
124
|
def _define_from_label(self):
|
125
125
|
q = QuantumRegister(self.num_qubits, "q")
|
@@ -156,8 +156,8 @@ class StatePreparation(Gate):
|
|
156
156
|
# Raise if number of bits is greater than num_qubits
|
157
157
|
if len(intstr) > self.num_qubits:
|
158
158
|
raise QiskitError(
|
159
|
-
"StatePreparation integer has
|
160
|
-
" number of qubits in the circuit,
|
159
|
+
f"StatePreparation integer has {len(intstr)} bits, but this exceeds the"
|
160
|
+
f" number of qubits in the circuit, {self.num_qubits}."
|
161
161
|
)
|
162
162
|
|
163
163
|
for qubit, bit in enumerate(intstr):
|
@@ -168,29 +168,18 @@ class StatePreparation(Gate):
|
|
168
168
|
# we don't need to invert anything
|
169
169
|
return initialize_circuit
|
170
170
|
|
171
|
-
def
|
172
|
-
"""Calculate a subcircuit that implements this initialization
|
171
|
+
def _define_synthesis_isom(self):
|
172
|
+
"""Calculate a subcircuit that implements this initialization via isometry"""
|
173
|
+
q = QuantumRegister(self.num_qubits, "q")
|
174
|
+
initialize_circuit = QuantumCircuit(q, name="init_def")
|
173
175
|
|
174
|
-
|
175
|
-
|
176
|
-
https://arxiv.org/abs/quant-ph/0406176v5
|
177
|
-
|
178
|
-
Additionally implements some extra optimizations: remove zero rotations and
|
179
|
-
double cnots.
|
180
|
-
"""
|
181
|
-
# call to generate the circuit that takes the desired vector to zero
|
182
|
-
disentangling_circuit = self._gates_to_uncompute()
|
176
|
+
isom = Isometry(self._params_arg, 0, 0)
|
177
|
+
initialize_circuit.append(isom, q[:])
|
183
178
|
|
184
179
|
# invert the circuit to create the desired vector from zero (assuming
|
185
180
|
# the qubits are in the zero state)
|
186
|
-
if self._inverse is
|
187
|
-
|
188
|
-
else:
|
189
|
-
initialize_instr = disentangling_circuit.to_instruction()
|
190
|
-
|
191
|
-
q = QuantumRegister(self.num_qubits, "q")
|
192
|
-
initialize_circuit = QuantumCircuit(q, name="init_def")
|
193
|
-
initialize_circuit.append(initialize_instr, q[:])
|
181
|
+
if self._inverse is True:
|
182
|
+
return initialize_circuit.inverse()
|
194
183
|
|
195
184
|
return initialize_circuit
|
196
185
|
|
@@ -225,9 +214,9 @@ class StatePreparation(Gate):
|
|
225
214
|
|
226
215
|
if self.num_qubits != len(flat_qargs):
|
227
216
|
raise QiskitError(
|
228
|
-
"StatePreparation parameter vector has
|
229
|
-
"
|
230
|
-
|
217
|
+
f"StatePreparation parameter vector has {2**self.num_qubits}"
|
218
|
+
f" elements, therefore expects {self.num_qubits} "
|
219
|
+
f"qubits. However, {len(flat_qargs)} were provided."
|
231
220
|
)
|
232
221
|
yield flat_qargs, []
|
233
222
|
|
@@ -239,8 +228,8 @@ class StatePreparation(Gate):
|
|
239
228
|
if parameter in ["0", "1", "+", "-", "l", "r"]:
|
240
229
|
return parameter
|
241
230
|
raise CircuitError(
|
242
|
-
"invalid param label {} for instruction {}. Label should be "
|
243
|
-
"0, 1, +, -, l, or r "
|
231
|
+
f"invalid param label {type(parameter)} for instruction {self.name}. Label should be "
|
232
|
+
"0, 1, +, -, l, or r "
|
244
233
|
)
|
245
234
|
|
246
235
|
# StatePreparation instruction parameter can be int, float, and complex.
|
@@ -254,163 +243,94 @@ class StatePreparation(Gate):
|
|
254
243
|
def _return_repeat(self, exponent: float) -> "Gate":
|
255
244
|
return Gate(name=f"{self.name}*{exponent}", num_qubits=self.num_qubits, params=[])
|
256
245
|
|
257
|
-
def _gates_to_uncompute(self):
|
258
|
-
"""Call to create a circuit with gates that take the desired vector to zero.
|
259
246
|
|
260
|
-
|
261
|
-
|
262
|
-
"""
|
263
|
-
q = QuantumRegister(self.num_qubits)
|
264
|
-
circuit = QuantumCircuit(q, name="disentangler")
|
247
|
+
class UniformSuperpositionGate(Gate):
|
248
|
+
r"""Implements a uniform superposition state.
|
265
249
|
|
266
|
-
|
267
|
-
|
250
|
+
This gate is used to create the uniform superposition state
|
251
|
+
:math:`\frac{1}{\sqrt{M}} \sum_{j=0}^{M-1} |j\rangle` when it acts on an input
|
252
|
+
state :math:`|0...0\rangle`. Note, that `M` is not required to be
|
253
|
+
a power of 2, in which case the uniform superposition could be
|
254
|
+
prepared by a single layer of Hadamard gates.
|
268
255
|
|
269
|
-
|
270
|
-
# work out which rotations must be done to disentangle the LSB
|
271
|
-
# qubit (we peel away one qubit at a time)
|
272
|
-
(remaining_param, thetas, phis) = StatePreparation._rotations_to_disentangle(
|
273
|
-
remaining_param
|
274
|
-
)
|
256
|
+
.. note::
|
275
257
|
|
276
|
-
|
277
|
-
|
258
|
+
This class uses the Shukla-Vedula algorithm [1], which only needs
|
259
|
+
:math:`O(\log_2 (M))` qubits and :math:`O(\log_2 (M))` gates,
|
260
|
+
to prepare the superposition.
|
278
261
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
rz_mult = self._multiplex(RZGate, phis, last_cnot=add_last_cnot)
|
285
|
-
circuit.append(rz_mult.to_instruction(), q[i : self.num_qubits])
|
286
|
-
|
287
|
-
if np.linalg.norm(thetas) != 0:
|
288
|
-
ry_mult = self._multiplex(RYGate, thetas, last_cnot=add_last_cnot)
|
289
|
-
circuit.append(ry_mult.to_instruction().reverse_ops(), q[i : self.num_qubits])
|
290
|
-
circuit.global_phase -= np.angle(sum(remaining_param))
|
291
|
-
return circuit
|
292
|
-
|
293
|
-
@staticmethod
|
294
|
-
def _rotations_to_disentangle(local_param):
|
295
|
-
"""
|
296
|
-
Static internal method to work out Ry and Rz rotation angles used
|
297
|
-
to disentangle the LSB qubit.
|
298
|
-
These rotations make up the block diagonal matrix U (i.e. multiplexor)
|
299
|
-
that disentangles the LSB.
|
300
|
-
|
301
|
-
[[Ry(theta_1).Rz(phi_1) 0 . . 0],
|
302
|
-
[0 Ry(theta_2).Rz(phi_2) . 0],
|
303
|
-
.
|
304
|
-
.
|
305
|
-
0 0 Ry(theta_2^n).Rz(phi_2^n)]]
|
306
|
-
"""
|
307
|
-
remaining_vector = []
|
308
|
-
thetas = []
|
309
|
-
phis = []
|
310
|
-
|
311
|
-
param_len = len(local_param)
|
312
|
-
|
313
|
-
for i in range(param_len // 2):
|
314
|
-
# Ry and Rz rotations to move bloch vector from 0 to "imaginary"
|
315
|
-
# qubit
|
316
|
-
# (imagine a qubit state signified by the amplitudes at index 2*i
|
317
|
-
# and 2*(i+1), corresponding to the select qubits of the
|
318
|
-
# multiplexor being in state |i>)
|
319
|
-
(remains, add_theta, add_phi) = StatePreparation._bloch_angles(
|
320
|
-
local_param[2 * i : 2 * (i + 1)]
|
321
|
-
)
|
262
|
+
**References:**
|
263
|
+
[1]: A. Shukla and P. Vedula (2024), An efficient quantum algorithm for preparation
|
264
|
+
of uniform quantum superposition states, `Quantum Inf Process 23, 38
|
265
|
+
<https://link.springer.com/article/10.1007/s11128-024-04258-4>`_.
|
266
|
+
"""
|
322
267
|
|
323
|
-
|
268
|
+
def __init__(
|
269
|
+
self,
|
270
|
+
num_superpos_states: int = 2,
|
271
|
+
num_qubits: Optional[int] = None,
|
272
|
+
):
|
273
|
+
r"""
|
274
|
+
Args:
|
275
|
+
num_superpos_states (int):
|
276
|
+
A positive integer M = num_superpos_states (> 1) representing the number of computational
|
277
|
+
basis states with an amplitude of 1/sqrt(M) in the uniform superposition
|
278
|
+
state (:math:`\frac{1}{\sqrt{M}} \sum_{j=0}^{M-1} |j\rangle`, where
|
279
|
+
:math:`1< M <= 2^n`). Note that the remaining (:math:`2^n - M`) computational basis
|
280
|
+
states have zero amplitudes. Here M need not be an integer power of 2.
|
324
281
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
phis.append(-add_phi)
|
282
|
+
num_qubits (int):
|
283
|
+
A positive integer representing the number of qubits used. If num_qubits is None
|
284
|
+
or is not specified, then num_qubits is set to ceil(log2(num_superpos_states)).
|
329
285
|
|
330
|
-
|
286
|
+
Raises:
|
287
|
+
ValueError: num_qubits must be an integer greater than or equal to log2(num_superpos_states).
|
331
288
|
|
332
|
-
@staticmethod
|
333
|
-
def _bloch_angles(pair_of_complex):
|
334
289
|
"""
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
# Force a and b to be complex, as otherwise numpy.angle might fail.
|
340
|
-
a_complex = complex(a_complex)
|
341
|
-
b_complex = complex(b_complex)
|
342
|
-
mag_a = abs(a_complex)
|
343
|
-
final_r = math.sqrt(mag_a**2 + abs(b_complex) ** 2)
|
344
|
-
if final_r < _EPS:
|
345
|
-
theta = 0
|
346
|
-
phi = 0
|
347
|
-
final_r = 0
|
348
|
-
final_t = 0
|
290
|
+
if num_superpos_states <= 1:
|
291
|
+
raise ValueError("num_superpos_states must be a positive integer greater than 1.")
|
292
|
+
if num_qubits is None:
|
293
|
+
num_qubits = int(math.ceil(math.log2(num_superpos_states)))
|
349
294
|
else:
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
return final_r * cmath.exp(1.0j * final_t / 2), theta, phi
|
357
|
-
|
358
|
-
def _multiplex(self, target_gate, list_of_angles, last_cnot=True):
|
359
|
-
"""
|
360
|
-
Return a recursive implementation of a multiplexor circuit,
|
361
|
-
where each instruction itself has a decomposition based on
|
362
|
-
smaller multiplexors.
|
295
|
+
if not (isinstance(num_qubits, int) and (num_qubits >= math.log2(num_superpos_states))):
|
296
|
+
raise ValueError(
|
297
|
+
"num_qubits must be an integer greater than or equal to log2(num_superpos_states)."
|
298
|
+
)
|
299
|
+
super().__init__("USup", num_qubits, [num_superpos_states])
|
363
300
|
|
364
|
-
|
365
|
-
|
366
|
-
Args:
|
367
|
-
target_gate (Gate): Ry or Rz gate to apply to target qubit, multiplexed
|
368
|
-
over all other "select" qubits
|
369
|
-
list_of_angles (list[float]): list of rotation angles to apply Ry and Rz
|
370
|
-
last_cnot (bool): add the last cnot if last_cnot = True
|
371
|
-
|
372
|
-
Returns:
|
373
|
-
DAGCircuit: the circuit implementing the multiplexor's action
|
374
|
-
"""
|
375
|
-
list_len = len(list_of_angles)
|
376
|
-
local_num_qubits = int(math.log2(list_len)) + 1
|
377
|
-
|
378
|
-
q = QuantumRegister(local_num_qubits)
|
379
|
-
circuit = QuantumCircuit(q, name="multiplex" + str(local_num_qubits))
|
380
|
-
|
381
|
-
lsb = q[0]
|
382
|
-
msb = q[local_num_qubits - 1]
|
301
|
+
def _define(self):
|
383
302
|
|
384
|
-
|
385
|
-
if local_num_qubits == 1:
|
386
|
-
circuit.append(target_gate(list_of_angles[0]), [q[0]])
|
387
|
-
return circuit
|
303
|
+
qc = QuantumCircuit(self._num_qubits)
|
388
304
|
|
389
|
-
|
390
|
-
# requested angles have been correctly implemented by recursion
|
391
|
-
angle_weight = np.kron([[0.5, 0.5], [0.5, -0.5]], np.identity(2 ** (local_num_qubits - 2)))
|
305
|
+
num_superpos_states = self.params[0]
|
392
306
|
|
393
|
-
|
394
|
-
|
307
|
+
if (
|
308
|
+
num_superpos_states & (num_superpos_states - 1)
|
309
|
+
) == 0: # if num_superpos_states is an integer power of 2
|
310
|
+
m = int(math.log2(num_superpos_states))
|
311
|
+
qc.h(range(m))
|
312
|
+
self.definition = qc
|
313
|
+
return
|
395
314
|
|
396
|
-
|
397
|
-
|
398
|
-
|
315
|
+
n_value = [int(x) for x in reversed(np.binary_repr(num_superpos_states))]
|
316
|
+
k = len(n_value)
|
317
|
+
l_value = [index for (index, item) in enumerate(n_value) if item == 1] # Locations of '1's
|
399
318
|
|
400
|
-
|
401
|
-
|
319
|
+
qc.x(l_value[1:k])
|
320
|
+
m_current_value = 2 ** l_value[0]
|
321
|
+
theta = -2 * np.arccos(np.sqrt(m_current_value / num_superpos_states))
|
402
322
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
if list_len > 1:
|
408
|
-
circuit.append(multiplex_2.to_instruction().reverse_ops(), q[0:-1])
|
409
|
-
else:
|
410
|
-
circuit.append(multiplex_2.to_instruction(), q[0:-1])
|
323
|
+
if l_value[0] > 0: # if num_superpos_states is even
|
324
|
+
qc.h(range(l_value[0]))
|
325
|
+
qc.ry(theta, l_value[1])
|
326
|
+
qc.ch(l_value[1], range(l_value[0], l_value[1]), ctrl_state="0")
|
411
327
|
|
412
|
-
|
413
|
-
|
414
|
-
|
328
|
+
for m in range(1, len(l_value) - 1):
|
329
|
+
theta = -2 * np.arccos(
|
330
|
+
np.sqrt(2 ** l_value[m] / (num_superpos_states - m_current_value))
|
331
|
+
)
|
332
|
+
qc.cry(theta, l_value[m], l_value[m + 1], ctrl_state="0")
|
333
|
+
qc.ch(l_value[m + 1], range(l_value[m], l_value[m + 1]), ctrl_state="0")
|
334
|
+
m_current_value = m_current_value + 2 ** l_value[m]
|
415
335
|
|
416
|
-
|
336
|
+
self.definition = qc
|
@@ -45,10 +45,10 @@ class Isometry(Instruction):
|
|
45
45
|
|
46
46
|
The decomposition is based on [1].
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
References:
|
49
|
+
1. Iten et al., Quantum circuits for isometries (2016).
|
50
|
+
`Phys. Rev. A 93, 032318
|
51
|
+
<https://journals.aps.org/pra/abstract/10.1103/PhysRevA.93.032318>`__.
|
52
52
|
|
53
53
|
"""
|
54
54
|
|
@@ -123,8 +123,8 @@ class Isometry(Instruction):
|
|
123
123
|
# later here instead.
|
124
124
|
gate = self.inv_gate()
|
125
125
|
gate = gate.inverse()
|
126
|
-
q = QuantumRegister(self.num_qubits)
|
127
|
-
iso_circuit = QuantumCircuit(q)
|
126
|
+
q = QuantumRegister(self.num_qubits, "q")
|
127
|
+
iso_circuit = QuantumCircuit(q, name="isometry")
|
128
128
|
iso_circuit.append(gate, q[:])
|
129
129
|
self.definition = iso_circuit
|
130
130
|
|
@@ -139,8 +139,8 @@ class Isometry(Instruction):
|
|
139
139
|
Call to create a circuit with gates that take the desired isometry to the first 2^m columns
|
140
140
|
of the 2^n*2^n identity matrix (see https://arxiv.org/abs/1501.06911)
|
141
141
|
"""
|
142
|
-
q = QuantumRegister(self.num_qubits)
|
143
|
-
circuit = QuantumCircuit(q)
|
142
|
+
q = QuantumRegister(self.num_qubits, "q")
|
143
|
+
circuit = QuantumCircuit(q, name="isometry_to_uncompute")
|
144
144
|
(
|
145
145
|
q_input,
|
146
146
|
q_ancillas_for_output,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# This code is part of Qiskit.
|
2
2
|
#
|
3
|
-
# (C) Copyright IBM 2017,
|
3
|
+
# (C) Copyright IBM 2017, 2024.
|
4
4
|
#
|
5
5
|
# This code is licensed under the Apache License, Version 2.0. You may
|
6
6
|
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
@@ -16,7 +16,6 @@ from __future__ import annotations
|
|
16
16
|
import numpy as np
|
17
17
|
from qiskit.circuit.quantumcircuit import QuantumCircuit, Gate
|
18
18
|
from qiskit.circuit.exceptions import CircuitError
|
19
|
-
from qiskit.synthesis.linear import check_invertible_binary_matrix
|
20
19
|
from qiskit.circuit.library.generalized_gates.permutation import PermutationGate
|
21
20
|
|
22
21
|
# pylint: disable=cyclic-import
|
@@ -115,6 +114,8 @@ class LinearFunction(Gate):
|
|
115
114
|
|
116
115
|
# Optionally, check that the matrix is invertible
|
117
116
|
if validate_input:
|
117
|
+
from qiskit.synthesis.linear import check_invertible_binary_matrix
|
118
|
+
|
118
119
|
if not check_invertible_binary_matrix(linear):
|
119
120
|
raise CircuitError(
|
120
121
|
"A linear function must be represented by an invertible matrix."
|
@@ -68,8 +68,8 @@ class MCGupDiag(Gate):
|
|
68
68
|
def _define(self):
|
69
69
|
mcg_up_diag_circuit, _ = self._dec_mcg_up_diag()
|
70
70
|
gate = mcg_up_diag_circuit.to_instruction()
|
71
|
-
q = QuantumRegister(self.num_qubits)
|
72
|
-
mcg_up_diag_circuit = QuantumCircuit(q)
|
71
|
+
q = QuantumRegister(self.num_qubits, "q")
|
72
|
+
mcg_up_diag_circuit = QuantumCircuit(q, name="mcg_up_to_diagonal")
|
73
73
|
mcg_up_diag_circuit.append(gate, q[:])
|
74
74
|
self.definition = mcg_up_diag_circuit
|
75
75
|
|
@@ -108,8 +108,8 @@ class MCGupDiag(Gate):
|
|
108
108
|
q=[q_target,q_controls,q_ancilla_zero,q_ancilla_dirty]
|
109
109
|
"""
|
110
110
|
diag = np.ones(2 ** (self.num_controls + 1)).tolist()
|
111
|
-
q = QuantumRegister(self.num_qubits)
|
112
|
-
circuit = QuantumCircuit(q)
|
111
|
+
q = QuantumRegister(self.num_qubits, "q")
|
112
|
+
circuit = QuantumCircuit(q, name="mcg_up_to_diagonal")
|
113
113
|
(q_target, q_controls, q_ancillas_zero, q_ancillas_dirty) = self._define_qubit_role(q)
|
114
114
|
# ToDo: Keep this threshold updated such that the lowest gate count is achieved:
|
115
115
|
# ToDo: we implement the MCG with a UCGate up to diagonal if the number of controls is
|