114 lines
2.4 KiB
Python
114 lines
2.4 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):
|
||
|
"""
|
||
|
Measure result from computation
|
||
|
"""
|
||
|
probabilites = [q[0] ** 2 for q in qubits]
|
||
|
return bin(random.choices(
|
||
|
population=range(len(qubits)),
|
||
|
weights=probabilites
|
||
|
)[0])
|
||
|
|
||
|
|
||
|
_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
|
||
|
superposition = Qubit(H * _0) * Qubit(H * _0)
|
||
|
print(superposition)
|
||
|
CNOT_superposition = Qubit(CNOT * superposition)
|
||
|
print(CNOT_superposition)
|
||
|
|
||
|
print(measure(CNOT_superposition))
|
||
|
# print(INVERTED_CNOT)
|
||
|
|
||
|
# 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()
|