| @@ -0,0 +1,37 @@ | |||||
| from abp.viz import VisibleGraphState | |||||
| import numpy as np | |||||
| import time | |||||
| 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))) | |||||
| def add_offset(vector, offset): | |||||
| """ Offset a vector in n-dimensional space """ | |||||
| return tuple(v+o for v, o in zip(vector, offset)) | |||||
| def offset_unit_cell(unit_cell, offset): | |||||
| """ Offset a unit cell """ | |||||
| return {(add_offset(a, offset), add_offset(b, offset)) for a, b in unit_cell} | |||||
| def lattice(unit_cell, size): | |||||
| """ Generate a lattice from a unit cell """ | |||||
| edges = set() | |||||
| for offset in itertools.product(*map(range, size)): | |||||
| edges |= offset_unit_cell(unit_cell, offset) | |||||
| nodes = set(itertools.chain(*edges)) | |||||
| return nodes, edges | |||||
| #s = VisibleGraphState() | |||||
| nodes, edges = lattice(funny_unit_cell, (10, 10)) | |||||
| psi = VisibleGraphState() | |||||
| for node in nodes: | |||||
| pos = {"x": node[0], "y": node[1], "z": 0} | |||||
| psi.add_node(str(node), meta={"position":pos}) | |||||
| for edge in edges: | |||||
| psi.add_edge(str(edge[0]), str(edge[1])) | |||||
| @@ -6,7 +6,7 @@ s = VisibleGraphState() | |||||
| for i in range(200): | for i in range(200): | ||||
| x = 10*np.cos(np.pi*2*i/60) | x = 10*np.cos(np.pi*2*i/60) | ||||
| y = 10*np.sin(np.pi*2*i/60) | y = 10*np.sin(np.pi*2*i/60) | ||||
| s.add_node(i, {"position": (round(x, 2), round(y, 2), round(i/50., 2))}) | |||||
| s.add_node(i, {"position": {"x":round(x, 2), "y":round(y, 2), "z":round(i/50., 2)}}) | |||||
| s.act_local_rotation(i, "hadamard") | s.act_local_rotation(i, "hadamard") | ||||
| for i in range(200-1): | for i in range(200-1): | ||||
| s.act_cz(i, i+1) | s.act_cz(i, i+1) | ||||
| @@ -1,15 +1,9 @@ | |||||
| var abj = {}; | var abj = {}; | ||||
| abj.ngbh = {}; | |||||
| abj.vops = {}; | |||||
| abj.meta = {}; | |||||
| ngbh = abj.ngbh; | |||||
| vops = abj.vops; | |||||
| meta = abj.meta; | |||||
| abj.add_node = function(node, m) { | abj.add_node = function(node, m) { | ||||
| ngbh[node] = {}; | |||||
| vops[node] = tables.clifford.hadamard; | |||||
| meta[node] = m ? m : {}; | |||||
| abj.ngbh[node] = {}; | |||||
| abj.vops[node] = tables.clifford.hadamard; | |||||
| abj.meta[node] = m ? m : {}; | |||||
| }; | }; | ||||
| abj.add_nodes = function(nodes) { | abj.add_nodes = function(nodes) { | ||||
| @@ -17,8 +11,8 @@ abj.add_nodes = function(nodes) { | |||||
| }; | }; | ||||
| abj.add_edge = function(a, b) { | abj.add_edge = function(a, b) { | ||||
| ngbh[a][b] = true; | |||||
| ngbh[b][a] = true; | |||||
| abj.ngbh[a][b] = true; | |||||
| abj.ngbh[b][a] = true; | |||||
| }; | }; | ||||
| abj.add_edges = function(edges) { | abj.add_edges = function(edges) { | ||||
| @@ -28,12 +22,12 @@ abj.add_edges = function(edges) { | |||||
| }; | }; | ||||
| abj.del_edge = function(a, b) { | abj.del_edge = function(a, b) { | ||||
| delete ngbh[a][b]; | |||||
| delete ngbh[b][a]; | |||||
| delete abj.ngbh[a][b]; | |||||
| delete abj.ngbh[b][a]; | |||||
| }; | }; | ||||
| abj.has_edge = function(a, b) { | abj.has_edge = function(a, b) { | ||||
| return Object.prototype.hasOwnProperty.call(ngbh[a], b); | |||||
| return Object.prototype.hasOwnProperty.call(abj.ngbh[a], b); | |||||
| }; | }; | ||||
| abj.toggle_edge = function(a, b) { | abj.toggle_edge = function(a, b) { | ||||
| @@ -45,7 +39,7 @@ abj.toggle_edge = function(a, b) { | |||||
| }; | }; | ||||
| abj.get_swap = function(node, avoid) { | abj.get_swap = function(node, avoid) { | ||||
| for (var i in ngbh[node]) { | |||||
| for (var i in abj.ngbh[node]) { | |||||
| if (i != avoid) { | if (i != avoid) { | ||||
| return i; | return i; | ||||
| } | } | ||||
| @@ -55,7 +49,7 @@ abj.get_swap = function(node, avoid) { | |||||
| abj.remove_vop = function(node, avoid) { | abj.remove_vop = function(node, avoid) { | ||||
| var swap_qubit = get_swap(node, avoid); | var swap_qubit = get_swap(node, avoid); | ||||
| var decomposition = decompositions[vops[node]]; | |||||
| var decomposition = decompositions[abj.vops[node]]; | |||||
| for (var i = decomposition.length - 1; i >= 0; --i) { | for (var i = decomposition.length - 1; i >= 0; --i) { | ||||
| var v = decomposition[i]; | var v = decomposition[i]; | ||||
| local_complementation(v == "x" ? a : swap_qubit); | local_complementation(v == "x" ? a : swap_qubit); | ||||
| @@ -63,19 +57,19 @@ abj.remove_vop = function(node, avoid) { | |||||
| }; | }; | ||||
| abj.local_complementation = function(node) { | abj.local_complementation = function(node) { | ||||
| var keys = Object.keys(ngbh[node]); | |||||
| var keys = Object.keys(abj.ngbh[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]); | toggle_edge(keys[i], keys[j]); | ||||
| } | } | ||||
| vops[i] = tables.times_table[vops[keys[i]]][sqz_h]; | |||||
| abj.vops[i] = tables.times_table[abj.vops[keys[i]]][sqz_h]; | |||||
| } | } | ||||
| vops[node] = tables.times_table[vops[node]][msqx_h]; | |||||
| abj.vops[node] = tables.times_table[abj.vops[node]][msqx_h]; | |||||
| }; | }; | ||||
| abj.act_local_rotation = function(node, operation) { | abj.act_local_rotation = function(node, operation) { | ||||
| var rotation = tables.clifford[operation]; | var rotation = tables.clifford[operation]; | ||||
| vops[node] = tables.times_table[rotation][vops[node]]; | |||||
| abj.vops[node] = tables.times_table[rotation][abj.vops[node]]; | |||||
| }; | }; | ||||
| abj.act_hadamard = function(node) { | abj.act_hadamard = function(node) { | ||||
| @@ -87,19 +81,19 @@ abj.is_sole_member = function(node, group) { | |||||
| }; | }; | ||||
| abj.act_cz = function(a, b) { | abj.act_cz = function(a, b) { | ||||
| if (is_sole_member(ngbh[a], b)) { | |||||
| if (is_sole_member(abj.ngbh[a], b)) { | |||||
| remove_vop(a, b); | remove_vop(a, b); | ||||
| } | } | ||||
| if (is_sole_member(ngbh[b], a)) { | |||||
| if (is_sole_member(abj.ngbh[b], a)) { | |||||
| remove_vop(b, a); | remove_vop(b, a); | ||||
| } | } | ||||
| if (is_sole_member(ngbh[a], b)) { | |||||
| if (is_sole_member(abj.ngbh[a], b)) { | |||||
| remove_vop(a, b); | remove_vop(a, b); | ||||
| } | } | ||||
| var edge = has_edge(a, b); | var edge = has_edge(a, b); | ||||
| var new_state = tables.cz_table[edge ? 1 : 0][vops[a]][vops[b]]; | |||||
| vops[a] = new_state[1]; | |||||
| vops[b] = new_state[2]; | |||||
| var new_state = tables.cz_table[edge ? 1 : 0][abj.vops[a]][abj.vops[b]]; | |||||
| abj.vops[a] = new_state[1]; | |||||
| abj.vops[b] = new_state[2]; | |||||
| if (new_state[0] != edge) { | if (new_state[0] != edge) { | ||||
| toggle_edge(a, b); | toggle_edge(a, b); | ||||
| } | } | ||||
| @@ -108,8 +102,8 @@ abj.act_cz = function(a, b) { | |||||
| abj.edgelist = function() { | abj.edgelist = function() { | ||||
| var seen = {}; | var seen = {}; | ||||
| var output = []; | var output = []; | ||||
| for (var i in ngbh) { | |||||
| for (var j in ngbh[i]) { | |||||
| for (var i in abj.ngbh) { | |||||
| for (var j in abj.ngbh[i]) { | |||||
| if (!Object.prototype.hasOwnProperty.call(seen, j)) { | if (!Object.prototype.hasOwnProperty.call(seen, j)) { | ||||
| output.push([i, j]); | output.push([i, j]); | ||||
| } | } | ||||
| @@ -120,7 +114,7 @@ abj.edgelist = function() { | |||||
| }; | }; | ||||
| abj.log_graph_state = function() { | abj.log_graph_state = function() { | ||||
| console.log(JSON.stringify(vops)); | |||||
| console.log(JSON.stringify(ngbh)); | |||||
| console.log(JSON.stringify(abj.vops)); | |||||
| console.log(JSON.stringify(abj.ngbh)); | |||||
| }; | }; | ||||
| @@ -7,24 +7,25 @@ graph.hook = function() { | |||||
| }; | }; | ||||
| graph.update = function(json) { | graph.update = function(json) { | ||||
| anders_briegel.vops = json.vops; | |||||
| anders_briegel.ngbh = json.ngbh; | |||||
| anders_briegel.meta = json.meta; | |||||
| abj.vops = json.vops; | |||||
| abj.ngbh = json.ngbh; | |||||
| abj.meta = json.meta; | |||||
| graph.updateScene(); | graph.updateScene(); | ||||
| }; | }; | ||||
| graph.updateScene = function() { | graph.updateScene = function() { | ||||
| var oldState = scene.getObjectByName("graphstate"); | |||||
| scene.remove(oldState); | |||||
| oldState = null; | |||||
| if (graph.object){gui.scene.remove(graph.object);} | |||||
| graph.object = null; | |||||
| console.log("update"); | |||||
| var geometry = new THREE.Geometry(); | var geometry = new THREE.Geometry(); | ||||
| geometry.colors = []; | |||||
| for (var i in abj.vops) { | for (var i in abj.vops) { | ||||
| var vop = abj.vops[i]; | var vop = abj.vops[i]; | ||||
| var pos = abj.meta[i].position; | var pos = abj.meta[i].position; | ||||
| var vertex = new THREE.Vector3(pos.x, pos.y, pos.z); | var vertex = new THREE.Vector3(pos.x, pos.y, pos.z); | ||||
| geometry.vertices.push(vertex); | geometry.vertices.push(vertex); | ||||
| geometry.colors[i] = new THREE.Color(colors[abj.vops[i] % colors.length]); | |||||
| geometry.colors.push(new THREE.Color(graph.colors[abj.vops[i] % graph.colors.length])); | |||||
| } | } | ||||
| var edges = new THREE.Object3D(); | var edges = new THREE.Object3D(); | ||||
| @@ -32,18 +33,18 @@ graph.updateScene = function() { | |||||
| for (i = 0; i < my_edges.length; ++i) { | for (i = 0; i < my_edges.length; ++i) { | ||||
| var edge = my_edges[i]; | var edge = my_edges[i]; | ||||
| var start = abj.meta[edge[0]].position; | var start = abj.meta[edge[0]].position; | ||||
| var startpos = new THREE.Vector3(start[0], start[1], start[2]); | |||||
| var startpos = new THREE.Vector3(start.x, start.y, start.z); | |||||
| var end = abj.meta[edge[1]].position; | var end = abj.meta[edge[1]].position; | ||||
| var endpos = new THREE.Vector3(end[0], end[1], end[2]); | |||||
| var newEdge = makeCurve(startpos, endpos); | |||||
| var endpos = new THREE.Vector3(end.x, end.y, end.z); | |||||
| var newEdge = materials.makeCurve(startpos, endpos); | |||||
| edges.add(newEdge); | edges.add(newEdge); | ||||
| } | } | ||||
| var particles = new THREE.Points(geometry, materials.qubit); | var particles = new THREE.Points(geometry, materials.qubit); | ||||
| var newState = new THREE.Object3D(); | |||||
| newState.name = "graphstate"; | |||||
| newState.add(particles); | |||||
| newState.add(edges); | |||||
| scene.add(newState); | |||||
| render(); | |||||
| graph.object = new THREE.Object3D(); | |||||
| graph.object.name = "graphstate"; | |||||
| graph.object.add(particles); | |||||
| graph.object.add(edges); | |||||
| gui.scene.add(graph.object); | |||||
| gui.render(); | |||||
| }; | }; | ||||
| @@ -1,6 +1,8 @@ | |||||
| var gui = {}; | var gui = {}; | ||||
| gui.construct = function() { | gui.construct = function() { | ||||
| gui.renderer = new THREE.WebGLRenderer(); | |||||
| gui.renderer = new THREE.WebGLRenderer({ | |||||
| "antialias": true | |||||
| }); | |||||
| gui.renderer.setSize(window.innerWidth, window.innerHeight); | gui.renderer.setSize(window.innerWidth, window.innerHeight); | ||||
| gui.renderer.setClearColor(0xffffff, 1); | gui.renderer.setClearColor(0xffffff, 1); | ||||
| document.querySelector("body").appendChild(gui.renderer.domElement); | document.querySelector("body").appendChild(gui.renderer.domElement); | ||||
| @@ -10,10 +12,10 @@ gui.construct = function() { | |||||
| gui.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.3, 1000); | gui.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.3, 1000); | ||||
| gui.controls = new THREE.OrbitControls(gui.camera); | gui.controls = new THREE.OrbitControls(gui.camera); | ||||
| gui.controls.addEventListener("change", gui.render); | |||||
| gui.controls.center.set(0, 0, 0); | gui.controls.center.set(0, 0, 0); | ||||
| gui.controls.rotateSpeed = 0.2; | gui.controls.rotateSpeed = 0.2; | ||||
| gui.camera.position.set(0, 0, 20); | gui.camera.position.set(0, 0, 20); | ||||
| gui.controls.addEventListener("change", gui.render); | |||||
| }; | }; | ||||
| // Someone resized the window | // Someone resized the window | ||||
| @@ -27,8 +29,9 @@ gui.onWindowResize = function(evt) { | |||||
| // Render the current frame to the screen | // Render the current frame to the screen | ||||
| gui.render = function() { | gui.render = function() { | ||||
| console.log("render"); | |||||
| gui.renderer.render(gui.scene, gui.camera); | |||||
| requestAnimationFrame(function() { | |||||
| gui.renderer.render(gui.scene, gui.camera); | |||||
| }); | |||||
| }; | }; | ||||
| // Make the extra bits of gui | // Make the extra bits of gui | ||||
| @@ -41,8 +44,25 @@ gui.makeScene = function() { | |||||
| }; | }; | ||||
| // Put an HTML message to the screen | // Put an HTML message to the screen | ||||
| gui.serverMessage = function(msgtext){ | |||||
| gui.serverMessage = function(msgtext) { | |||||
| message.innerHTML = msgtext; | message.innerHTML = msgtext; | ||||
| message.className = "visible"; | message.className = "visible"; | ||||
| }; | }; | ||||
| gui.loop = function() { | |||||
| gui.controls.update(); | |||||
| requestAnimationFrame(gui.loop); | |||||
| } | |||||
| // Try to add a qubit at the current mouse position | |||||
| gui.addQubitAtMouse = function(event) { | |||||
| this.raycaster.setFromCamera(mouse, camera); | |||||
| var intersection = this.raycaster.ray.intersectPlane(this.plane); | |||||
| intersection.x = Math.round(intersection.x); | |||||
| intersection.y = Math.round(intersection.y); | |||||
| abj.add_node(Object.keys(vops).length, { | |||||
| "position": intersection | |||||
| }); | |||||
| graph.updateScene(); | |||||
| } | |||||
| @@ -1,5 +1,6 @@ | |||||
| window.onload = function() { | window.onload = function() { | ||||
| graph.hook(); | graph.hook(); | ||||
| materials.load(); | |||||
| gui.construct(); | gui.construct(); | ||||
| gui.render(); | |||||
| gui.loop(); | |||||
| }; | }; | ||||
| @@ -1,38 +1,32 @@ | |||||
| var materials = {}; | var materials = {}; | ||||
| materials.textures = { | |||||
| sprite: new THREE.Texture() | |||||
| }; | |||||
| materials.load = function() { | |||||
| materials.textures.sprite = new THREE.Texture(document.getElementById("ball")); | |||||
| materials.textures.sprite.needsUpdate = true; | |||||
| var curveProperties = { | |||||
| splineDensity: 8, | |||||
| curvature: 20 | |||||
| }; | }; | ||||
| materials.curveProperties = { | |||||
| splineDensity: 10, | |||||
| curvature: 100 | |||||
| }; | |||||
| materials.materials = { | |||||
| edge: new THREE.LineBasicMaterial({ | |||||
| materials.load = function() { | |||||
| var sprite = new THREE.Texture(document.getElementById("ball")); | |||||
| sprite.needsUpdate = true; | |||||
| materials.edge = new THREE.LineBasicMaterial({ | |||||
| color: "gray", | color: "gray", | ||||
| transparent: false, | transparent: false, | ||||
| linewidth: 1 | linewidth: 1 | ||||
| }), | |||||
| point: new THREE.PointsMaterial({ | |||||
| }); | |||||
| materials.point = new THREE.PointsMaterial({ | |||||
| size: 0.1, | size: 0.1, | ||||
| map: materials.textures.sprite, | |||||
| map: sprite, | |||||
| alphaTest: 0.5, | alphaTest: 0.5, | ||||
| transparent: true, | transparent: true, | ||||
| vertexColors: THREE.VertexColors | vertexColors: THREE.VertexColors | ||||
| }), | |||||
| qubit: qubit = new THREE.PointsMaterial({ | |||||
| size: 0.8, | |||||
| map: materials.textures.sprite, | |||||
| }); | |||||
| materials.qubit = new THREE.PointsMaterial({ | |||||
| size: 0.3, | |||||
| map: sprite, | |||||
| alphaTest: 0.5, | alphaTest: 0.5, | ||||
| transparent: true, | transparent: true, | ||||
| vertexColors: THREE.VertexColors | vertexColors: THREE.VertexColors | ||||
| }) | |||||
| }); | |||||
| }; | }; | ||||
| materials.makeCurve = function(a, b) { | materials.makeCurve = function(a, b) { | ||||
| @@ -43,6 +37,6 @@ materials.makeCurve = function(a, b) { | |||||
| var geometry = new THREE.Geometry(); | var geometry = new THREE.Geometry(); | ||||
| var splinePoints = spline.getPoints(curveProperties.splineDensity); | var splinePoints = spline.getPoints(curveProperties.splineDensity); | ||||
| Array.prototype.push.apply(geometry.vertices, splinePoints); | Array.prototype.push.apply(geometry.vertices, splinePoints); | ||||
| return new THREE.Line(geometry, materials.materials.edge); | |||||
| return new THREE.Line(geometry, materials.edge); | |||||
| }; | }; | ||||
| @@ -224,6 +224,7 @@ THREE.OrbitControls = function ( object, domElement ) { | |||||
| if ( scope.enabled === false ) return; | if ( scope.enabled === false ) return; | ||||
| if ( scope.userRotate === false ) return; | if ( scope.userRotate === false ) return; | ||||
| event.preventDefault(); | event.preventDefault(); | ||||
| if ( state === STATE.NONE ) | if ( state === STATE.NONE ) | ||||
| @@ -19,7 +19,7 @@ websocket.connect = function(update){ | |||||
| ws.onclose = function(evt) | ws.onclose = function(evt) | ||||
| { | { | ||||
| gui.serverMessage("Connection to server lost. <a href='#' onclick='javascript:connect_to_server()'>Reconnect</a>."); | |||||
| gui.serverMessage("Connection to server lost. <a href='#' onclick='javascript:websocket.connect()'>Reconnect</a>."); | |||||
| }; | }; | ||||
| }; | }; | ||||