Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add indexing and inner product to Statevector #7095

Merged
merged 40 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
16ecf1c
Add inner product method to Statevector. fix #4934
DavideFrr Aug 14, 2020
8f3609f
Add getitem method to Statevector. fix #4916
DavideFrr Aug 14, 2020
37f3992
Update statevector.py
DavideFrr Aug 15, 2020
448e6c7
Update statevector.py
DavideFrr Aug 15, 2020
acae8fd
Update statevector.py
DavideFrr Aug 15, 2020
3107cd3
fix Qiskit#4934
DavideFrr Oct 4, 2021
1c54157
Merge branch 'main' into statevector_feature
DavideFrr Oct 4, 2021
10e3ab3
Fix indentation issue
DavideFrr Oct 4, 2021
c9cf3f8
Merge remote-tracking branch 'origin/statevector_feature' into statev…
DavideFrr Oct 4, 2021
5facc52
Add release note
DavideFrr Oct 4, 2021
ad47355
Fix linting
DavideFrr Oct 4, 2021
fee7020
Add missing-return-doc
DavideFrr Oct 4, 2021
e6824a2
Merge branch 'main' into statevector_feature
DavideFrr Oct 5, 2021
205f2a4
Update qiskit/quantum_info/states/statevector.py
DavideFrr Oct 5, 2021
b195dbe
Update releasenotes/notes/make-statevector-subscriptable-and-add-inne…
DavideFrr Oct 5, 2021
00b3a77
Update releasenotes/notes/make-statevector-subscriptable-and-add-inne…
DavideFrr Oct 5, 2021
8142597
Update release note
DavideFrr Oct 5, 2021
828b0fc
Merge branch 'main' into statevector_feature
DavideFrr Oct 7, 2021
09d4b1e
Update qiskit/quantum_info/states/statevector.py
DavideFrr Oct 8, 2021
04167da
Update test/python/quantum_info/states/test_statevector.py
DavideFrr Oct 8, 2021
297b53f
Update test/python/quantum_info/states/test_statevector.py
DavideFrr Oct 8, 2021
c06a97d
Handle negative key for Statevector __getitem__ method
DavideFrr Oct 8, 2021
d81f72d
Clean up test for inner product
DavideFrr Oct 8, 2021
937dc84
Merge branch 'main' into statevector_feature
DavideFrr Oct 8, 2021
a62f29b
Fix code style
DavideFrr Oct 12, 2021
78c24cf
Merge branch 'main' into statevector_feature
DavideFrr Oct 12, 2021
974e29a
Merge branch 'main' into statevector_feature
DavideFrr Oct 15, 2021
de9d31c
Test inner method raises exceptions
DavideFrr Oct 15, 2021
d944afb
Test getitem method raises exceptions
DavideFrr Oct 15, 2021
bc1bf36
Test getitem method raises exceptions
DavideFrr Oct 15, 2021
3b6f8ca
Test getitem method raises exceptions
DavideFrr Oct 15, 2021
4d62d48
Better exception message
DavideFrr Oct 15, 2021
fe18c89
Check for matching subsystems in vectors
DavideFrr Oct 19, 2021
ac47655
Correct type in return docstring
DavideFrr Oct 19, 2021
20339b6
Merge branch 'main' into statevector_feature
DavideFrr Oct 19, 2021
f10dd28
Fix inner product test
DavideFrr Oct 19, 2021
9a3d194
Fix linting
DavideFrr Oct 19, 2021
171ef22
Fix typos in release note
jakelishman Oct 21, 2021
5a92dab
Merge branch 'main' into statevector_feature
jakelishman Oct 21, 2021
6800690
Merge branch 'main' into statevector_feature
mergify[bot] Oct 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions qiskit/quantum_info/states/statevector.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,29 @@ def _ipython_display_(self):

display(out)

