Browse code

add some additional functionality to the state module

Joseph Weston authored on 01/11/2023 04:34:05
Showing 1 changed files
... ...
@@ -10,7 +10,7 @@ by the associated classical bitstring.
10 10
 
11 11
 import numpy as np
12 12
 
13
-__all__ = ["from_classical", "is_normalized", "num_qubits", "zero"]  # type: ignore
13
+__all__ = ["from_classical", "is_normalized", "is_normalizable", "normalize", "num_qubits", "zero"]  # type: ignore
14 14
 
15 15
 
16 16
 def from_classical(bitstring):
... ...
@@ -59,7 +59,22 @@ def num_qubits(state):
59 59
 
60 60
 def is_normalized(state: np.ndarray) -> bool:
61 61
     """Return True if and only if 'state' is normalized."""
62
-    return np.allclose(np.linalg.norm(state), 1)
62
+    return np.isclose(np.linalg.norm(state), 1)
63
+
64
+
65
+def is_normalizable(v: np.ndarray) -> bool:
66
+    """Return True if and only if 'v' is normalizable."""
67
+    # If the norm is too small then normalizing a vector using
68
+    # the norm will yield a vector that is not normalized to machine
69
+    # precision.
70
+    return bool(np.linalg.norm(v) ** 2 > np.finfo(float).smallest_normal)
71
+
72
+
73
+def normalize(state: np.ndarray) -> np.ndarray:
74
+    """Return a normalized state, given a potentially un-normalized one."""
75
+    if not is_normalizable(state):
76
+        raise ValueError("State is not normalizable")
77
+    return state / np.linalg.norm(state)
63 78
 
64 79
 
65 80
 def _check_valid_state(state):
Browse code

Fix some minor typos

Joseph Weston authored on 01/11/2023 04:33:23
Showing 1 changed files
... ...
@@ -68,7 +68,7 @@ def _check_valid_state(state):
68 68
         isinstance(state, np.ndarray)
69 69
         # is complex
70 70
         and np.issubdtype(state.dtype, np.complex128)
71
-        # is square
71
+        # is a vector
72 72
         and len(state.shape) == 1
73 73
         # has size 2**n, n > 1
74 74
         and np.log2(state.shape[0]).is_integer()
Browse code

Add more constructors and tests to the "state" module

Joseph Weston authored on 15/09/2021 17:23:38
Showing 1 changed files
... ...
@@ -10,7 +10,7 @@ by the associated classical bitstring.
10 10
 
11 11
 import numpy as np
12 12
 
13
-__all__ = ["from_classical"]  # type: ignore
13
+__all__ = ["from_classical", "is_normalized", "num_qubits", "zero"]  # type: ignore
14 14
 
15 15
 
16 16
 def from_classical(bitstring):
... ...
@@ -28,7 +28,6 @@ def from_classical(bitstring):
28 28
         The state vector in the computational basis.
29 29
         Has :math:`2^n` components.
30 30
     """
31
-
32 31
     bitstring = "".join(map(str, bitstring))
33 32
     n_qubits = len(bitstring)
34 33
     try:
... ...
@@ -39,3 +38,41 @@ def from_classical(bitstring):
39 38
     state = np.zeros(1 << n_qubits, dtype=complex)
40 39
     state[index] = 1
41 40
     return state
41
+
42
+
43
+def zero(n: int):
44
+    """Return the zero state on 'n' qubits."""
45
+    state = np.zeros(1 << n, dtype=complex)
46
+    state[0] = 1
47
+    return state
48
+
49
+
50
+def num_qubits(state):
51
+    """Return the number of qubits in the state.
52
+
53
+    Raises ValueError if 'state' does not have a shape that is
54
+    an integer power of 2.
55
+    """
56
+    _check_valid_state(state)
57
+    return state.shape[0].bit_length() - 1
58
+
59
+
60
+def is_normalized(state: np.ndarray) -> bool:
61
+    """Return True if and only if 'state' is normalized."""
62
+    return np.allclose(np.linalg.norm(state), 1)
63
+
64
+
65
+def _check_valid_state(state):
66
+    if not (
67
+        # is an array
68
+        isinstance(state, np.ndarray)
69
+        # is complex
70
+        and np.issubdtype(state.dtype, np.complex128)
71
+        # is square
72
+        and len(state.shape) == 1
73
+        # has size 2**n, n > 1
74
+        and np.log2(state.shape[0]).is_integer()
75
+        and state.shape[0].bit_length() > 1
76
+        and is_normalized(state)
77
+    ):
78
+        raise ValueError("State is not valid")
Browse code

moved to src directory structure

This avoids problems with testing against the wrong package version

Joseph Weston authored on 30/11/2019 18:31:57
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,41 @@
1
+"""Quantum state vectors
2
+
3
+The quantum state of :math:`n` quantum bits is represented as a 1D array of complex
4
+numbers of length :math:`2^n`; the components of the state vector in the
5
+computational basis.
6
+
7
+The computational basis for :math:`n` qubits is ordered by the number represented
8
+by the associated classical bitstring.
9
+"""
10
+
11
+import numpy as np
12
+
13
+__all__ = ["from_classical"]  # type: ignore
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[(2**n,), 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_qubits = 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(1 << n_qubits, dtype=complex)
40
+    state[index] = 1
41
+    return state