partial measurement half-implemented

This commit is contained in:
Daniel Tsvetkov 2020-02-20 11:01:05 +01:00
parent 14bee6764a
commit aa06605f6c
1 changed files with 35 additions and 23 deletions

View File

@ -140,6 +140,7 @@ class State(Vector):
"""State vector representing quantum state"""
super().__init__(m, *args, **kwargs)
self.name = name
self.measurement_result = None
if not self._is_normalized():
raise TypeError("Not a normalized state vector")
@ -246,9 +247,10 @@ class State(Vector):
def measure(self):
"""
Measures in the computational basis
Measures in the computational basis.
Irreversable operation. Measuring again will result in the same result
TODO: Generalize the method so it takes a basis
TODO: Should we memoize the result? Should we memoize per basis?
TODO: Should we memoize per basis?
If it's measured twice, should it return the same state?
What about if measured twice but in different bases?
E.g. measure1 -> computation -> A
@ -257,10 +259,13 @@ class State(Vector):
measure4 -> +/- basis -> should it return B again or random weighted?
:return: binary representation of the measured qubit (e.g. "011")
"""
if self.measurement_result:
return self.measurement_result
weights = [self.get_prob(j) for j in range(len(self))]
format_str = self.get_fmt_of_element()
choices = [format_str.format(i) for i in range(len(weights))]
return random.choices(choices, weights)[0]
self.measurement_result = random.choices(choices, weights)[0]
return self.measurement_result
def measure_with_op(self, mo):
"""
@ -270,15 +275,24 @@ class State(Vector):
m = mo.on(self) / np.sqrt(mo.get_prob(self))
return State(m)
def measure_n(self, n=1):
"""measures n times
TODO: Does this make sense? When a state is measured once, it should "collapse"
def measure_partial(self, qubit_n):
"""Partial measurement of state
Measures the n-th qubit with probability sum(a_n),
adjusting the probability of the rest of the state
"""
measurements = defaultdict(int)
for _ in range(n):
k = self.measure()
measurements[k] += 1
return measurements
max_qubits = int(np.log2(len(self)))
if not (0 < qubit_n <= max_qubits):
raise Exception("Partial measurement of qubit_n must be between 1 and {}".format(max_qubits))
format_str = self.get_fmt_of_element()
bin_repr = [format_str.format(i) for i in range(len(self))]
partial_measurement_of_qbit = [int(b[qubit_n - 1]) for b in bin_repr]
indexes_for_p_0 = [i for i, index in enumerate(partial_measurement_of_qbit) if index==0]
weights_0 = [self.get_prob(j) for j in indexes_for_p_0]
choices_0 = [format_str.format(i) for i in indexes_for_p_0]
measurement_result = random.choices(choices_0, weights_0)[0]
# TODO: collapse the state and change the probabilities of the rest
# https://www.youtube.com/watch?v=MG_9JWsrKtM&list=PL1826E60FD05B44E4&index=16
return measurement_result
def pretty_print(self):
format_str = self.get_fmt_of_element() + " | {}"
@ -312,6 +326,11 @@ class State(Vector):
return [x, y, z]
def test_measure_partial():
state = s("|000>")
state.measure_partial(2)
def normalize_state(state_vector: ListOrNdarray):
"""Normalize a state by dividing by the square root of sum of the squares of states"""
norm_coef = np.sqrt(np.sum(np.array(state_vector) ** 2))
@ -923,16 +942,6 @@ def test_to_from_angles():
assert s == qbit
def test_measure_n():
qq = State([
[0.5],
[0.5],
[0.5],
[0.5],
])
qq.measure_n(100)
def naive_load_test(N):
import os
import psutil
@ -1154,6 +1163,7 @@ def test_quantum_processor():
def test_light():
# TODO: Are these measurement operators the correct way to represent hor/ver/diag filter?
# No, becuase they are not unitaries
hor_filter = MeasurementOperator.create_from_prob(Matrix(_0.m), name='h')
diag_filter = MeasurementOperator.create_from_prob(Matrix(_p.m), name='d')
ver_filter = MeasurementOperator.create_from_prob(Matrix(_1.m), name='v')
@ -1164,6 +1174,7 @@ def test_light():
qc = QuantumCircuit(1, initial_steps=[[random_light]])
# add three filters as operators
# qc.add_row([hor_filter, ver_filter])
qc.add_row([hor_filter, diag_filter, ver_filter])
qc.print()
qp = QuantumProcessor(qc)
@ -1173,6 +1184,7 @@ def test_light():
if __name__ == "__main__":
test()
test_quantum_processor()
# test()
# test_quantum_processor()
# test_light()
test_measure_partial()