Browse Source

Lattice example

master
Pete Shadbolt 8 years ago
parent
commit
37913a4b2c
9 changed files with 124 additions and 76 deletions
  1. +37
    -0
      examples/lattice_demo.py
  2. +1
    -1
      examples/visualization_demo.py
  3. +24
    -30
      static/scripts/anders_briegel.js
  4. +17
    -16
      static/scripts/graph.js
  5. +25
    -5
      static/scripts/gui.js
  6. +2
    -1
      static/scripts/main.js
  7. +16
    -22
      static/scripts/materials.js
  8. +1
    -0
      static/scripts/orbitcontrols.js
  9. +1
    -1
      static/scripts/websocket.js

+ 37
- 0
examples/lattice_demo.py View File

@@ -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]))



+ 1
- 1
examples/visualization_demo.py View File

@@ -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)


+ 24
- 30
static/scripts/anders_briegel.js View File

@@ -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));
}; };



+ 17
- 16
static/scripts/graph.js View File

@@ -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();
}; };

+ 25
- 5
static/scripts/gui.js View File

@@ -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();
}


+ 2
- 1
static/scripts/main.js View File

@@ -1,5 +1,6 @@
window.onload = function() { window.onload = function() {
graph.hook(); graph.hook();
materials.load();
gui.construct(); gui.construct();
gui.render();
gui.loop();
}; };

+ 16
- 22
static/scripts/materials.js View File

@@ -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);
}; };



+ 1
- 0
static/scripts/orbitcontrols.js View File

@@ -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 )


+ 1
- 1
static/scripts/websocket.js View File

@@ -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>.");
}; };
}; };




Loading…
Cancel
Save