Browse code

Add a function to produce a state from a classical bitstring

also add relevant tests.

Joseph Weston authored on 09/11/2019 00:48:19
Showing 2 changed files
... ...
@@ -8,4 +8,34 @@ The computational basis for :math:`n` qubits is ordered by the number represente
8 8
 by the associated classical bitstring.
9 9
 """
10 10
 
11
-__all__ = []
11
+import numpy as np
12
+
13
+__all__ = ["from_classical"]
14
+
15
+
16
+def from_classical(bitstring):
17
+    """Return a quantum state corresponding to a classical bitstring.
18
+
19
+    Parameters
20
+    ----------
21
+    bitstring : sequence of bits
22
+        Can be a string like "01011", or a sequence of
23
+        integers.
24
+
25
+    Returns
26
+    -------
27
+    state : ndarray[complex]
28
+        The state vector in the computational basis.
29
+        Has :math:`2^n` components.
30
+    """
31
+
32
+    bitstring = "".join(map(str, bitstring))
33
+    n = len(bitstring)
34
+    try:
35
+        index = int(bitstring, base=2)
36
+    except ValueError:
37
+        raise ValueError("Input is not a classical bitstring") from None
38
+
39
+    state = np.zeros(2 ** n, dtype=complex)
40
+    state[index] = 1
41
+    return state
12 42
new file mode 100644
... ...
@@ -0,0 +1,49 @@
1
+import string
2
+from functools import partial
3
+
4
+from hypothesis import given
5
+import hypothesis.strategies as st
6
+import numpy as np
7
+import pytest
8
+
9
+import qsim.state
10
+
11
+
12
+MAX_QUBITS = 5
13
+
14
+n_qubits = st.integers(1, MAX_QUBITS)
15
+classical_bitstrings = n_qubits.flatmap(
16
+    lambda n: st.integers(0, 2 ** n).map(partial("{:0{n}b}".format, n=n))
17
+)
18
+invalid_bitstrings = n_qubits.flatmap(
19
+    lambda n: st.text(alphabet=string.digits, min_size=n, max_size=n)
20
+).filter(lambda s: any(b not in "01" for b in s))
21
+
22
+
23
+@given(classical_bitstrings)
24
+def test_from_classical(bitstring):
25
+
26
+    state = qsim.state.from_classical(bitstring)
27
+
28
+    i = int(bitstring, base=2)
29
+
30
+    assert np.issubdtype(state.dtype, np.dtype(complex))
31
+    assert state.shape == (2 ** len(bitstring),)
32
+    assert np.linalg.norm(state) == 1
33
+    assert abs(state[i]) == 1
34
+
35
+
36
+@given(classical_bitstrings)
37
+def test_from_classical_works_on_integer_lists(bitstring):
38
+
39
+    int_list = [int(b) for b in bitstring]
40
+
41
+    assert np.all(
42
+        qsim.state.from_classical(bitstring) == qsim.state.from_classical(int_list)
43
+    )
44
+
45
+
46
+@given(invalid_bitstrings)
47
+def test_from_classical_raises_on_bad_input(bitstring):
48
+    with pytest.raises(ValueError):
49
+        qsim.state.from_classical(bitstring)