quantum/01_computer.py

131 lines
3.1 KiB
Python

import random
from math import sqrt, log
class Gate(list):
# Matrix multiplication
def __mul__(self, other):
rv = Gate()
for kol in range(len(other[0])):
for _ in range(len(self)):
rv.append([0])
# iterate through rows of a
for i in range(len(self)):
# iterate through columns of b
for j in range(len(other[0])):
# iterate through rows of b
for k in range(len(other)):
rv[i][j] += self[i][k] * other[k][j]
return rv
class Qubit(list):
# tensor multiplication
def __mul__(self, other):
rv = Qubit()
for i in self:
for j in other:
rv.append([i[0] * j[0]])
return rv
def measure(qubits, times=10):
"""
Measure result from computation based on the qubit population
"""
probabilites = [q[0] ** 2 for q in qubits]
return [bin(m) for m in random.choices(
population=range(len(qubits)),
weights=probabilites,
k=times
)]
_0 = Qubit([[1], [0]])
_1 = Qubit([[0], [1]])
I = Gate([
[1, 0],
[0, 1],
])
X = Gate([
[0, 1],
[1, 0],
])
Y = Gate([
[0, complex(0, -1)],
[complex(0, 1), 0],
])
Z = Gate([
[1, 0],
[0, -1],
])
CNOT = Gate([
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0],
])
H = Gate([
[1 / sqrt(2), 1 / sqrt(2)],
[1 / sqrt(2), -1 / sqrt(2)],
])
def main():
# TEST IDENTITY
assert _1 == I * _1
assert _0 == I * _0
# TEST BIT-FLIP
assert _1 == X * _0
assert _0 == X * _1
# TEST CNOT GATE - Control * Target
# Control is FALSE, so target doesn't change
assert CNOT * (_0 * _0) == (_0 * _0)
assert CNOT * (_0 * _1) == (_0 * _1)
# Control is TRUE, so target MUST change
assert CNOT * (_1 * _0) == (_1 * _1)
assert CNOT * (_1 * _1) == (_1 * _0)
# TEST HADAMARD
# Put two qubits in superposition
superposition = Qubit(H * _0) * Qubit(H * _0)
print(superposition)
# Entangle the qubits
entanglement = Qubit(CNOT * superposition)
print(entanglement)
# TODO: What does it mean to apply H gate on the entangled qubits???
# https://en.wikipedia.org/wiki/Controlled_NOT_gate#Behaviour_in_the_Hadamard_transformed_basis
# Should it be:
# q1 = Qubit(H * entanglement[:2])
# q2 = Qubit(H * entanglement[2:])
# But how does one get the 4x4 matrix of CNOT???
#
# q1 = Qubit(H * Qubit(entanglement[:2]))
# print(q1)
# q2 = Qubit(H * Qubit(entanglement[2:]))
# print(q2)
# print(q1 * q2)
# this should get us 1/4 chance for each combination of 00 01 10 and 10;
# measure 42 times
print(measure(entanglement, times=42))
# TEST MY MEMORY
# rv = _0
# QUBITS = 23
# print(2**QUBITS)
# print("{:.1f} KB".format(2**QUBITS / 2**10))
# print("{:.1f} MB".format(2**QUBITS / 2**20))
# print("{:.1f} GB".format(2**QUBITS / 2**30))
# for i in range(QUBITS):
# rv *= _0
# print(len(rv))
if __name__ == "__main__":
main()