Next up: measurement Also added a test on local complementationmaster
@@ -2,7 +2,7 @@ | |||||
Allows us to visualize the state in a browser | Allows us to visualize the state in a browser | ||||
""" | """ | ||||
import atexit, json | |||||
import atexit, json, time | |||||
from graphstate import GraphState | from graphstate import GraphState | ||||
from websocket import create_connection | from websocket import create_connection | ||||
@@ -21,14 +21,9 @@ class VisibleGraphState(GraphState): | |||||
self.update() | self.update() | ||||
self.ws.close() | self.ws.close() | ||||
def to_json(self): | |||||
""" We override to_json() so that we send the whole `ngbh` structure in JS-friendly form """ | |||||
ngbh = {a: {b: True for b in self.ngbh[a]} | |||||
for a in self.ngbh} | |||||
return {"vops": self.vops, "ngbh": ngbh, "meta": self.meta} | |||||
def update(self): | |||||
def update(self, delay = 0.5): | |||||
""" Call this function when you are ready to send data to the browser """ | """ Call this function when you are ready to send data to the browser """ | ||||
data = json.dumps(self.to_json()) | data = json.dumps(self.to_json()) | ||||
self.ws.send(data) | self.ws.send(data) | ||||
time.sleep(delay) | |||||
@@ -1,19 +1,25 @@ | |||||
from abp.viz import VisibleGraphState | from abp.viz import VisibleGraphState | ||||
from abp.util import xyz | |||||
import numpy as np | import numpy as np | ||||
import time | import time | ||||
import itertools | import itertools | ||||
square_unit_cell = (((0, 0), (0, 1)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((0, 1), (1, 1))) | |||||
funny_unit_cell = (((0, 0), (0, 1)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((0, 1), (1, 1)), ((0, 0), (.5, .5))) | |||||
square_unit_cell = ( | |||||
((0, 0), (0, 1)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((0, 1), (1, 1))) | |||||
funny_unit_cell = (((0, 0), (0, 1)), ((0, 0), (1, 0)), | |||||
((1, 0), (1, 1)), ((0, 1), (1, 1)), ((0, 0), (.5, .5))) | |||||
def add_offset(vector, offset): | def add_offset(vector, offset): | ||||
""" Offset a vector in n-dimensional space """ | """ Offset a vector in n-dimensional space """ | ||||
return tuple(v+o for v, o in zip(vector, offset)) | |||||
return tuple(v + o for v, o in zip(vector, offset)) | |||||
def offset_unit_cell(unit_cell, offset): | def offset_unit_cell(unit_cell, offset): | ||||
""" Offset a unit cell """ | """ Offset a unit cell """ | ||||
return {(add_offset(a, offset), add_offset(b, offset)) for a, b in unit_cell} | return {(add_offset(a, offset), add_offset(b, offset)) for a, b in unit_cell} | ||||
def lattice(unit_cell, size): | def lattice(unit_cell, size): | ||||
""" Generate a lattice from a unit cell """ | """ Generate a lattice from a unit cell """ | ||||
edges = set() | edges = set() | ||||
@@ -23,15 +29,14 @@ def lattice(unit_cell, size): | |||||
nodes = set(itertools.chain(*edges)) | nodes = set(itertools.chain(*edges)) | ||||
return nodes, edges | return nodes, edges | ||||
#s = VisibleGraphState() | |||||
nodes, edges = lattice(funny_unit_cell, (10, 10)) | |||||
# s = VisibleGraphState() | |||||
nodes, edges = lattice(square_unit_cell, (4, 4)) | |||||
psi = VisibleGraphState() | psi = VisibleGraphState() | ||||
for node in nodes: | for node in nodes: | ||||
pos = {"x": node[0], "y": node[1], "z": 0} | |||||
psi.add_node(str(node), meta={"position":pos}) | |||||
psi.add_node(str(node), position=xyz(node[0], node[1])) | |||||
psi.act_hadamard(str(node)) | |||||
for edge in edges: | for edge in edges: | ||||
psi.add_edge(str(edge[0]), str(edge[1])) | |||||
psi.act_cz(str(edge[0]), str(edge[1])) | |||||
@@ -0,0 +1,20 @@ | |||||
from abp.viz import VisibleGraphState | |||||
from abp.util import xyz | |||||
from abp.clifford import * | |||||
psi = VisibleGraphState() | |||||
psi.add_node(0, position = xyz(0, 0)) | |||||
psi.add_node(1, position = xyz(1, 1)) | |||||
psi.add_node(2, position = xyz(3, 2)) | |||||
psi.add_node(3, position = xyz(0, 3)) | |||||
for n in psi.node: | |||||
psi.act_hadamard(n) | |||||
psi.act_cz(0, 1) | |||||
psi.act_cz(0, 3) | |||||
psi.act_cz(1, 3) | |||||
psi.act_cz(1, 2) | |||||
while True: | |||||
psi.update() | |||||
psi.local_complementation(1) |
@@ -34,6 +34,7 @@ | |||||
<li><a href="#">Measure in Z</a></li> | <li><a href="#">Measure in Z</a></li> | ||||
<li><a href="#">Act Hadamard</a></li> | <li><a href="#">Act Hadamard</a></li> | ||||
<li><a href="#">Act Phase</a></li> | <li><a href="#">Act Phase</a></li> | ||||
<li><a href="#" onclick="editor.localComplementation()">Invert neighbourhood</a></li> | |||||
<!--<li>--> | <!--<li>--> | ||||
<!--<a href="#">IA</a>--> | <!--<a href="#">IA</a>--> | ||||
<!--<a href="#">IB</a>--> | <!--<a href="#">IB</a>--> | ||||
@@ -70,11 +70,11 @@ abj.local_complementation = function(node) { | |||||
var keys = Object.keys(abj.adj[node]); | var keys = Object.keys(abj.adj[node]); | ||||
for (var i = 0; i < keys.length; ++i) { | for (var i = 0; i < keys.length; ++i) { | ||||
for (var j = i + 1; j < keys.length; ++j) { | for (var j = i + 1; j < keys.length; ++j) { | ||||
toggle_edge(keys[i], keys[j]); | |||||
abj.toggle_edge(keys[i], keys[j]); | |||||
} | } | ||||
abj.node[i].vop = tables.times_table[abj.node[keys[i]].vop][sqz_h]; | |||||
abj.node[i].vop = tables.times_table[abj.node[keys[i]].vop][6]; | |||||
} | } | ||||
abj.node[node].vop = tables.times_table[abj.node[node].vop][msqx_h]; | |||||
abj.node[node].vop = tables.times_table[abj.node[node].vop][14]; | |||||
}; | }; | ||||
abj.act_local_rotation = function(node, operation) { | abj.act_local_rotation = function(node, operation) { | ||||
@@ -48,7 +48,7 @@ editor.addQubitAtPoint = function(point) { | |||||
} | } | ||||
// TODO: This SUCKS | // TODO: This SUCKS | ||||
var new_node = Math.random()*100000|0; | |||||
var new_node = point.x + "." + point.y + "." + point.z; | |||||
abj.add_node(new_node, { position: point, vop:0 }); | abj.add_node(new_node, { position: point, vop:0 }); | ||||
editor.focus(new_node); | editor.focus(new_node); | ||||
graph.update(); | graph.update(); | ||||
@@ -145,3 +145,10 @@ editor.deleteNode = function() { | |||||
editor.selection = undefined; | editor.selection = undefined; | ||||
node_data.className = "hidden"; | node_data.className = "hidden"; | ||||
}; | }; | ||||
editor.localComplementation = function() { | |||||
if (editor.selection === undefined){ return; } | |||||
abj.local_complementation(editor.selection); | |||||
graph.update(); | |||||
gui.serverMessage("Inverted neighbourhood of " + editor.selection + "."); | |||||
}; |
@@ -0,0 +1,24 @@ | |||||
from abp import GraphState | |||||
from abp import qi | |||||
def test_local_comp(): | |||||
""" Test that local complementation works okay """ | |||||
psi = GraphState() | |||||
psi.add_node(0) | |||||
psi.add_node(1) | |||||
psi.add_node(2) | |||||
psi.add_node(3) | |||||
for n in psi.node: | |||||
psi.act_hadamard(n) | |||||
psi.act_cz(0, 1) | |||||
psi.act_cz(0, 3) | |||||
psi.act_cz(1, 3) | |||||
psi.act_cz(1, 2) | |||||
before = psi.copy() | |||||
psi.local_complementation(1) | |||||
assert before.edgelist() != psi.edgelist() | |||||
assert before.to_state_vector() == psi.to_state_vector() | |||||