-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
44 lines (39 loc) · 1.39 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import numpy as np
from qiskit.quantum_info import SparsePauliOp
def compute_cut_size(graph, bitstring):
"""
Get the cut size of the partition of ``graph`` described by the given
``bitstring``.
"""
cut_sz = 0
for (u, v) in graph.edges:
if bitstring[u] != bitstring[v]:
cut_sz += 1
return cut_sz
def get_ising_energies(
operator: SparsePauliOp,
states: np.array
):
"""
Get the energies of the given Ising ``operator`` that correspond to the
given ``states``.
"""
# Unroll Hamiltonian data into NumPy arrays
paulis = np.array([list(ops) for ops, _ in operator.label_iter()]) != "I"
coeffs = operator.coeffs.real
# Vectorized energies computation
energies = (-1) ** (states @ paulis.T) @ coeffs
return energies
def expected_energy(
hamiltonian: SparsePauliOp,
measurements: np.array
):
"""
Compute the expected energy of the given ``hamiltonian`` with respect to
the observed ``measurement``.
The latter is assumed to by a NumPy records array with fields ``states``
--describing the observed bit-strings as an integer array-- and ``counts``,
describing the corresponding observed frequency of each state.
"""
energies = get_ising_energies(hamiltonian, measurements["states"])
return np.dot(energies, measurements["counts"]) / measurements["counts"].sum()