def __getitem__(self, key):
"""Return Statevector item either by index or binary label
Args:
key (int or str): index or corresponding binary label, e.g. '01' = 1.

Returns:
np.complex128: Statevector item.

Raises:
QiskitError: if key is not valid.
"""
if isinstance(key, str):
if re.match(r"^[01]+$", key) is None:
raise QiskitError("Key contains invalid characters.")
key = int(key, 2)
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
if isinstance(key, int):
if key < self.dim:
return self._data[key]
else:
raise QiskitError("Key is greater than Statevector dimension.")
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
else:
raise QiskitError("Key must be int or a valid binary string.")

@property
def data(self):
"""Return data."""
Expand Down Expand Up @@ -244,6 +267,26 @@ def tensor(self, other):
ret._data = np.kron(self._data, other._data)
return ret

def inner(self, other):
r"""Return the inner product of self and other as
:math:`\langle self| other \rangle`.

Args:
other (Statevector): a quantum state object.

Returns:
Statevector: the inner product of self and other, :math:`\langle self| other \rangle`.

Raises:
QiskitError: if other is not a quantum state or has different dimension.
"""
if not isinstance(other, Statevector):
other = Statevector(other)
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
if self.dim != other.dim:
raise QiskitError("Other Statevector has different dimensions.")
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
inner = np.dot(self.conjugate().data, other.data)
return inner

def expand(self, other):
"""Return the tensor product state other ⊗ self.

Expand Down Expand Up @@ -805,6 +848,7 @@ def _evolve_instruction(statevec, obj, qargs=None):
obj.name, type(obj.definition)
)
)

if obj.definition.global_phase:
statevec._data *= np.exp(1j * float(obj.definition.global_phase))
qubits = {qubit: i for i, qubit in enumerate(obj.definition.qubits)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
features:
- |
Make :class:`qiskit.quantum_info.states.statevector.Statevector` subscriptable.
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
User can now retrieve the i-th elementh in a Statevector by index as statevec[i].

See `#4916 <https://github.com/Qiskit/qiskit-terra/issues/4916>`__ from more information.

Add inner product method to :class:`qiskit.quantum_info.states.statevector.Statevector`.
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
It takes as imput an other statevector an outputs the inner product.

For example::
statevec_inner_other = statevec.inner(other)

See `#4934 <https://github.com/Qiskit/qiskit-terra/issues/4934>`__ from more information.
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
25 changes: 24 additions & 1 deletion test/python/quantum_info/states/test_statevector.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from itertools import permutations
from ddt import ddt, data
import numpy as np
from numpy.testing import assert_allclose
from numpy.testing import assert_allclose, assert_almost_equal

from qiskit.test import QiskitTestCase
from qiskit import QiskitError
Expand Down Expand Up @@ -208,6 +208,15 @@ def test_equal(self):
vec = self.rand_vec(4)
self.assertEqual(Statevector(vec), Statevector(vec.tolist()))

def test_getitem(self):
"""Test __getitem__ method"""
for _ in range(10):
vec = self.rand_vec(4)
state = Statevector(vec)
for i in range(4):
self.assertEqual(state[i], vec[i])
self.assertEqual(state[format(i, "b")], vec[i])

DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
def test_copy(self):
"""Test Statevector copy method"""
for _ in range(5):
Expand Down Expand Up @@ -335,6 +344,20 @@ def test_tensor(self):
self.assertEqual(state.dims(), (3, 2))
assert_allclose(state.data, target)

def test_inner(self):
"""Test inner method."""
for _ in range(10):
seed = np.random.randint(0, np.iinfo(np.int32).max)
rng = np.random.default_rng(seed)
dim = 2 ** rng.integers(1, 4)
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
vec0 = Statevector(self.rand_vec(dim))
vec1 = Statevector(self.rand_vec(dim))
target = 0
for i in range(vec0.dim):
target += np.conj(vec0.data[i]) * vec1.data[i]
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved
result = vec0.inner(vec1)
assert_almost_equal(result, target)
DavideFrr marked this conversation as resolved.
Show resolved Hide resolved

def test_add(self):
"""Test add method."""
for _ in range(10):
Expand Down