Design and Implementation of Metrized Graph Caculation Functions, ``laplacian.mpl''
Philip Zeyliger
July 10, 2003
Abstract: we discuss each of the functions within laplacian.mpl, covering their usage and showing an example. We also briefly mention the mathematics behind the functions and caveats about their implementation in Maple.
Introduction and Getting Started
The procedures in laplacian.mpl are meant to get numerically acquainted with several of the notions on metrized graphs that we developed during the course of the VIGRE REU program at UGA in June-July 2003.
To use the functions, you first need to load up "laplacian.mpl", which is typically done like so:
| > | read("laplacian.mpl"); |
There is also a file called "laplacian-retired.mpl". This contains functions that were formerly useful but have been superceded. It is left purely as a curiosity and is largely undocumented.
Graph Generation and Manipulation
Please refer to "networks-guide.mpl" for help on how to create graphs. ``laplacian.mpl'' provides a few functions that generate certain graphs. The implementation is in all cases straight-forward. Typically a graph is created and then for loops are used to generate the vertices and the edges.
banana, banana2
| > | G:=banana2(3): draw(Linear([3,4,5]),G); |
star
| > | G:=star(3): draw3d(G); |
bouquet / flower , bouquet2 / flower2
| > | G:=bouquet2(2): draw3d(G); |
hypercube
| > | G:=hypercube(2): draw(Linear([0,1]),G); |
| > | G:=hypercube(3): draw3d(G); |
supercirc
| > | G:=supercirc(5): draw(G); |
| > | draw3d(G); |
| > | evalf(tau(G)); |
The following functions do basic manipulations on graphs. It is important to note that they change the graph given to them.
normalize
| > | G:=complete(4): eweight(G)[e1]:=3: # change one of the default weights print(`Originally:` ,eweight(G)); normalize(G): print(`Normalized:`,eweight(G)); |
subdividegraph, subdivideedge
| > | G:=star(3): draw(G); subdivideedge(e1,G,3): draw3d(G); G:=star(3):subdividegraph(G,3): draw(Linear([v2,v3,2],[1,v4,v5,3],[v6,v7,4]),G); |
identifyedge
| > | G:=cycle(4): draw(G); identifyedge(e1,G): draw(G); G:=cycle(4): contract(e1,G): # the same thing, but built-in draw(G); |
assigndirections
| > | G:=complete(3): ends(G); assigndirections(G): ends(G); |
Calculations - The Discrete Laplacian, Resistances and Measures
Many of the calculations we are interested in involve calculating effective resistances between vertices. An easy way to do this is to use the discrete laplacian
laplacian
| > | G:=cycle(3): eweight(G)[e1]:=2: # change a default weight laplacian(G); laplacian(G,foobar); |
| > | laplacian(graph({1},{{1,1}})); # a self-looping graph |
Error, (in laplacian) Laplacian dont make no sense with self-loops
effresistance, resistancevec
| > | G:=petersen(): effresistance(G,1,2), effresistance(G,1,2,laplacian(G)); |
| > | G:=graph({1,2,3,4},{{1,2},{2,3}}): resistancevec(G,1); |
canonical
| > | G:=cycle(3): canonical(G),canonical(G,2),canonical(G,3); |
canonicalcts
| > | G:=cycle(3): canonicalcts(G); G:=star(3): canonicalcts(G); |
dxmeasure, IDeltaX
| > | G:=cycle(3): dxmeasure(G), IDeltaX(G); G:=star(3): # produces a normalized star dxmeasure(G); |
Discrete Approximations for the Eigenvalues
The function ``eigs'' is the main point of this file. It calculates the eigenvalues of the laplacian, under an arbitrary measure, numerically. We have conjectured (and proved, for certain measures) that as we increase the number of subdivisions, the values here approach the continuous values.
eigs
| > | G:=star(3): eigs(G,dxmeasure,16)[1..8]; # only print out the first 8 |
| > | eigs(G,canonical,16)[1..8]; # only print out the first 8 |
| > | infolevel[LinearAlgebra]:=2: eigs(G,dxmeasure,4); infolevel[LinearAlgebra]:=0: |
Transpose: "calling external function"
HermitianTranspose: hw_MatTransRR
MatrixMatrixMultiply: "calling external function"
MatrixMatrixMultiply: "NAG" hw_f06yaf
MatrixScalarMultiply: "calling external function"
MatrixScalarMultiply: "NAG" hw_f06edf
MatrixScalarMultiply: "calling external function"
MatrixScalarMultiply: "NAG" hw_f06edf
MatrixAdd: "calling external function"
MatrixAdd: "NAG" hw_f06ecf
MatrixMatrixMultiply: "calling external function"
MatrixMatrixMultiply: "NAG" hw_f06yaf
MatrixMatrixMultiply: "calling external function"
MatrixMatrixMultiply: "NAG" hw_f06yaf
MatrixMatrixMultiply: "copying first Matrix to enable external call"
MatrixMatrixMultiply: "calling external function"
MatrixMatrixMultiply: "NAG" hw_f06yaf
MatrixMatrixMultiply: "calling external function"
MatrixMatrixMultiply: "NAG" hw_f06yaf
MatrixInverse: "calling external function"
MatrixInverse: "NAG" hw_f07adf
MatrixInverse: "NAG" hw_f07ajf
MatrixMatrixMultiply: "calling external function"
MatrixMatrixMultiply: "NAG" hw_f06yaf
Eigenvalues: "calling external function"
Eigenvalues: "CLAPACK" hw_dgeevx_
The Tau Constant
tau
| > | G:=cycle(12): tau(G),tau(G,nonormalize); |
taushorten
| > | G:=complete(4): m:=taushorten(G,e1,30); plot([seq([i,m[i]],i=1..30)]); |
| > | G:=complete(4): m:=taushorten(G,e1,30,donormalize); plot([seq([i,m[i]],i=1..30)]); |
Helper Functions
vname
| > | G:=complete(4): vertices(G); addvertex(vname(G),G); vertices(G); addvertex(vname(G),G); vertices(G); |
Spreadsheet Generation
A word of warning--Maple's spreadsheet interface is cool, but it acts buggy. We've had a lot of trouble using these things. It is imperative that you do "with(Spread)" first and then read-in the laplacian.mpl functions.
makeeigspread, graphspread
| > | with(Spread): G:=cycle(3): ssid1:=CreateSpreadsheet(): ssid2:=CreateSpreadsheet(): graphspread(G,ssid1,ssid2); |
General Implementation Notes (and Bugs)