-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Uniform State Preparation (#12112)
* Update state_preparation.py * Update state_preparation.py * Add files via upload * Update __init__.py * Update test_generalized_uniform_superposition_gate.py * Update test_generalized_uniform_superposition_gate.py * Update test_gate_definitions.py * made the format consistent with StatePreparation class * Put description and arguments in init * replaced assert with raise ValueError * small mistake in Returns * added test cases for ValueError cases * Update state_preparation.py * incorporate Steve's helpful suggestions * small bug * test_case fix * function for returning M * oops..forgot "" marks * Update state_preparation.py * removed get methods for num_qubit and M * added power of 2 condition * included test function when num_qubits is None * blacked init * blacked state_prep * blacked test_generalized_uniform_superposition_gate.py * reblacked state_prep * reblacked test_generalized_uniform_superposition_gate.py * shorterned max line length * reblacked state_prep * reblacked state_prep * for pyline * pylinted state_preparation.py * pylinted test_generalized_uniform_superposition_gate.py * pylinted test_gate_definitions.py * pylinted test_generalized_uniform_superposition_gate.py * Added GeneralizedUniformSuperposition gate Added GeneralizedUniformSuperposition gate class to the StatePreparation file in Circuit library. * modified: releasenotes/notes/generalized-uniform-superposition-gate-3bd95ffdf05ef18c.yaml * Updated release notes based on Steve's suggestions * Update release note * implemented the changes * fixed error * Update test_uniform_superposition_gate.py * Update uniform-superposition-gate-3bd95ffdf05ef18c.yaml * Update uniform-superposition-gate-3bd95ffdf05ef18c.yaml * Update qiskit/circuit/library/data_preparation/state_preparation.py Sounds good! Co-authored-by: Julien Gacon <[email protected]> * Update qiskit/circuit/library/data_preparation/state_preparation.py Okay! Co-authored-by: Julien Gacon <[email protected]> * Update qiskit/circuit/library/data_preparation/state_preparation.py oh that's interesting...I didn't know that. Thanks for the info! Co-authored-by: Julien Gacon <[email protected]> * Update releasenotes/notes/uniform-superposition-gate-3bd95ffdf05ef18c.yaml Ahhh...that's nice! Co-authored-by: Julien Gacon <[email protected]> * Update releasenotes/notes/uniform-superposition-gate-3bd95ffdf05ef18c.yaml You're quite right, will help for others who might look at the code in future. Co-authored-by: Luciano Bello <[email protected]> * Update state_preparation.py incorporated Julien's changes! * Update test_uniform_superposition_gate.py Incorporated Julien's optimization suggestion. * Update uniform-superposition-gate-3bd95ffdf05ef18c.yaml implemented both reviewers' suggestions. * Update uniform-superposition-gate-3bd95ffdf05ef18c.yaml removed SV24 * Update state_preparation.py * Update state_preparation.py * Update test_uniform_superposition_gate.py * Update uniform-superposition-gate-3bd95ffdf05ef18c.yaml * Update qiskit/circuit/library/data_preparation/state_preparation.py Co-authored-by: Julien Gacon <[email protected]> * blacked state_preparation.py * Update test_uniform_superposition_gate.py * pylinted state_preparation.py * removed transpile test_uniform_superposition_gate.py --------- Co-authored-by: Julien Gacon <[email protected]> Co-authored-by: Luciano Bello <[email protected]>
- Loading branch information
1 parent
0f585bd
commit ba486b7
Showing
5 changed files
with
230 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
releasenotes/notes/uniform-superposition-gate-3bd95ffdf05ef18c.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--- | ||
features: | ||
- | | ||
Implemented :class:`.UniformSuperpositionGate` class, which allows | ||
the creation of a uniform superposition state using | ||
the Shukla-Vedula algorithm. This feature facilitates the | ||
creation of quantum circuits that produce a uniform superposition | ||
state :math:`\frac{1}{\sqrt{M}} \sum_{j=0}^{M-1} |j\rangle`, where | ||
:math:`M` is a positive integer representing the number of | ||
computational basis states with an amplitude of | ||
:math:`\frac{1}{\sqrt{M}}`. This implementation supports the | ||
efficient creation of uniform superposition states, | ||
requiring only :math:`O(\log_2 (M))` qubits and | ||
:math:`O(\log_2 (M))` gates. Usage example: | ||
.. code-block:: python | ||
from qiskit import QuantumCircuit | ||
from qiskit.circuit.library.data_preparation import UniformSuperpositionGate | ||
M = 5 | ||
num_qubits = 3 | ||
usp_gate = UniformSuperpositionGate(M, num_qubits) | ||
qc = QuantumCircuit(num_qubits) | ||
qc.append(usp_gate, list(range(num_qubits))) | ||
qc.draw() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2024. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
""" | ||
Uniform Superposition Gate test. | ||
""" | ||
|
||
import unittest | ||
import math | ||
from test import QiskitTestCase | ||
import numpy as np | ||
from ddt import ddt, data | ||
|
||
from qiskit import QuantumCircuit | ||
from qiskit.quantum_info import Operator, Statevector | ||
|
||
from qiskit.circuit.library.data_preparation import ( | ||
UniformSuperpositionGate, | ||
) | ||
|
||
|
||
@ddt | ||
class TestUniformSuperposition(QiskitTestCase): | ||
"""Test initialization with UniformSuperpositionGate class""" | ||
|
||
@data(2, 3, 5) | ||
def test_uniform_superposition_gate(self, num_superpos_states): | ||
"""Test Uniform Superposition Gate""" | ||
n = int(math.ceil(math.log2(num_superpos_states))) | ||
desired_sv = (1 / np.sqrt(num_superpos_states)) * np.array( | ||
[1.0] * num_superpos_states + [0.0] * (2**n - num_superpos_states) | ||
) | ||
gate = UniformSuperpositionGate(num_superpos_states, n) | ||
actual_sv = Statevector(gate) | ||
np.testing.assert_allclose(desired_sv, actual_sv) | ||
|
||
@data(2, 3, 5, 13) | ||
def test_inverse_uniform_superposition_gate(self, num_superpos_states): | ||
"""Test Inverse Uniform Superposition Gate""" | ||
n = int(math.ceil(math.log2(num_superpos_states))) | ||
gate = UniformSuperpositionGate(num_superpos_states, n) | ||
qc = QuantumCircuit(n) | ||
qc.append(gate, list(range(n))) | ||
qc.append(gate.inverse(annotated=True), list(range(n))) | ||
actual_unitary_matrix = np.array(Operator(qc).data) | ||
desired_unitary_matrix = np.eye(2**n) | ||
np.testing.assert_allclose(desired_unitary_matrix, actual_unitary_matrix, atol=1e-14) | ||
|
||
@data(-2, -1, 0, 1) | ||
def test_incompatible_num_superpos_states(self, num_superpos_states): | ||
"""Test error raised if num_superpos_states not valid""" | ||
n = 1 | ||
with self.assertRaises(ValueError): | ||
UniformSuperpositionGate(num_superpos_states, n) | ||
|
||
@data(1, 2, 3, 4) | ||
def test_incompatible_int_num_superpos_states_and_qubit_args(self, n): | ||
"""Test error raised if number of qubits not compatible with integer | ||
state num_superpos_states (n >= log2(num_superpos_states) )""" | ||
num_superpos_states = 50 | ||
with self.assertRaises(ValueError): | ||
UniformSuperpositionGate(num_superpos_states, n) | ||
|
||
@data(2, 3, 5) | ||
def test_extra_qubits(self, num_superpos_states): | ||
"""Tests for cases where n >= log2(num_superpos_states)""" | ||
num_extra_qubits = 2 | ||
n = int(math.ceil(math.log2(num_superpos_states))) + num_extra_qubits | ||
desired_sv = (1 / np.sqrt(num_superpos_states)) * np.array( | ||
[1.0] * num_superpos_states + [0.0] * (2**n - num_superpos_states) | ||
) | ||
gate = UniformSuperpositionGate(num_superpos_states, n) | ||
actual_sv = Statevector(gate) | ||
np.testing.assert_allclose(desired_sv, actual_sv) | ||
|
||
@data(2, 3, 5) | ||
def test_no_qubit_args(self, num_superpos_states): | ||
"""Test Uniform Superposition Gate without passing the number of qubits as an argument""" | ||
n = int(math.ceil(math.log2(num_superpos_states))) | ||
desired_sv = (1 / np.sqrt(num_superpos_states)) * np.array( | ||
[1.0] * num_superpos_states + [0.0] * (2**n - num_superpos_states) | ||
) | ||
gate = UniformSuperpositionGate(num_superpos_states) | ||
actual_sv = Statevector(gate) | ||
np.testing.assert_allclose(desired_sv, actual_sv) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |