@@ -5,6 +5,7 @@ Provides an extremely basic graph structure, based on neighbour lists | |||||
from collections import defaultdict | from collections import defaultdict | ||||
import itertools as it | import itertools as it | ||||
import clifford | import clifford | ||||
import json | |||||
class GraphState(object): | class GraphState(object): | ||||
@@ -93,6 +94,11 @@ class GraphState(object): | |||||
return "graph:\n vops: {}\n ngbh: {}\n"\ | return "graph:\n vops: {}\n ngbh: {}\n"\ | ||||
.format(str(dict(self.vops)), str(dict(self.ngbh))) | .format(str(dict(self.vops)), str(dict(self.ngbh))) | ||||
def to_json(self): | |||||
""" Convert the graph to JSON form """ | |||||
ngbh = {key: tuple(value) for key, value in self.ngbh.items()} | |||||
return json.dumps({"vops": self.vops, "ngbh": ngbh}) | |||||
class DiffedGraphState(GraphState): | class DiffedGraphState(GraphState): | ||||
""" Just like a graph state, but tracks changes for rendering purposes """ | """ Just like a graph state, but tracks changes for rendering purposes """ | ||||
@@ -8,8 +8,11 @@ import threading | |||||
import time | import time | ||||
import os | import os | ||||
class VizHandler(SimpleHTTPRequestHandler): | class VizHandler(SimpleHTTPRequestHandler): | ||||
""" Handles requests to the server """ | """ Handles requests to the server """ | ||||
def __init__(self, *args, **kwargs): | def __init__(self, *args, **kwargs): | ||||
SimpleHTTPRequestHandler.__init__(self, *args, **kwargs) | SimpleHTTPRequestHandler.__init__(self, *args, **kwargs) | ||||
@@ -19,8 +22,8 @@ class VizHandler(SimpleHTTPRequestHandler): | |||||
self.send_header('Content-Type', 'application/json') | self.send_header('Content-Type', 'application/json') | ||||
self.end_headers() | self.end_headers() | ||||
state = self.server.state | state = self.server.state | ||||
self.wfile.write(json.dumps({"state":"{}".format(state)})) | |||||
self.wfile.write(json.dumps({"state": "{}".format(state)})) | |||||
def do_GET(self, *args, **kwargs): | def do_GET(self, *args, **kwargs): | ||||
""" Someone belled the server """ | """ Someone belled the server """ | ||||
parsed_path = urlparse.urlparse(self.path) | parsed_path = urlparse.urlparse(self.path) | ||||
@@ -29,14 +32,17 @@ class VizHandler(SimpleHTTPRequestHandler): | |||||
else: | else: | ||||
return SimpleHTTPRequestHandler.do_GET(self, *args, **kwargs) | return SimpleHTTPRequestHandler.do_GET(self, *args, **kwargs) | ||||
class Server(SocketServer.TCPServer): | class Server(SocketServer.TCPServer): | ||||
""" Serves the good stuff """ | """ Serves the good stuff """ | ||||
allow_reuse_address = True | allow_reuse_address = True | ||||
def __init__(self, port = 8000): | |||||
def __init__(self, port=8000): | |||||
self.port = port | self.port = port | ||||
self.state = None | self.state = None | ||||
SocketServer.TCPServer.__init__(self, ("127.0.0.1", self.port), VizHandler) | |||||
SocketServer.TCPServer.__init__( | |||||
self, ("127.0.0.1", self.port), VizHandler) | |||||
def update(self, state): | def update(self, state): | ||||
""" Update the in-memory state """ | """ Update the in-memory state """ | ||||
@@ -62,11 +68,10 @@ if __name__ == '__main__': | |||||
server = Server() | server = Server() | ||||
server.start() | server.start() | ||||
i=0 | |||||
i = 0 | |||||
while True: | while True: | ||||
server.update(i) | server.update(i) | ||||
i += 1 | i += 1 | ||||
time.sleep(1) | time.sleep(1) | ||||
server.shutdown() | server.shutdown() | ||||
@@ -11,7 +11,7 @@ | |||||
<body> | <body> | ||||
<script type="text/javascript" src="three.js"></script> | <script type="text/javascript" src="three.js"></script> | ||||
<script type="text/javascript" src="libs.js"></script> | <script type="text/javascript" src="libs.js"></script> | ||||
<script type="text/javascript" src="graph.js"></script> | |||||
<script type="text/javascript" src="poll.js"></script> | |||||
<script type="text/javascript" src="main.js"></script> | <script type="text/javascript" src="main.js"></script> | ||||
<img id="ball" src="data:image/png;base64,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"/ | <img id="ball" src="data:image/png;base64,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"/ | ||||
style=display:none;> | style=display:none;> | ||||
@@ -16,6 +16,7 @@ var curveProperties = { | |||||
curvature: 10 | curvature: 10 | ||||
}; | }; | ||||
var camera; | var camera; | ||||
var qubits; | |||||
// Run on startup | // Run on startup | ||||
window.onload = init; | window.onload = init; | ||||
@@ -38,6 +39,15 @@ function makeEdge(e) { | |||||
return line; | return line; | ||||
} | } | ||||
function makeQubits() { | |||||
qubitGeometry = new THREE.Geometry(); | |||||
qubitGeometry.labels = []; | |||||
var vertex = new THREE.Vector3(0, 0, 0); | |||||
qubitGeometry.vertices.push(vertex); | |||||
particles = new THREE.Points(qubitGeometry, materials.qubit); | |||||
return particles; | |||||
} | |||||
// Clear the whole scene | // Clear the whole scene | ||||
function makeScene() { | function makeScene() { | ||||
// Scene, controls, camera and so on | // Scene, controls, camera and so on | ||||
@@ -50,27 +60,38 @@ function makeScene() { | |||||
linewidth: 1 | linewidth: 1 | ||||
}; | }; | ||||
materials.edge = new THREE.LineBasicMaterial(lineStyle); | materials.edge = new THREE.LineBasicMaterial(lineStyle); | ||||
var pointStyle = { | var pointStyle = { | ||||
size: 0.2, | |||||
color: "0xcccccc", | |||||
size: 0.1, | |||||
map: materials.sprite, | map: materials.sprite, | ||||
alphaTest: 0.5, | alphaTest: 0.5, | ||||
transparent: true, | transparent: true, | ||||
vertexColors: THREE.VertexColors | |||||
}; | }; | ||||
materials.point = new THREE.PointsMaterial(pointStyle); | materials.point = new THREE.PointsMaterial(pointStyle); | ||||
var qubitStyle = { | |||||
size: 0.6, | |||||
map: materials.sprite, | |||||
alphaTest: 0.5, | |||||
transparent: true, | |||||
color: "red" | |||||
}; | |||||
materials.qubit = new THREE.PointsMaterial(qubitStyle); | |||||
// Build all the edges | // Build all the edges | ||||
//var edgeGroup = new THREE.Object3D(); | //var edgeGroup = new THREE.Object3D(); | ||||
qubits = makeQubits(); | |||||
myScene.add(qubits); | |||||
// Build all the nodes | // Build all the nodes | ||||
nodeGeometry = new THREE.Geometry(); | nodeGeometry = new THREE.Geometry(); | ||||
nodeGeometry.labels = []; | nodeGeometry.labels = []; | ||||
nodeGeometry.colors = []; | |||||
for (var i = 0; i < 10; ++i) { | for (var i = 0; i < 10; ++i) { | ||||
for (var j = 0; j < 10; ++j) { | for (var j = 0; j < 10; ++j) { | ||||
var vertex = new THREE.Vector3(i - 5, j - 5, 0); | var vertex = new THREE.Vector3(i - 5, j - 5, 0); | ||||
nodeGeometry.vertices.push(vertex); | nodeGeometry.vertices.push(vertex); | ||||
nodeGeometry.colors.push(new THREE.Color(0.5, 0.5, 0.5)); | |||||
nodeGeometry.labels.push("Click to add a qubit at (" + i + ", " + j + ")"); | nodeGeometry.labels.push("Click to add a qubit at (" + i + ", " + j + ")"); | ||||
} | } | ||||
} | } | ||||
@@ -145,6 +166,14 @@ function onMouseMove(event) { | |||||
checkIntersections(); | checkIntersections(); | ||||
} | } | ||||
function onClick(event){ | |||||
if (!selection){return;} | |||||
console.log(nodeGeometry.vertices[selection]); | |||||
qubits.geometry.dynamic = true; | |||||
qubits.geometry.vertices.push(nodeGeometry.vertices[selection].clone()); | |||||
qubits.geometry.verticesNeedUpdate = true; | |||||
} | |||||
// Render the current frame to the screen | // Render the current frame to the screen | ||||
function render() { | function render() { | ||||
renderer.render(scene, camera); | renderer.render(scene, camera); | ||||
@@ -160,7 +189,8 @@ function loopForever() { | |||||
// This just organises kickoff | // This just organises kickoff | ||||
function startMainLoop() { | function startMainLoop() { | ||||
scene = makeScene(); | scene = makeScene(); | ||||
document.addEventListener("mousemove", onMouseMove, false); | |||||
renderer.domElement.addEventListener("mousemove", onMouseMove, false); | |||||
renderer.domElement.addEventListener("click", onClick, false); | |||||
controls.addEventListener("change", render); | controls.addEventListener("change", render); | ||||
loopForever(); | loopForever(); | ||||
} | } | ||||
@@ -194,6 +224,9 @@ function init() { | |||||
controls.rotateSpeed = 0.2; | controls.rotateSpeed = 0.2; | ||||
camera.position.set(0, 0, 20); | camera.position.set(0, 0, 20); | ||||
// Start polling | |||||
setInterval(poll, 1000); | |||||
// Run | // Run | ||||
startMainLoop(); | startMainLoop(); | ||||
} | } |
@@ -4,7 +4,7 @@ var state; | |||||
function poll() { | function poll() { | ||||
var xhr = new XMLHttpRequest(); | var xhr = new XMLHttpRequest(); | ||||
xhr.onload=function() { | |||||
xhr.onload = function() { | |||||
state = JSON.parse(xhr.response); | state = JSON.parse(xhr.response); | ||||
soft_console.innerHTML = "\n" + xhr.responseText; | soft_console.innerHTML = "\n" + xhr.responseText; | ||||
}; | }; | ||||
@@ -17,7 +17,3 @@ function poll() { | |||||
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); | xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); | ||||
xhr.send(); | xhr.send(); | ||||
} | } | ||||
window.onload = function () { | |||||
setInterval(poll, 1000); | |||||
} |
@@ -67,6 +67,7 @@ def test_stress(): | |||||
g.add_edge(i, i + 1) | g.add_edge(i, i + 1) | ||||
assert time.clock() - t < .5 | assert time.clock() - t < .5 | ||||
def test_cz(): | def test_cz(): | ||||
""" Test CZ gate """ | """ Test CZ gate """ | ||||
g = GraphState() | g = GraphState() | ||||
@@ -75,9 +76,9 @@ def test_cz(): | |||||
g.act_local_rotation(0, clifford.by_name["hadamard"]) | g.act_local_rotation(0, clifford.by_name["hadamard"]) | ||||
g.act_local_rotation(1, clifford.by_name["hadamard"]) | g.act_local_rotation(1, clifford.by_name["hadamard"]) | ||||
g.act_local_rotation(1, clifford.by_name["py"]) | g.act_local_rotation(1, clifford.by_name["py"]) | ||||
print g | |||||
assert not g.has_edge(0, 1) | |||||
g.act_cz(0, 1) | g.act_cz(0, 1) | ||||
print g | |||||
assert g.has_edge(0, 1) | |||||
def test_diff(): | def test_diff(): | ||||
@@ -88,10 +89,5 @@ def test_diff(): | |||||
g.act_local_rotation(0, clifford.by_name["hadamard"]) | g.act_local_rotation(0, clifford.by_name["hadamard"]) | ||||
g.act_local_rotation(1, clifford.by_name["hadamard"]) | g.act_local_rotation(1, clifford.by_name["hadamard"]) | ||||
g.act_local_rotation(1, clifford.by_name["py"]) | g.act_local_rotation(1, clifford.by_name["py"]) | ||||
print g | |||||
g.act_cz(0, 1) | g.act_cz(0, 1) | ||||
print g.diff | |||||
assert len(g.diff) == 3 |