light experiment works
This commit is contained in:
parent
7bd12b203d
commit
4fd95fcbf6
@ -2,7 +2,7 @@ import cirq
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
from lib_q_computer_math import State, QuantumCircuit, QuantumProcessor, C, H, x, _, _0, _1
|
||||
from lib import State, QuantumCircuit, QuantumProcessor, C, H, x, _, _0, _1
|
||||
|
||||
|
||||
def from_angles_1(theta, phi):
|
||||
|
@ -1,4 +1,4 @@
|
||||
from lib_q_computer_math import s
|
||||
from lib import s
|
||||
|
||||
|
||||
def int_to_state(i):
|
||||
|
@ -2,6 +2,7 @@ import random
|
||||
from collections import defaultdict
|
||||
from functools import reduce
|
||||
from numbers import Complex
|
||||
from pprint import pprint
|
||||
from typing import Union
|
||||
|
||||
import numpy as np
|
||||
@ -46,6 +47,9 @@ class Matrix(object):
|
||||
def __add__(self, other):
|
||||
return Matrix(self.m + other.m)
|
||||
|
||||
def __sub__(self, other):
|
||||
return Matrix(self.m - other.m)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, Complex):
|
||||
return bool(np.allclose(self.m, other))
|
||||
@ -86,8 +90,30 @@ class Matrix(object):
|
||||
def __len__(self):
|
||||
return len(self.m)
|
||||
|
||||
def inner(self, other):
|
||||
"""Define inner product - a.k.a dot product, scalar product - <0|0>"""
|
||||
return Matrix(np.dot(self._conjugate_transpose(), other.m))
|
||||
|
||||
def dot(self, other):
|
||||
"""Alias to inner"""
|
||||
return self.inner(other)
|
||||
|
||||
def scalar(self, other):
|
||||
"""Alias to inner"""
|
||||
return self.inner(other)
|
||||
|
||||
def outer(self, other):
|
||||
"""Define outer product |0><0|"""
|
||||
"""Define outer product |0><0|
|
||||
https://en.wikipedia.org/wiki/Outer_product
|
||||
|
||||
Given two vectors u and v, their outer product u ⊗ v is defined
|
||||
as the m × n matrix A obtained by multiplying each element of u
|
||||
by each element of v
|
||||
|
||||
The outer product u ⊗ v is equivalent to a matrix multiplication uvT,
|
||||
provided that u is represented as a m × 1 column vector and v as a
|
||||
n × 1 column vector (which makes vT a row vector).
|
||||
"""
|
||||
return Matrix(np.outer(self.m, other.m))
|
||||
|
||||
def x(self, other):
|
||||
@ -136,10 +162,16 @@ class Vector(Matrix):
|
||||
return self.m.shape[1] == 1
|
||||
|
||||
|
||||
VectorOrList = Union[Vector, ListOrNdarray]
|
||||
|
||||
|
||||
class State(Vector):
|
||||
def __init__(self, m: ListOrNdarray = None, name: str = '', *args, **kwargs):
|
||||
def __init__(self, m: VectorOrList = None, name: str = '', *args, **kwargs):
|
||||
"""State vector representing quantum state"""
|
||||
super().__init__(m, *args, **kwargs)
|
||||
if type(m) is Vector:
|
||||
super().__init__(m.m, *args, **kwargs)
|
||||
else:
|
||||
super().__init__(m, *args, **kwargs)
|
||||
self.name = name
|
||||
self.measurement_result = None
|
||||
# TODO: SHOULD WE NORMALIZE?
|
||||
@ -190,6 +222,9 @@ class State(Vector):
|
||||
assert 0 <= phi <= 2 * np.pi
|
||||
return theta, phi
|
||||
|
||||
def to_ket(self):
|
||||
return self.conjugate_transpose()
|
||||
|
||||
def rotate_x(self, theta):
|
||||
return Rx(theta).on(self)
|
||||
|
||||
@ -276,7 +311,7 @@ class State(Vector):
|
||||
Measures with a measurement operator mo
|
||||
TODO: Can't define `mo: MeasurementOperator` because in python you can't declare classes before defining them
|
||||
"""
|
||||
m = mo.on(self) / np.sqrt(mo.get_prob(self))
|
||||
m = mo.on(self).m / np.sqrt(mo.get_prob(self))
|
||||
return State(m)
|
||||
|
||||
def measure_partial(self, qubit_n):
|
||||
@ -342,7 +377,7 @@ class State(Vector):
|
||||
|
||||
|
||||
def test_measure_partial():
|
||||
state = b_00
|
||||
state = b_phi_p
|
||||
state.measure_partial(1)
|
||||
|
||||
|
||||
@ -635,31 +670,31 @@ _m = State([[1 / np.sqrt(2)],
|
||||
name='-')
|
||||
|
||||
# 4 Bell states
|
||||
b_00 = State([[1 / np.sqrt(2)],
|
||||
[0],
|
||||
[0],
|
||||
[1 / np.sqrt(2)]],
|
||||
name='B00')
|
||||
b_phi_p = State([[1 / np.sqrt(2)],
|
||||
[0],
|
||||
[0],
|
||||
[1 / np.sqrt(2)]],
|
||||
name="{}+".format(REPR_GREEK_PHI))
|
||||
|
||||
b_01 = State([[0],
|
||||
[1 / np.sqrt(2)],
|
||||
[1 / np.sqrt(2)],
|
||||
[0]],
|
||||
name='B01')
|
||||
b_psi_p = State([[0],
|
||||
[1 / np.sqrt(2)],
|
||||
[1 / np.sqrt(2)],
|
||||
[0]],
|
||||
name="{}+".format(REPR_GREEK_PSI))
|
||||
|
||||
b_10 = State([[1 / np.sqrt(2)],
|
||||
[0],
|
||||
[0],
|
||||
[-1 / np.sqrt(2)]],
|
||||
name='B10')
|
||||
b_phi_m = State([[1 / np.sqrt(2)],
|
||||
[0],
|
||||
[0],
|
||||
[-1 / np.sqrt(2)]],
|
||||
name="{}-".format(REPR_GREEK_PHI))
|
||||
|
||||
b_11 = State([[0],
|
||||
[1 / np.sqrt(2)],
|
||||
[-1 / np.sqrt(2)],
|
||||
[0]],
|
||||
name='B11')
|
||||
b_psi_m = State([[0],
|
||||
[1 / np.sqrt(2)],
|
||||
[-1 / np.sqrt(2)],
|
||||
[0]],
|
||||
name="{}-".format(REPR_GREEK_PSI))
|
||||
|
||||
well_known_states = [_p, _m, b_00, b_01, b_10, b_11]
|
||||
well_known_states = [_p, _m, b_phi_p, b_psi_p, b_phi_m, b_psi_m]
|
||||
|
||||
_ = I = UnitaryOperator([[1, 0],
|
||||
[0, 1]],
|
||||
@ -847,17 +882,17 @@ def test():
|
||||
assert _0 + _1 == _1 + _0 # commutativity of vector addition
|
||||
assert _0 + (_1 + _p) == (_0 + _1) + _p # associativity of vector addition
|
||||
assert 8 * (_0 + _1) == 8 * _0 + 8 * _1 # Linear when multiplying by constants
|
||||
assert _0 | _0 == 1 # parallel have 1 product
|
||||
assert _0 | _1 == 0 # orthogonal have 0 product
|
||||
assert _0.inner(_0) == 1 # parallel have 1 product
|
||||
assert _0.inner(_1) == 0 # orthogonal have 0 product
|
||||
assert _0.is_orthogonal(_1)
|
||||
assert _1 | (8 * _0) == 8 * (_1 | _0) # Inner product is linear multiplied by constants
|
||||
assert _p | (_1 + _0) == (_p | _1) + (_p | _0) # Inner product is linear in superpos of vectors
|
||||
assert _1.inner(8 * _0) == 8 * _1.inner(_0) # Inner product is linear multiplied by constants
|
||||
assert _p.inner(_1 + _0) == _p.inner(_1) + _p.inner(_0) # Inner product is linear in superpos of vectors
|
||||
|
||||
assert np.isclose(_1.length(), 1.0) # all of the vector lengths are normalized
|
||||
assert np.isclose(_0.length(), 1.0)
|
||||
assert np.isclose(_p.length(), 1.0)
|
||||
|
||||
assert _0 | _1 == (_1 | _0).complex_conjugate() # non-commutative inner product
|
||||
assert _0.inner(_1) == _1.inner(_0).complex_conjugate() # non-commutative inner product
|
||||
|
||||
test_to_from_angles()
|
||||
|
||||
@ -871,14 +906,14 @@ def test():
|
||||
test_unitary_hermitian()
|
||||
|
||||
# Pauli X gate flips the |0> to |1> and the |1> to |0>
|
||||
assert X | _1 == _0
|
||||
assert X | _0 == _1
|
||||
assert X.on(_1) == _0
|
||||
assert X.on(_0) == _1
|
||||
|
||||
# Test the Y Pauli operator with complex number literal notation
|
||||
assert Y | _0 == State([[0],
|
||||
[1j]])
|
||||
assert Y | _1 == State([[-1j],
|
||||
[0]])
|
||||
assert Y.on(_0) == State([[0],
|
||||
[1j]])
|
||||
assert Y.on(_1) == State([[-1j],
|
||||
[0]])
|
||||
|
||||
# Test Pauli rotation gates
|
||||
testRotPauli()
|
||||
@ -928,11 +963,11 @@ def test():
|
||||
# First - create a superposition
|
||||
H = UnitaryOperator([[1 / np.sqrt(2), 1 / np.sqrt(2)],
|
||||
[1 / np.sqrt(2), -1 / np.sqrt(2)], ])
|
||||
superpos = H | _0
|
||||
superpos = H.on(_0)
|
||||
assert superpos == _p
|
||||
|
||||
# Then CNOT the superposition with a |0> qubit
|
||||
bell = CNOT | (superpos * _0)
|
||||
bell = CNOT.on(superpos * _0)
|
||||
assert bell == State([[1 / np.sqrt(2)],
|
||||
[0.],
|
||||
[0.],
|
||||
@ -944,7 +979,6 @@ def test():
|
||||
assert np.isclose(bell.get_prob(0b11), 0.5) # Probability for bell in 11 is 0.5
|
||||
|
||||
################################
|
||||
# TODO: Don't know where outer product fits - something about density operator?
|
||||
assert _0.x(_0) == Matrix([[1, 0],
|
||||
[0, 0]])
|
||||
assert _0.x(_1) == Matrix([[0, 1],
|
||||
@ -1196,33 +1230,44 @@ def test_quantum_processor():
|
||||
|
||||
def test_light():
|
||||
# http://alienryderflex.com/polarizer/
|
||||
# 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')
|
||||
|
||||
# create random light/photon
|
||||
random_pol = Vector([[np.random.uniform(0, 1)], [np.random.uniform(0, 1)]])
|
||||
random_light = normalize_state(random_pol)
|
||||
def random_light():
|
||||
random_pol = Vector([[np.random.uniform(0, 1)], [np.random.uniform(0, 1)]])
|
||||
return normalize_state(random_pol)
|
||||
|
||||
# TODO: Doesn't work...
|
||||
qc = QuantumCircuit(1, initial_steps=[[random_light]])
|
||||
qc.add_row([hor_filter, ver_filter])
|
||||
qc.print()
|
||||
qp = QuantumProcessor(qc)
|
||||
qp.print_sample(qp.get_sample(100))
|
||||
def experiment(id, random_ls, filters):
|
||||
total_light = defaultdict(int)
|
||||
human_state = "Light"
|
||||
for filter in filters:
|
||||
human_state += "->{}".format(filter.name)
|
||||
|
||||
# add three filters as operators
|
||||
qc = QuantumCircuit(1, initial_steps=[[random_light]])
|
||||
qc.add_row([hor_filter, diag_filter, ver_filter])
|
||||
qc.print()
|
||||
qp = QuantumProcessor(qc)
|
||||
qp.print_sample(qp.get_sample(100))
|
||||
for r in random_ls:
|
||||
st = filters[0].on(r)
|
||||
for filter in filters:
|
||||
st = filter.on(st)
|
||||
st = State(st)
|
||||
total_light[st.measure()] += 1
|
||||
print("{}. {}:\n {}".format(id, human_state, dict(total_light)))
|
||||
|
||||
its = 100
|
||||
random_lights = [random_light() for _ in range(its)]
|
||||
|
||||
# Just horizonal - should result in some light
|
||||
experiment(1, random_lights, [hor_filter, ])
|
||||
|
||||
# Vertical after horizonal - should result in 0
|
||||
experiment(2, random_lights, [ver_filter, hor_filter])
|
||||
|
||||
# TODO: Something is wrong here...
|
||||
# Vertical after diagonal after horizontal - should result in ~ 50% compared to only Horizontal
|
||||
experiment(3, random_lights, [ver_filter, diag_filter, hor_filter])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
||||
# test_quantum_processor()
|
||||
# test_light()
|
||||
test_quantum_processor()
|
||||
test_light()
|
||||
# test_measure_partial()
|
20
play.py
20
play.py
@ -1,20 +0,0 @@
|
||||
import numpy as np
|
||||
from lib_q_computer_math import Vector, Matrix, MeasurementOperator, _0, _1, _p, normalize_state, State
|
||||
|
||||
|
||||
def main():
|
||||
random_pol = Vector([[np.random.uniform(0, 1)], [np.random.uniform(0, 1)]])
|
||||
random_light = normalize_state(random_pol)
|
||||
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')
|
||||
State(hor_filter.on(random_light).m).measure()
|
||||
print(hor_filter.on(_0))
|
||||
print(ver_filter.on(_0))
|
||||
print(ver_filter.on(hor_filter.on(_0)))
|
||||
print(ver_filter.on(diag_filter.on(hor_filter.on(_0))))
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user