If you really want to simulate measurement, that's how I would do it.
A function that finds probability amplitude associated to each eigenstate.
import numpy as np
import itertools
from qutip import basis, tensor, snot
def prepareMeasurement(N, psi):
# all the spin configurations
confs = list(itertools.product([0, 1], repeat=N))
# probability distribution
P = []
for conf in confs:
# particular outcome as quantum object
psi_ref = tensor([basis(2, m) for m in conf])
# probability of this outcome
p = np.abs(psi.overlap(psi_ref))**2.
# append to the distribution
P.append(p)
return confs, np.array(P)
Then a function that given this amplitude takes n
random measurements.
def simulateMeasurement(confs, P, n):
return np.random.choice(range(len(confs)), n, p=P)
We can test it on a little example, let's create an even superposition of all the eigenstates. They should all have same amplitudes.
psi0 = tensor([basis(2, 0), basis(2, 0), basis(2, 0)])
psif = snot(N=3, target=0)*psi0
psif = snot(N=3, target=1)*psif
psif = snot(N=3, target=2)*psif
And this is how we apply our measurement simulation, let's perform 10000
measurements. Let's also calculate counts.
confs, P = prepareMeasurement(3, psif)
measurements = simulateMeasurement(confs, P, 10000)
unique, counts = np.unique(measurements, return_counts=True)
Visualize the data in histogram-like form.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.bar(unique, height=counts)
plt.xticks(unique, ["|{0}>".format(format(m, '03b')) for m in unique])
ax.set_title('Testing measurement simulation with QuTip')
ax.set_ylabel('Count')
ax.set_xlabel('Measurement')
plt.show()
This is what we're getting
I included everything in this public gist repository. Hope it helps!