TODO quantum circuit
This commit is contained in:
parent
fae34da41a
commit
a09bdb949c
@ -236,11 +236,7 @@ class UnitaryOperator(LinearOperator, UnitaryMatrix):
|
||||
LinearOperator.__init__(self, func=self.operator_func, *args, **kwargs)
|
||||
|
||||
def operator_func(self, other):
|
||||
if not hasattr(other, "m"):
|
||||
other_m = other
|
||||
else:
|
||||
other_m = other.m
|
||||
return State(np.dot(self.m, other_m))
|
||||
return State(np.dot(self.m, other.m))
|
||||
|
||||
def __repr__(self):
|
||||
if self.name:
|
||||
@ -248,49 +244,6 @@ class UnitaryOperator(LinearOperator, UnitaryMatrix):
|
||||
return str(self.m)
|
||||
|
||||
|
||||
"""
|
||||
Define States and Operators
|
||||
"""
|
||||
|
||||
_0 = State([[1],
|
||||
[0]],
|
||||
name='0')
|
||||
|
||||
_1 = State([[0],
|
||||
[1]],
|
||||
name='1')
|
||||
|
||||
_p = State([[1 / np.sqrt(2)],
|
||||
[1 / np.sqrt(2)]],
|
||||
name='+')
|
||||
|
||||
_m = State([[1 / np.sqrt(2)],
|
||||
[- 1 / np.sqrt(2)]],
|
||||
name='-')
|
||||
|
||||
well_known_states = [_0, _1, _p, _m]
|
||||
|
||||
_ = I = UnitaryOperator([[1, 0],
|
||||
[0, 1]],
|
||||
name="-")
|
||||
|
||||
X = UnitaryOperator([[0, 1],
|
||||
[1, 0]],
|
||||
name="X")
|
||||
|
||||
Y = UnitaryOperator([[0, -1j],
|
||||
[1j, 0]],
|
||||
name="Y")
|
||||
|
||||
Z = UnitaryOperator([[1, 0],
|
||||
[0, -1]],
|
||||
name="Z")
|
||||
|
||||
H = UnitaryOperator([[1 / np.sqrt(2), 1 / np.sqrt(2)],
|
||||
[1 / np.sqrt(2), -1 / np.sqrt(2)], ],
|
||||
name="H")
|
||||
|
||||
|
||||
# TODO - How to add a CNOT gate to the Quantum Processor?
|
||||
# Imagine if I have to act on a 3-qubit computer and CNOT(q1, q3)
|
||||
#
|
||||
@ -353,6 +306,48 @@ class TwoQubitOperator(UnitaryOperator):
|
||||
return reduce((lambda x, y: x * y), outer_0) + reduce((lambda x, y: x * y), outer_1)
|
||||
|
||||
|
||||
"""
|
||||
Define States and Operators
|
||||
"""
|
||||
|
||||
_0 = State([[1],
|
||||
[0]],
|
||||
name='0')
|
||||
|
||||
_1 = State([[0],
|
||||
[1]],
|
||||
name='1')
|
||||
|
||||
_p = State([[1 / np.sqrt(2)],
|
||||
[1 / np.sqrt(2)]],
|
||||
name='+')
|
||||
|
||||
_m = State([[1 / np.sqrt(2)],
|
||||
[- 1 / np.sqrt(2)]],
|
||||
name='-')
|
||||
|
||||
well_known_states = [_0, _1, _p, _m]
|
||||
|
||||
_ = I = UnitaryOperator([[1, 0],
|
||||
[0, 1]],
|
||||
name="-")
|
||||
|
||||
X = UnitaryOperator([[0, 1],
|
||||
[1, 0]],
|
||||
name="X")
|
||||
|
||||
Y = UnitaryOperator([[0, -1j],
|
||||
[1j, 0]],
|
||||
name="Y")
|
||||
|
||||
Z = UnitaryOperator([[1, 0],
|
||||
[0, -1]],
|
||||
name="Z")
|
||||
|
||||
H = UnitaryOperator([[1 / np.sqrt(2), 1 / np.sqrt(2)],
|
||||
[1 / np.sqrt(2), -1 / np.sqrt(2)], ],
|
||||
name="H")
|
||||
|
||||
CNOT = TwoQubitOperator([[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 0, 1],
|
||||
@ -513,18 +508,11 @@ def naive_load_test(N):
|
||||
gc.collect()
|
||||
|
||||
|
||||
class QuantumProcessor(object):
|
||||
HALT_STATE = "HALT"
|
||||
RUNNING_STATE = "RUNNING"
|
||||
|
||||
class QuantumCircuit(object):
|
||||
def __init__(self, n_qubits: int):
|
||||
self.n_qubits = n_qubits
|
||||
self.steps = [[_0 for _ in range(n_qubits)], ]
|
||||
self._called_add_row = 0
|
||||
self.current_step = 0
|
||||
self.current_quantum_state = None
|
||||
self.current_state = self.HALT_STATE
|
||||
self.reset()
|
||||
|
||||
def add_row_step(self, row: int, step: int, qbit_state):
|
||||
if len(self.steps) <= step:
|
||||
@ -553,39 +541,14 @@ class QuantumProcessor(object):
|
||||
for row_data in rows_data:
|
||||
self.add_row(row_data)
|
||||
|
||||
def compose_quantum_state(self, step):
|
||||
if any([type(s) is TwoQubitPartial for s in step]):
|
||||
two_qubit_gates = filter(lambda s: type(s) is TwoQubitPartial, step)
|
||||
state = []
|
||||
for two_qubit_gate in two_qubit_gates:
|
||||
two_qubit_gate.operator.verify_step(step)
|
||||
state = two_qubit_gate.operator.compose(step, state)
|
||||
return state
|
||||
return reduce((lambda x, y: x * y), step)
|
||||
|
||||
def step(self):
|
||||
if self.current_step == 0 and self.current_state == self.HALT_STATE:
|
||||
self.current_state = self.RUNNING_STATE
|
||||
if self.current_step >= len(self.steps):
|
||||
self.current_state = self.HALT_STATE
|
||||
raise RuntimeWarning("Halted")
|
||||
running_step = self.steps[self.current_step]
|
||||
def get_next_step(self):
|
||||
running_step = self.steps[self.c_step]
|
||||
step_quantum_state = self.compose_quantum_state(running_step)
|
||||
if not self.current_quantum_state:
|
||||
self.current_quantum_state = step_quantum_state
|
||||
if not self.c_q_state:
|
||||
self.c_q_state = step_quantum_state
|
||||
else:
|
||||
self.current_quantum_state = State((step_quantum_state | self.current_quantum_state).m)
|
||||
self.current_step += 1
|
||||
|
||||
def run(self):
|
||||
for _ in self.steps:
|
||||
self.step()
|
||||
self.current_state = self.HALT_STATE
|
||||
|
||||
def reset(self):
|
||||
self.current_step = 0
|
||||
self.current_quantum_state = None
|
||||
self.current_state = self.HALT_STATE
|
||||
self.c_q_state = State((step_quantum_state | self.c_q_state).m)
|
||||
self.c_step += 1
|
||||
|
||||
def print(self):
|
||||
print("=" * 3 * len(self.steps))
|
||||
@ -597,10 +560,56 @@ class QuantumProcessor(object):
|
||||
print(line)
|
||||
print("=" * 3 * len(self.steps))
|
||||
|
||||
|
||||
class QuantumProcessor(object):
|
||||
HALT_STATE = "HALT"
|
||||
RUNNING_STATE = "RUNNING"
|
||||
|
||||
def __init__(self, circuit: QuantumCircuit):
|
||||
self.circuit = circuit
|
||||
self.c_step = 0
|
||||
self.c_q_state = None
|
||||
self.c_state = self.HALT_STATE
|
||||
self.reset()
|
||||
|
||||
def compose_quantum_state(self, step):
|
||||
if any([type(s) is TwoQubitPartial for s in step]):
|
||||
two_qubit_gates = filter(lambda s: type(s) is TwoQubitPartial, step)
|
||||
state = []
|
||||
for two_qubit_gate in two_qubit_gates:
|
||||
two_qubit_gate.operator.verify_step(step)
|
||||
state = two_qubit_gate.operator.compose(step, state)
|
||||
return state
|
||||
return reduce((lambda x, y: x * y), step)
|
||||
|
||||
def step(self):
|
||||
if self.c_step == 0 and self.c_state == self.HALT_STATE:
|
||||
self.c_state = self.RUNNING_STATE
|
||||
if self.c_step >= len(self.circuit.steps):
|
||||
self.c_state = self.HALT_STATE
|
||||
raise RuntimeWarning("Halted")
|
||||
running_step = self.circuit.get_next_step()
|
||||
step_quantum_state = self.compose_quantum_state(running_step)
|
||||
if not self.c_q_state:
|
||||
self.c_q_state = step_quantum_state
|
||||
else:
|
||||
self.c_q_state = State((step_quantum_state | self.c_q_state).m)
|
||||
self.c_step += 1
|
||||
|
||||
def run(self):
|
||||
for _ in self.steps:
|
||||
self.step()
|
||||
self.current_state = self.HALT_STATE
|
||||
|
||||
def reset(self):
|
||||
self.c_step = 0
|
||||
self.c_q_state = None
|
||||
self.c_state = self.HALT_STATE
|
||||
|
||||
def measure(self):
|
||||
if self.current_state != self.HALT_STATE:
|
||||
if self.c_state != self.HALT_STATE:
|
||||
raise RuntimeError("Processor is still running")
|
||||
return self.current_quantum_state.measure()
|
||||
return self.c_q_state.measure()
|
||||
|
||||
def run_n(self, n: int):
|
||||
for i in range(n):
|
||||
|
Loading…
Reference in New Issue
Block a user