During my PhD I always wanted to have an interactive way of plotting a nice
looking Bethe Lattice
and particular to my work a Dimer Bethe
lattice. Because this visualization wasn’t an essential part of my research
I never investigated into it. It is enough to draw them on paper for any
practical purpose. I was then confronted with my PhD oral presentation,
great opportunity to procrastinate and get the nice unessential plots
done. They didn’t end in the final version of the presentation(again is not
the fundamental part of my work), but I wanted to share them anyway.
I first found this project vis.js
for browser based visualization, which
has an entire section of examples dedicated to drawing networks. That is
all I need. Doing things on the browser is great, it allows to publish many
documents with user interactivity, which then can be openly shared as a
webpage instead of a PDF document or other presentation files. With
vis.js being able to plot networks the only task left is to find the good
algorithm that solves the generation of the lattice problem.
Returning to JavaScript
The language of the web. Good that is a simple language, bad that is a
simple language. I haven’t programmed in JavaScript in years(I was probably
still in high school that time), other languages like PHP, C++, Python took
over. But programming is one thing, the language syntax is another, so
working again on JavaScript wasn’t to much of a problem.
The logic of vis.js to draw a network is that it takes a list of nodes
and a list of edges, so I just need to generate them. A recursive algorithm
was to me the most intuitive way to describe the Bethe Lattice
, which is a
connected cycle-free graph where each node is connected to a certain number
of neighbors. In the end it is just a tree. I just need a function that
creates a node, links that node to a head and then calls the function again
for the amount of remaining neighbors the node has.
The Bethe Lattice
This algorithm lets itself be expressed by the following code:
1functiongen_Bethe(generations,neighbors){ 2varnodes=[]; 3varedges=[]; 4varcounter=-1; 5 6// Recursive function to create a new node and call itself to generate
7// the branches(subtree) structure of the graph
8functiontree(level,neighbors,head){ 9counter++;10nodes.push({11id:counter,12label:String(counter),13group:level14});15varcurrent_node=counter;16if(head!=current_node){17edges.push({18from:head,19to:current_node20});21}2223if(level==0){24return0;25}2627varchilds=neighbors-1;28// Only the first/central node is special. For the recursive call
29// it has all neighbors
30if(current_node==0){31childs=neighbors;32}3334varlow=level-1;35for(vari=0;i<childs;i++){36tree(low,neighbors,current_node);37}3839return0;40}4142tree(generations,neighbors,0);4344return{45nodes:nodes,46edges:edges47};48}
There are maybe better ways to solve this in JavaScript, I don’t know. The
reduced amount of code makes me happy about it. The little amount of code
does not reflect the amount of time I spent trying to make this work. I
save it in a file /js/bethe_lattice_generator.js to be able to use it
later.
In the head of the webpage I’ll import the vis.js JavaScript and CSS
modules. Then I import the file with the previous algorithm to the bethe
lattice and define a CSS #id to contain the plot.
The next JavaScript section goes also in the webpage, it declares how
vis.js is to be used to draw the lattice. I need to setup variables of
nodes, edges, network (that is the lattice), and configuration
options.
1<scripttype="text/javascript"> 2varnodes=null; 3varedges=null; 4varnetwork=null; 5varsetSmooth=true; 6 7// cleans the canvas where the lattice is plotted
8functiondestroy(net){ 9if(net!==null){10net.destroy();11net=null;12}13}1415functiondraw_bethe(level,neighbors){16destroy(network);17// create a network
18level=(typeoflevel=='number')?level:2;19neighbors=(typeofneighbors=='number')?neighbors:3;20varcontainer=document.getElementById('bethe-lattice');21vardata=gen_Bethe(level,neighbors);22varoptions={23physics:{stabilization:false}24};25network=newvis.Network(container,data,options);26}27</script>
Finally, in the content of the website I embed the HTML where to draw the
Bethe Lattice and propose some options of configurations.
The can be understood as the Bethe lattice but placing two closely
connected nodes at each place where the original Bethe lattice only has one
node. An alternative view of it is to think of two independent Bethe
lattices that are placed side by side and coupled at each node.
When extending the previous algorithm to plot the dimer lattice I’ll join
both views. I start generating the Bethe lattice, but for each node I
generate I immediately create its neighbor and link them to compose the
dimer. In that way I build the second lattice at the same time.
1functiongen_dimerBethe(generations,neighbors){ 2varnodes=[]; 3varedges=[]; 4varcounter=-1; 5 6functiontree(level,neighbors,head){ 7counter++; 8varcurrent_node=counter; 9// first node
10nodes.push({11id:counter,12label:String(counter),13group:2014});15// second node
16counter++;17nodes.push({18id:counter,19label:String(counter),20group:10021});22// link the two nodes to build the dimer
23edges.push({24from:counter-1,25to:counter,26dashes:true27});2829if(head!=current_node){30edges.push({from:head,to:current_node,arrows:'to'});31// The second lattice
32edges.push({from:head+1,to:current_node+1,arrows:'to'});33}343536if(level==0){37return0;38}3940varchilds=neighbors-1;41if(current_node==0){42childs=neighbors;43}4445varlow=level-1;46for(vari=0;i<childs;i++){47tree(low,neighbors,current_node);48}4950return0;51}5253tree(generations,neighbors,0);5455return{56nodes:nodes,57edges:edges58};59}
Setting up vis.js is the same as in the previous section,
1<styletype="text/css"> 2#dimer-bethe-lattice{ 3height:450px; 4border:1pxsolidlightgray; 5align:center; 6} 7</style> 8 9<scripttype="text/javascript">10varnodes=null;11varedges=null;12varsetSmooth=true;13varnetwork_dimer=null;14functiondraw_dimer_bethe(level,neighbors){15destroy(network_dimer);16// create a network
17level=(typeoflevel=='number')?level:2;18neighbors=(typeofneighbors=='number')?neighbors:3;19varcontainer=document.getElementById('dimer-bethe-lattice');20vardata=gen_dimerBethe(level,neighbors);21varoptions={22physics:{stabilization:false}23};24network_dimer=newvis.Network(container,data,options);25}2627// This draws the default lattices on window load
28window.onload=function(){draw_bethe();draw_dimer_bethe();};29</script>
As a scientist I studied the physics of the very small quantum world. As a computer hacker I distill code. Software is eating the world, and less code means less errors, less problems. Millions of lines of legacy code demand attention and have to be understood and simplified for future reliable operation.