krisi's experiment

This commit is contained in:
Daniel Tsvetkov 2020-01-29 18:29:13 +01:00
parent ad57b7b006
commit 64644d322e
2 changed files with 82 additions and 33 deletions

View File

@ -1,25 +1,49 @@
import cirq
from math import pi
import numpy as np
from collections import defaultdict
from lib_q_computer_math import State, QuantumCircuit, QuantumProcessor, C, H, x, _, _0, _1
def superdense():
# Pick a qubit.
q0 = cirq.GridQubit(0, 0)
def from_angles_1(theta, phi):
theta, phi = State._normalize_angles(theta, phi)
m0 = -np.sin(theta / 2)
m1 = np.cos(theta / 2) * np.power(np.e, (1j * phi))
m = m0 * _0 + m1 * _1
return State(m.m)
# Create a circuit
circuit = cirq.Circuit(
cirq.rx(pi/8).on(q0),
cirq.rz(pi/2).on(q0),
cirq.measure(q0, key='q0'),
)
print("Circuit:")
print(circuit)
simulator = cirq.Simulator()
result = simulator.run(circuit, repetitions=100)
print("Results:")
print(result)
def krisi(q2func, iterations=100, sample_count=1):
all_samples = defaultdict(int)
for i in range(iterations):
# print("Running iteration {}".format(i))
theta = round(np.random.uniform(0, np.pi), 3)
phi = round(np.random.uniform(0, 2 * np.pi), 3)
# print("theta: {:.2f} ({:.2f} deg) | phi: {:.2f} ({:.2f} deg)".format(
# theta, np.rad2deg(theta),
# phi, np.rad2deg(phi)))
q1 = State.from_angles(theta, phi)
q2 = q2func(theta, phi)
qc = QuantumCircuit(2, [[q1, q2], ])
qc.add_row([C, H])
qc.add_row([x, _])
qp = QuantumProcessor(qc)
this_samples = qp.get_sample(sample_count)
for k, v in this_samples.items():
all_samples[k] += v
print("------------- ALL SAMPLES for {}".format(q2func.__name__))
for k, v in sorted(all_samples.items(), key=lambda x: x[0]):
print("{}: {}".format(k, v))
print("==============================================")
def krisi_0():
krisi(q2func=State.from_angles)
def krisi_1():
krisi(q2func=from_angles_1)
if __name__ == "__main__":
superdense()
krisi_0()

View File

@ -129,8 +129,17 @@ class State(Vector):
def _is_normalized(self):
return np.isclose(np.sum(np.abs(self.m ** 2)), 1.0)
@staticmethod
def _normalize_angles(theta, phi):
# theta is between [0 and pi]
theta = theta.real % np.pi if theta.real != np.pi else theta.real
# phi is between (0 and 2*pi]
phi = phi.real % (2 * np.pi)
return theta, phi
@classmethod
def from_angles(cls, theta, phi):
theta, phi = cls._normalize_angles(theta, phi)
m0 = np.cos(theta / 2)
m1 = np.sin(theta / 2) * np.power(np.e, (1j * phi))
m = m0 * _0 + m1 * _1
@ -147,8 +156,9 @@ class State(Vector):
theta += np.pi
assert 0 <= theta <= np.pi
div = np.sin(theta/2)
div = np.sin(theta / 2)
if div == 0:
# here is doesn't matter what phi is as phase at the poles is arbitrary
phi = 0
else:
exp = m1 / div
@ -159,17 +169,18 @@ class State(Vector):
return theta, phi
def __repr__(self):
if self.name:
return '|{}>'.format(self.name)
for well_known_state in well_known_states:
if self == well_known_state:
return repr(well_known_state)
for used_state in UNIVERSE_STATES:
if self.m == used_state:
return repr(used_state)
next_state_sub = ''.join([REPR_MATH_SUBSCRIPT_NUMBERS[int(d)] for d in str(len(UNIVERSE_STATES))])
state_name = '|{}{}>'.format(REPR_GREEK_PSI, next_state_sub)
UNIVERSE_STATES.append(self.m)
if not self.name:
for well_known_state in well_known_states:
if self == well_known_state:
return repr(well_known_state)
for used_state in UNIVERSE_STATES:
if self == used_state:
return repr(used_state)
next_state_sub = ''.join([REPR_MATH_SUBSCRIPT_NUMBERS[int(d)] for d in str(len(UNIVERSE_STATES))])
self.name = '{}{}'.format(REPR_GREEK_PSI, next_state_sub)
UNIVERSE_STATES.append(self)
matrix_rep = "{}".format(self.m).replace('[', '').replace(']', '').replace('\n', '|').strip()
state_name = '|{}> = {}'.format(self.name, matrix_rep)
return state_name
def norm(self):
@ -570,11 +581,18 @@ def naive_load_test(N):
class QuantumCircuit(object):
def __init__(self, n_qubits: int):
def __init__(self, n_qubits: int, initial_steps=None):
self.n_qubits = n_qubits
self.steps = [[_0 for _ in range(n_qubits)], ]
if not initial_steps:
self.steps = [[_0 for _ in range(n_qubits)], ]
else:
self.steps = initial_steps
self._called_add_row = 0
@property
def rows(self):
return self._called_add_row
def add_row_step(self, row: int, step: int, qbit_state):
if len(self.steps) <= step:
self.steps += [[I for _ in range(self.n_qubits)] for _ in range(len(self.steps) - step + 1)]
@ -663,6 +681,10 @@ class QuantumProcessor(object):
RUNNING_STATE = "RUNNING"
def __init__(self, circuit: QuantumCircuit):
if circuit.rows != circuit.n_qubits:
raise Exception("Declared circuit with n_qubits: {} but called add_row: {}".format(
circuit.n_qubits, circuit.rows
))
self.circuit = circuit
self.c_step = 0
self.c_q_state = None
@ -726,9 +748,12 @@ class QuantumProcessor(object):
result = self.measure()
rv[result] += 1
self.reset()
return rv
@staticmethod
def print_sample(rv):
for k, v in sorted(rv.items(), key=lambda x: x[0]):
print("{}: {}".format(k, v))
return rv
def test_quantum_processor():