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):
x = 10*np.cos(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")
for i in range(200-1):
s.act_cz(i, i+1)


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

@@ -1,15 +1,9 @@
var abj = {};
abj.ngbh = {};
abj.vops = {};
abj.meta = {};
ngbh = abj.ngbh;
vops = abj.vops;
meta = abj.meta;

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) {
@@ -17,8 +11,8 @@ abj.add_nodes = function(nodes) {
};

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) {
@@ -28,12 +22,12 @@ abj.add_edges = function(edges) {
};

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) {
return Object.prototype.hasOwnProperty.call(ngbh[a], b);
return Object.prototype.hasOwnProperty.call(abj.ngbh[a], b);
};

abj.toggle_edge = function(a, b) {
@@ -45,7 +39,7 @@ abj.toggle_edge = function(a, b) {
};

abj.get_swap = function(node, avoid) {
for (var i in ngbh[node]) {
for (var i in abj.ngbh[node]) {
if (i != avoid) {
return i;
}
@@ -55,7 +49,7 @@ abj.get_swap = function(node, avoid) {

abj.remove_vop = function(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) {
var v = decomposition[i];
local_complementation(v == "x" ? a : swap_qubit);
@@ -63,19 +57,19 @@ abj.remove_vop = function(node, avoid) {
};

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 j = i + 1; j < keys.length; ++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) {
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) {
@@ -87,19 +81,19 @@ abj.is_sole_member = function(node, group) {
};

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);
}
if (is_sole_member(ngbh[b], a)) {
if (is_sole_member(abj.ngbh[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);
}
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) {
toggle_edge(a, b);
}
@@ -108,8 +102,8 @@ abj.act_cz = function(a, b) {
abj.edgelist = function() {
var seen = {};
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)) {
output.push([i, j]);
}
@@ -120,7 +114,7 @@ abj.edgelist = 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) {
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 = 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();
geometry.colors = [];
for (var i in abj.vops) {
var vop = abj.vops[i];
var pos = abj.meta[i].position;
var vertex = new THREE.Vector3(pos.x, pos.y, pos.z);
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();
@@ -32,18 +33,18 @@ graph.updateScene = function() {
for (i = 0; i < my_edges.length; ++i) {
var edge = my_edges[i];
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 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);
}

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 = {};
gui.construct = function() {
gui.renderer = new THREE.WebGLRenderer();
gui.renderer = new THREE.WebGLRenderer({
"antialias": true
});
gui.renderer.setSize(window.innerWidth, window.innerHeight);
gui.renderer.setClearColor(0xffffff, 1);
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.controls = new THREE.OrbitControls(gui.camera);
gui.controls.addEventListener("change", gui.render);
gui.controls.center.set(0, 0, 0);
gui.controls.rotateSpeed = 0.2;
gui.camera.position.set(0, 0, 20);
gui.controls.addEventListener("change", gui.render);
};

// Someone resized the window
@@ -27,8 +29,9 @@ gui.onWindowResize = function(evt) {

// Render the current frame to the screen
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
@@ -41,8 +44,25 @@ gui.makeScene = function() {
};

// Put an HTML message to the screen
gui.serverMessage = function(msgtext){
gui.serverMessage = function(msgtext) {
message.innerHTML = msgtext;
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() {
graph.hook();
materials.load();
gui.construct();
gui.render();
gui.loop();
};

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

@@ -1,38 +1,32 @@
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",
transparent: false,
linewidth: 1
}),
point: new THREE.PointsMaterial({
});
materials.point = new THREE.PointsMaterial({
size: 0.1,
map: materials.textures.sprite,
map: sprite,
alphaTest: 0.5,
transparent: true,
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,
transparent: true,
vertexColors: THREE.VertexColors
})
});
};

materials.makeCurve = function(a, b) {
@@ -43,6 +37,6 @@ materials.makeCurve = function(a, b) {
var geometry = new THREE.Geometry();
var splinePoints = spline.getPoints(curveProperties.splineDensity);
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.userRotate === false ) return;


event.preventDefault();

if ( state === STATE.NONE )


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

@@ -19,7 +19,7 @@ websocket.connect = function(update){
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