# wiki

name: GraphToolGuide
author: count0
ipnr: 201.51.129.119
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "{{{--load}}}" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in {{{.xml}}} are considered graphml files, and files ending in {{{.dot}}} are considered dot files. Files can also end in {{{.gz}}} or {{{.bz2}}} to indicate compression, such as {{{.xml.gz}}} or {{{.dot.bz2}}}. Files can be saved with the "{{{--save}}}" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property (which will be called "weight"):
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are done in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifiyng the option "{{{--undirected}}}" before "{{{--load}}}". Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understants the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performace for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in [[ref(File Format Description)]] is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any vertex scalar property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with {{{.gz}}} or {{{.bz2}}} for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (henceforth referred to as {{{multi-comp.dot}}}):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are therefore of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as directed with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space. Here's an example using the graph defined in [[ref(File Format Description)]]:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file {{{filtered.dot}}} contains (representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to {{{True}}} the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performace note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as unfiltered to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indices ===

  Vertices and Edges are identified internally by indices. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges ramain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacenty matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a filename. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an aternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a filename. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferencially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option "`--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      -0.230769230769
  }}}

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and $N_c$ is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as paramenter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  --------

  == Layout ==
      --compute-spring-block-layout=ITERATIONS[|SEED]                           compute the spring block layout
      --compute-gursoy-atun-layout=ITERATIONS[|SEED]                            compute the Gursoy-Atun layout


  == Random Graph Generation ==

  TODO

  == Graph History ==

      --history=INIT|CONDITION|STEP                                             compute graph history
      --history-rate=TIME  


name: GraphToolGuide
author: anonymous
ipnr: 201.51.139.16
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "{{{--load}}}" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in {{{.xml}}} are considered graphml files, and files ending in {{{.dot}}} are considered dot files. Files can also end in {{{.gz}}} or {{{.bz2}}} to indicate compression, such as {{{.xml.gz}}} or {{{.dot.bz2}}}. Files can be saved with the "{{{--save}}}" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property (which will be called "weight"):
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are done in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifiyng the option "{{{--undirected}}}" before "{{{--load}}}". Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understants the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performace for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in [[ref(File Format Description)]] is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any vertex scalar property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with {{{.gz}}} or {{{.bz2}}} for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (henceforth referred to as {{{multi-comp.dot}}}):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are therefore of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as directed with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space. Here's an example using the graph defined in [[ref(File Format Description)]]:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file {{{filtered.dot}}} contains (representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to {{{True}}} the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performace note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as unfiltered to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indices ===

  Vertices and Edges are identified internally by indices. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges ramain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacenty matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a filename. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an aternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a filename. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferencially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option "`--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      -0.230769230769
  }}}

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as paramenter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

      --history=INIT|CONDITION|STEP                                             compute graph history
      --history-rate=TIME  


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "{{{--load}}}" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in {{{.xml}}} are considered graphml files, and files ending in {{{.dot}}} are considered dot files. Files can also end in {{{.gz}}} or {{{.bz2}}} to indicate compression, such as {{{.xml.gz}}} or {{{.dot.bz2}}}. Files can be saved with the "{{{--save}}}" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property (which will be called "weight"):
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are done in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifiyng the option "{{{--undirected}}}" before "{{{--load}}}". Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understants the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performace for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in [[ref(File Format Description)]] is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any vertex scalar property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with {{{.gz}}} or {{{.bz2}}} for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (henceforth referred to as {{{multi-comp.dot}}}):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are therefore of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as directed with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space. Here's an example using the graph defined in [[ref(File Format Description)]]:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file {{{filtered.dot}}} contains (representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to {{{True}}} the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performace note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as unfiltered to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indices ===

  Vertices and Edges are identified internally by indices. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges ramain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacenty matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a filename. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an aternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a filename. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferencially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option "`--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      -0.230769230769
  }}}

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as paramenter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is therefore iteresting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which functions just like a `for` loop: the initial statement, a condition to be checked either iteration, and a step statement. The variables defined and modified in the paramenters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's and edge property calles time which goes from 1 to 8. So in order to calculate the number of edges and, for instance, the degree distribution over time, one could do the following:


      --history=INIT|CONDITION|STEP                                             compute graph history
      --history-rate=TIME  


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "{{{--load}}}" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in {{{.xml}}} are considered graphml files, and files ending in {{{.dot}}} are considered dot files. Files can also end in {{{.gz}}} or {{{.bz2}}} to indicate compression, such as {{{.xml.gz}}} or {{{.dot.bz2}}}. Files can be saved with the "{{{--save}}}" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property (which will be called "weight"):
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are done in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifiyng the option "{{{--undirected}}}" before "{{{--load}}}". Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understants the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performace for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in [[ref(File Format Description)]] is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any vertex scalar property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with {{{.gz}}} or {{{.bz2}}} for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (henceforth referred to as {{{multi-comp.dot}}}):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are therefore of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as directed with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space. Here's an example using the graph defined in [[ref(File Format Description)]]:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file {{{filtered.dot}}} contains (representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to {{{True}}} the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performace note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as unfiltered to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indices ===

  Vertices and Edges are identified internally by indices. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges ramain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacenty matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a filename. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an aternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a filename. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferencially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option "`--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      -0.230769230769
  }}}

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as paramenter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is therefore iteresting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which functions just like a `for` loop: the initial statement, a condition to be checked either iteration, and a step statement. The variables defined and modified in the paramenters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's and edge property calles time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the following options by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number. In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`", which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "{{{--load}}}" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in {{{.xml}}} are considered graphml files, and files ending in {{{.dot}}} are considered dot files. Files can also end in {{{.gz}}} or {{{.bz2}}} to indicate compression, such as {{{.xml.gz}}} or {{{.dot.bz2}}}. Files can be saved with the "{{{--save}}}" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property (which will be called "weight"):
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are done in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifiyng the option "{{{--undirected}}}" before "{{{--load}}}". Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understants the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performace for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in [[ref(File Format Description)]] is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any vertex scalar property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with {{{.gz}}} or {{{.bz2}}} for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (henceforth referred to as {{{multi-comp.dot}}}):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are therefore of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as directed with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space. Here's an example using the graph defined in [[ref(File Format Description)]]:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file {{{filtered.dot}}} contains (representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to {{{True}}} the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performace note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as unfiltered to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indices ===

  Vertices and Edges are identified internally by indices. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges ramain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacenty matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a filename. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an aternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a filename. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any vertex scalar property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferencially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option "`--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      -0.230769230769
  }}}

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as paramenter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is therefore iteresting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which functions just like a "`for` loop": the initial statement, a condition to be checked every iteration, and a step statement. The variables defined and modified in the paramenters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's and edge property calles time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the following options by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number. In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`", which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "`--load`" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in "`.xml`" are considered graphml files, and files ending in "`.dot`" are considered dot files. Files can also end in "`.gz`" or "`.bz2`" to indicate compression, such as "`.xml.gz`" or "`.dot.bz2`". Files can be saved with the "`--save`" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property called "weight":
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are specified in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifying the option "`--undirected`" before "`--load`" (see [[ref(Directedness)]] for details). Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understands the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performance for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in the [[ref(File Format Description)]] section is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any scalar vertex property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with "{{{.gz}}}" or "{{{.bz2}}}" for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{--component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (called "{{{multi-comp.dot}}}"):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph as if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as undirected with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode. If you want to load an undirected graph with graph-tool, just use the "{{{--undirected}}}" option before the "{{{--load}}}" option.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space). Here's an example using the graph defined in the [[ref(File Format Description)]] section:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file "{{{filtered.dot}}}" contains (graphical representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to "{{{True}}}" the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performance note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as an unfiltered graph to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indexes ===

  Vertices and Edges are identified internally by indexes. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges remain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacency matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a file name. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an alternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a file name. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferentially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option "`--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      -0.230769230769
  }}}

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as parameter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is often interesting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which function just like a "`for` loop": the initial statement, a condition to be checked every iteration, and a step statement. The variables defined and modified in the parameters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's an edge property called time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the options that follow it by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number (not the variable(s) used in the "`--history`" option). In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph. The syntax of the history specification is any valid [http://www.python.org python] statement.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones, otherwise they'll still contain old information.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`" option, which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "`--load`" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in "`.xml`" are considered graphml files, and files ending in "`.dot`" are considered dot files. Files can also end in "`.gz`" or "`.bz2`" to indicate compression, such as "`.xml.gz`" or "`.dot.bz2`". Files can be saved with the "`--save`" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property called "weight":
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are specified in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifying the option "`--undirected`" before "`--load`" (see [[ref(Directedness)]] for details). Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understands the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performance for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in the [[ref(File Format Description)]] section is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any scalar vertex property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with "{{{.gz}}}" or "{{{.bz2}}}" for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{--component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (called "{{{multi-comp.dot}}}"):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph as if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as undirected with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode. If you want to load an undirected graph with graph-tool, just use the "{{{--undirected}}}" option before the "{{{--load}}}" option.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space). Here's an example using the graph defined in the [[ref(File Format Description)]] section:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file "{{{filtered.dot}}}" contains (graphical representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to "{{{True}}}" the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performance note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as an unfiltered graph to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indexes ===

  Vertices and Edges are identified internally by indexes. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges remain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacency matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a file name. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an alternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a file name. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferentially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option "`--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      -0.230769230769
  }}}

  -------

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as parameter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is often interesting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which function just like a "`for` loop": the initial statement, a condition to be checked every iteration, and a step statement. The variables defined and modified in the parameters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's an edge property called time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the options that follow it by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number (not the variable(s) used in the "`--history`" option). In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph. The syntax of the history specification is any valid [http://www.python.org python] statement.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones, otherwise they'll still contain old information.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`" option, which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "`--load`" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in "`.xml`" are considered graphml files, and files ending in "`.dot`" are considered dot files. Files can also end in "`.gz`" or "`.bz2`" to indicate compression, such as "`.xml.gz`" or "`.dot.bz2`". Files can be saved with the "`--save`" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property called "weight":
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are specified in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifying the option "`--undirected`" before "`--load`" (see [[ref(Directedness)]] for details). Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understands the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performance for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in the [[ref(File Format Description)]] section is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any scalar vertex property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with "{{{.gz}}}" or "{{{.bz2}}}" for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{--component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (called "{{{multi-comp.dot}}}"):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph as if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as undirected with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode. If you want to load an undirected graph with graph-tool, just use the "{{{--undirected}}}" option before the "{{{--load}}}" option.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space). Here's an example using the graph defined in the [[ref(File Format Description)]] section:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file "{{{filtered.dot}}}" contains (graphical representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to "{{{True}}}" the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performance note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as an unfiltered graph to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indexes ===

  Vertices and Edges are identified internally by indexes. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges remain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacency matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a file name. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an alternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a file name. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferentially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option "`--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      -0.230769230769
  }}}

  -------

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as parameter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  === global clustering ===

  The global clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(2)} = \frac{3N_t}{N_c}\])]], where [[Equation($N_t$)]] is the number of triangles in the graph and [[Equation($N_c$)]] is the number of connected triplets. It can be obtained with the "`--global-clustering-coefficient`" option, which takes a file name as a parameter, or "`-`" for terminal output. Example:

  {{{
  $ graph-tool --load example.xml --global-clustering-coefficient=- 
  global clustering coefficient:  0.230769        0.030769
  }}}

  The first value is the global clustering coefficient, and the second value is the variance using the [http://en.wikipedia.org/wiki/Resampling_(statistics)#Jackknife jackknife method] on the vertices.
  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is often interesting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which function just like a "`for` loop": the initial statement, a condition to be checked every iteration, and a step statement. The variables defined and modified in the parameters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's an edge property called time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the options that follow it by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number (not the variable(s) used in the "`--history`" option). In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph. The syntax of the history specification is any valid [http://www.python.org python] statement.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones, otherwise they'll still contain old information.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`" option, which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "`--load`" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in "`.xml`" are considered graphml files, and files ending in "`.dot`" are considered dot files. Files can also end in "`.gz`" or "`.bz2`" to indicate compression, such as "`.xml.gz`" or "`.dot.bz2`". Files can be saved with the "`--save`" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property called "weight":
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are specified in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifying the option "`--undirected`" before "`--load`" (see [[ref(Directedness)]] for details). Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understands the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performance for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in the [[ref(File Format Description)]] section is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any scalar vertex property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with "{{{.gz}}}" or "{{{.bz2}}}" for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{--component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (called "{{{multi-comp.dot}}}"):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph as if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as undirected with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode. If you want to load an undirected graph with graph-tool, just use the "{{{--undirected}}}" option before the "{{{--load}}}" option.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space). Here's an example using the graph defined in the [[ref(File Format Description)]] section:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file "{{{filtered.dot}}}" contains (graphical representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to "{{{True}}}" the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performance note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as an unfiltered graph to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indexes ===

  Vertices and Edges are identified internally by indexes. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges remain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacency matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a file name. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an alternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a file name. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  === Mixing Patterns ===

  ==== Assortativity Coefficient ====

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferentially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option `--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      0.492063        0.252221
  }}}

  The first value is the assortativity coefficient, and the second is the variance, obtained with the [http://en.wikipedia.org/wiki/Resampling_%28statistics%29#Jackknife jackknife method].

  ==== Scalar Assortativity Coefficient ====

  If the types of vertices are scalar properties, the following coefficient may be more useful:

  [[Equation(\[r = \frac{\sum_{xy} xy(e_{xy} - a_x b_y)}{\sigma_a\sigma_b}\])]] where [[Equation(\[a_x=\sum_ye_{xy}\])]] and [[Equation(\[b_y=\sum_xe_{xy}\])]], and [[Equation($e_{xy}$)]] is the fraction of edges from a vertex of type [[Equation($x$)]] to a vertex of type [[Equation($y$)]]. It can be obtained with the "`--scalar-assortativity-coefficient`" option, which takes the same parameters as the [[ref(Assortativity Coefficient)]]. Example:

  {{{
  $ graph-tool --load example.xml --scalar-assortativity-coefficient="total-degree|-"
  scalar assortativity coefficient:       -0.241202       0.292476
  }}}

  The first value is the scalar assortativity coefficient, and the second is the variance, obtained with the [http://en.wikipedia.org/wiki/Resampling_%28statistics%29#Jackknife jackknife method].

  -------

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as parameter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  === global clustering ===

  The global clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(2)} = \frac{3N_t}{N_c}\])]], where [[Equation($N_t$)]] is the number of triangles in the graph and [[Equation($N_c$)]] is the number of connected triplets. It can be obtained with the "`--global-clustering-coefficient`" option, which takes a file name as a parameter, or "`-`" for terminal output. Example:

  {{{
  $ graph-tool --load example.xml --global-clustering-coefficient=- 
  global clustering coefficient:  0.230769        0.030769
  }}}

  The first value is the global clustering coefficient, and the second value is the variance using the [http://en.wikipedia.org/wiki/Resampling_(statistics)#Jackknife jackknife method] on the vertices.
  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is often interesting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which function just like a "`for` loop": the initial statement, a condition to be checked every iteration, and a step statement. The variables defined and modified in the parameters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's an edge property called time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the options that follow it by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number (not the variable(s) used in the "`--history`" option). In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph. The syntax of the history specification is any valid [http://www.python.org python] statement.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones, otherwise they'll still contain old information.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`" option, which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "`--load`" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in "`.xml`" are considered graphml files, and files ending in "`.dot`" are considered dot files. Files can also end in "`.gz`" or "`.bz2`" to indicate compression, such as "`.xml.gz`" or "`.dot.bz2`". Files can be saved with the "`--save`" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property called "weight":
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are specified in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifying the option "`--undirected`" before "`--load`" (see [[ref(Directedness)]] for details). Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understands the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performance for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in the [[ref(File Format Description)]] section is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any scalar vertex property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with "{{{.gz}}}" or "{{{.bz2}}}" for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{--component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (called "{{{multi-comp.dot}}}"):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph as if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as undirected with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode. If you want to load an undirected graph with graph-tool, just use the "{{{--undirected}}}" option before the "{{{--load}}}" option.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space). Here's an example using the graph defined in the [[ref(File Format Description)]] section:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file "{{{filtered.dot}}}" contains (graphical representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to "{{{True}}}" the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performance note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as an unfiltered graph to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indexes ===

  Vertices and Edges are identified internally by indexes. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges remain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacency matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a file name. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an alternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a file name. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  == Mixing Patterns ==

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferentially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option `--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      0.492063        0.252221
  }}}

  The first value is the assortativity coefficient, and the second is the variance, obtained with the [http://en.wikipedia.org/wiki/Resampling_%28statistics%29#Jackknife jackknife method].

  === Scalar Assortativity Coefficient ===

  If the types of vertices are scalar properties, the following coefficient may be more useful:

  [[Equation(\[r = \frac{\sum_{xy} xy(e_{xy} - a_x b_y)}{\sigma_a\sigma_b}\])]] where [[Equation(\[a_x=\sum_ye_{xy}\])]] and [[Equation(\[b_y=\sum_xe_{xy}\])]], and [[Equation($e_{xy}$)]] is the fraction of edges from a vertex of type [[Equation($x$)]] to a vertex of type [[Equation($y$)]]. It can be obtained with the "`--scalar-assortativity-coefficient`" option, which takes the same parameters as the [[ref(Assortativity Coefficient)]]. Example:

  {{{
  $ graph-tool --load example.xml --scalar-assortativity-coefficient="total-degree|-"
  scalar assortativity coefficient:       -0.241202       0.292476
  }}}

  The first value is the scalar assortativity coefficient, and the second is the variance, obtained with the [http://en.wikipedia.org/wiki/Resampling_%28statistics%29#Jackknife jackknife method].

  -------

  == Clustering ==

  === local clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as parameter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  === global clustering ===

  The global clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(2)} = \frac{3N_t}{N_c}\])]], where [[Equation($N_t$)]] is the number of triangles in the graph and [[Equation($N_c$)]] is the number of connected triplets. It can be obtained with the "`--global-clustering-coefficient`" option, which takes a file name as a parameter, or "`-`" for terminal output. Example:

  {{{
  $ graph-tool --load example.xml --global-clustering-coefficient=- 
  global clustering coefficient:  0.230769        0.030769
  }}}

  The first value is the global clustering coefficient, and the second value is the variance using the [http://en.wikipedia.org/wiki/Resampling_(statistics)#Jackknife jackknife method] on the vertices.
  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is often interesting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which function just like a "`for` loop": the initial statement, a condition to be checked every iteration, and a step statement. The variables defined and modified in the parameters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's an edge property called time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the options that follow it by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number (not the variable(s) used in the "`--history`" option). In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph. The syntax of the history specification is any valid [http://www.python.org python] statement.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones, otherwise they'll still contain old information.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`" option, which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: GraphToolGuide
author: count0
ipnr: 201.52.69.185
text:
  = graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "`--load`" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in "`.xml`" are considered graphml files, and files ending in "`.dot`" are considered dot files. Files can also end in "`.gz`" or "`.bz2`" to indicate compression, such as "`.xml.gz`" or "`.dot.bz2`". Files can be saved with the "`--save`" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property called "weight":
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are specified in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifying the option "`--undirected`" before "`--load`" (see [[ref(Directedness)]] for details). Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understands the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performance for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in the [[ref(File Format Description)]] section is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any scalar vertex property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with "{{{.gz}}}" or "{{{.bz2}}}" for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{--component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (called "{{{multi-comp.dot}}}"):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph as if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as undirected with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode. If you want to load an undirected graph with graph-tool, just use the "{{{--undirected}}}" option before the "{{{--load}}}" option.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space). Here's an example using the graph defined in the [[ref(File Format Description)]] section:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file "{{{filtered.dot}}}" contains (graphical representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to "{{{True}}}" the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performance note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as an unfiltered graph to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indexes ===

  Vertices and Edges are identified internally by indexes. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges remain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacency matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a file name. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an alternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a file name. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  == Mixing Patterns ==

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferentially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option `--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      0.492063        0.252221
  }}}

  The first value is the assortativity coefficient, and the second is the variance, obtained with the [http://en.wikipedia.org/wiki/Resampling_%28statistics%29#Jackknife jackknife method].

  === Scalar Assortativity Coefficient ===

  If the types of vertices are scalar properties, the following coefficient may be more useful:

  [[Equation(\[r = \frac{\sum_{xy} xy(e_{xy} - a_x b_y)}{\sigma_a\sigma_b}\])]] where [[Equation(\[a_x=\sum_ye_{xy}\])]] and [[Equation(\[b_y=\sum_xe_{xy}\])]], and [[Equation($e_{xy}$)]] is the fraction of edges from a vertex of type [[Equation($x$)]] to a vertex of type [[Equation($y$)]]. It can be obtained with the "`--scalar-assortativity-coefficient`" option, which takes the same parameters as the [[ref(Assortativity Coefficient)]]. Example:

  {{{
  $ graph-tool --load example.xml --scalar-assortativity-coefficient="total-degree|-"
  scalar assortativity coefficient:       -0.241202       0.292476
  }}}

  The first value is the scalar assortativity coefficient, and the second is the variance, obtained with the [http://en.wikipedia.org/wiki/Resampling_%28statistics%29#Jackknife jackknife method].

  -------

  == Clustering ==

  === Local Clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as parameter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  === Global Clustering ===

  The global clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(2)} = \frac{3N_t}{N_c}\])]], where [[Equation($N_t$)]] is the number of triangles in the graph and [[Equation($N_c$)]] is the number of connected triplets. It can be obtained with the "`--global-clustering-coefficient`" option, which takes a file name as a parameter, or "`-`" for terminal output. Example:

  {{{
  $ graph-tool --load example.xml --global-clustering-coefficient=- 
  global clustering coefficient:  0.230769        0.030769
  }}}

  The first value is the global clustering coefficient, and the second value is the variance using the [http://en.wikipedia.org/wiki/Resampling_(statistics)#Jackknife jackknife method] on the vertices.
  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is often interesting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which function just like a "`for` loop": the initial statement, a condition to be checked every iteration, and a step statement. The variables defined and modified in the parameters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's an edge property called time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the options that follow it by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number (not the variable(s) used in the "`--history`" option). In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph. The syntax of the history specification is any valid [http://www.python.org python] statement.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones, otherwise they'll still contain old information.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`" option, which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: GraphToolGuide
author: anonymous
ipnr: 201.52.69.185
text:
  = The graph-tool Guide =

  [[PageOutline]]

  == Invoking ==

  graph-tool is invoked by typing {{{graph-tool}}} in the command line. For a quick summary of options type
  {{{
  graph-tool --help
  }}}


  == Loading and saving files ==

  Files can be loaded with the "`--load`" option. Graph tool supports both [http://graphml.graphdrawing.org/ graphml] and [http://www.graphviz.org/ dot] formats. The formats are identified by the file name extension: files ending in "`.xml`" are considered graphml files, and files ending in "`.dot`" are considered dot files. Files can also end in "`.gz`" or "`.bz2`" to indicate compression, such as "`.xml.gz`" or "`.dot.bz2`". Files can be saved with the "`--save`" command, and the file name specifications are the same.

  === File format description ===

  Consider the following directed graph, with one floating point edge property called "weight":
  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1.2  ", len=0.6];
  2->3 [label = "  0.8  ", len=0.6];
  3->7 [label = "  0.5", len=0.6];
  4->5 [label = "  0.2  ", len=0.6];
  5->6 [label = "  10.1  ", len=0.6];
  5->3 [label = "  5.5", len=0.6];
  6->7 [label = "  2.0", len=0.6];
  7->2 [label = "  0.1", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  It can be defined in dot format as such:

  {{{
  digraph G {
  1->2 [weight = "1.2"];
  2->3 [weight = "0.8"];
  3->7 [weight = "0.5"];
  4->5 [weight = "0.2"];
  5->6 [weight = "10.1"];
  5->3 [weight = "5.5"];
  6->7 [weight = "2.0"];
  7->2 [weight = "0.1"];
  }
  }}}

  and in graphml format as such:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="weight" attr.type="double"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1.2</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">0.8</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">0.5</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">0.2</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">10.1</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">5.5</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">2.0</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">0.1</data>
      </edge>
    </graph>
  </graphml>
  }}}

  Vertex properties are specified in an analogous manner. There's no limit on the number of properties the graph can have. 

  Graphs can also be undirected, and are loaded by specifying the option "`--undirected`" before "`--load`" (see [[ref(Directedness)]] for details). Here's an example:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  graph G {
  start="12";
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  In dot format:

  {{{
  graph G {
  1--2 
  2--3 
  3--7 
  4--5 
  5--6 
  5--3 
  6--7 
  7--2 
  }
  }}}

  and in graphml format:

  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <graph id="G" edgedefault="undirected">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1"/>
      <edge id="e1" source="n1" target="n2"/>
      <edge id="e2" source="n2" target="n6"/>
      <edge id="e3" source="n3" target="n4"/>
      <edge id="e4" source="n4" target="n5"/>
      <edge id="e5" source="n4" target="n2"/>
      <edge id="e6" source="n5" target="n6"/>
      <edge id="e7" source="n6" target="n1"/>
    </graph>
  </graphml>
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ==== Which format to use? ====

  You can of course use either format, but in general graphml is preferred. It provides for a tighter definition of the graph, and since graph-tool understands the parse info attributes of the graph, you can speed up the loading of the file and reduce memory usage by using the following in your graph definition:

  {{{
  #!xml
  ...
   <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
  ...
  }}}

  This says that all vertices and edges are named "n0","n1", ..., "nN-1", and  "e0", "e1", ..., "eE-1", respectively. And also it says that the vertex list comes before the edge list. You're not forced to define your graph this way, but it does improve performance for large graphs.

  {{{
  #!html
  </div>
  }}}

  ----

  == Basic Statistics ==

  The two most basic properties of the graph are the number of vertex and edges, which is obtainable through the "{{{--number-of-vertices}}}" and "{{{--number-of-edges}}}" options. Suppose the first graph in the [[ref(File Format Description)]] section is saved under {{{example.xml}}}. We can then get the number of vertices and edges by typing:

  {{{
  $ graph-tool --load example.xml --number-of-vertices=- --number-of-edges=-
  number of vertices:     7
  number of edges:        8
  }}}

  The "-" parameter to the options is necessary to output the results in the terminal. Otherwise it writes it to the file given in the parameter.

  === Vertex Histogram ===

  The histogram of vertex properties (such as degree) can be obtained by the "{{{--vertex-histogram}}}" option. It requires two parameters, separated by "|": degree type and file name. Degree type can be any of "in-degree", "out-degree", "total-degree" and __any scalar vertex property__. The file name is the file the histogram is written to, or "-" to be written to the terminal. Files may be terminated with "{{{.gz}}}" or "{{{.bz2}}}" for compression. Example:

  {{{
  $ graph-tool --load example.xml --vertex-histogram="total-degree|deg-dist"
  $ cat deg-dist
  1.0     2
  2.0     1
  3.0     4
  }}}

  For directed graphs, it is also possible to get the combined (in,out)-degree histogram with the "{{{--combined-degree-histogram}}}" option:

  {{{
  $ graph-tool --load example.xml --combined-degree-histogram="deg-dist"
  $ cat deg-dist
  0.0     1.0     2
  1.0     1.0     1
  1.0     2.0     1
  2.0     1.0     3
  }}}

  === Edge Histogram ===

  The histogram of edge properties can be obtained in an analogous fashion with the "`--edge-histogram`" 
  option. Example:

  {{{
  $ graph-tool --load example.xml --edge-histogram="weight|weight-dist"                 
  $ cat weight-dist 
  0.1     1
  0.2     1
  0.5     1
  0.8     1
  1.2     1
  2.0     1
  5.5     1
  10.1    1
  }}}

  === Average Distance ===

  The average vertex-vertex distance can be obtained with the "{{{--average-distance}}}" option:

  {{{
  $ graph-tool --load example.xml --average-distance=-
  average distance:       0.714285714286
  }}}

  For directed and/or disconnected graphs, it may be better to use the average harmonic distance defined as:

  [[Equation(\[d_h = \left[\sum_{v,u}\frac{1}{d_{uv}}\right]^{-1}\])]], where [[Equation($d_{uv}$)]] is the regular graph distance between [[Equation($u$)]] and [[Equation($v$)]], which here is taken to be infinity when there's no path between those two vertices.

  Example:

  {{{
  $ graph-tool --load example.xml --average-harmonic-distance=-
  average harmonic distance:      4.1226993865
  }}}

  === Component Size Histogram === 

  Component size statistics can be obtained by the "{{{--component-size-histogram}}}" option. Consider the following graph:

  {{{
  #!html
  <div style="text-align: center;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  Defined by the following dot file (called "{{{multi-comp.dot}}}"):
  {{{
  digraph G {
  1->2
  2->3
  3->1

  4->5

  6->7
  7->8
  8->9
  9->10
  10->11
  11->6
  }
  }}}

  When called with a directed graph, the program returns the '''strong component''' statistics:

  {{{
  $graph-tool --load multi-comp.dot --component-size-histogram="comp-hist"
  $ cat comp-hist
  1.0     2
  3.0     1
  6.0     1
  }}}

  To see the component statistics if the graph as if the graph were undirected, we just have to treat it as such:

  {{{
  $ graph-tool --load multi-comp.dot --undirected --component-size-histogram="comp-hist"
  $ cat comp-hist
  2.0     1
  3.0     1
  6.0     1
  }}}

  ------

  == Filtering ==

  Graphs can be filtered in several ways. None of them actually modify the internally kept graph, and are of complexity O(1).

  === Directedness ===

  Internally, all graphs in graph-tool are directed graphs. But it is possible to treat them easily as undirected with the "{{{--undirected}}}" option. All options after that will operate on a undirected filter of the internal directed graph. The "{{{--directed}}}" option reverts back to the default mode. If you want to load an undirected graph with graph-tool, just use the "{{{--undirected}}}" option before the "{{{--load}}}" option.

  === Edge direction ===

  Directed graphs can have the the edge direction reversed with the "{{{--reverse}}}" option. A second "{{{--reverse}}}" reverts back to the original state.

  === Filtering of vertices or edges ===

  ==== Range filtering ====

  Edges and vertices can be filtered out of the graph based on their properties. The most basic and fastest way of filtering is called "range filtering" and filters out vertices with a scalar property which lays outside a given range. The filtering is controlled with the "{{{--vertex-range-filter}}}" and "{{{--edge-range-filter}}}" options, which takes two parameters separated by "|": the property to be used as filter and the range (two values separated by space). Here's an example using the graph defined in the [[ref(File Format Description)]] section:

  {{{
  $ graph-tool --load example.xml --number-of-edges=-
  number of edges:        8
  $ graph-tool --load example.xml --edge-range-filter="weight|0.6 6.0" --number-of-edges=- --save filtered.dot
  number of edges:        4
  }}}

  The file "{{{filtered.dot}}}" contains (graphical representation on the side):

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [label="1.2"];
  2->3  [label="0.8"];
  5->3  [label="5.5"];
  6->7  [label="2.0"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}

  {{{
  digraph G {
  1;
  2;
  3;
  7;
  4;
  5;
  6;
  1->2  [weight="1.2"];
  2->3  [weight="0.8"];
  5->3  [weight="5.5"];
  6->7  [weight="2"];
  }
  }}}

  ==== Generic Filtering ====

  Graphs can be filtered in a more versatile way than above (at a performance cost). This is done through the "{{{--vertex-filter}}}" and "{{{--edge-filter}}}" options, which take a generic [http://www.python.org python] expression as a parameter, and if it evaluates to "{{{True}}}" the vertex or edge is removed.

  Example:

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [label="0.5"];
  2->3  [label="10.1"];
  2->1  [label="5.5"];
  3->4  [label="2"];
  4->0  [label="0.1"];
  }
  }}}
  {{{
  #!html
  </div>
  }}}
  {{{
  $ graph-tool --load example.xml --edge-filter="weight==0.8" --vertex-filter="in_degree==0" --save filtered.dot
  $ cat filtered.dot
  digraph G {
  0;
  1;
  2;
  3;
  4;
  1->4  [weight="0.5"];
  2->3  [weight="10.1"];
  2->1  [weight="5.5"];
  3->4  [weight="2"];
  4->0  [weight="0.1"];
  }
  }}}

  {{{
  #!html
  <div class="note">
  }}}
  ===== Performance note =====
  When generic filtering is turned on, algorithms in general will run much slower, since the python interpreter will be involved in the computations. Therefore, if some expensive computation is being considered, it is in general better to save the graph to a file after the filtering, and load it as an unfiltered graph to perform the computation.
  {{{
  #!html
  </div>
  }}}

  ==== Removing filtering ====

  The graph can be returned to its unfiltered state by calling "{{{--reset-vertex-filter}}}" and "{{{--reset-edge-filter}}}".

  -------

  == Graph Modifications ==

  There's a couple of options which change the internally kept graph.

  === Removing Properties ===

  Vertex and edge properties can be removed from the graph with the options "{{{--remove-vertex-property}}}" and "{{{--remove-edge-property}}}", which take the name of the property to be removed as parameter.

  === Vertex and Edge Indexes ===

  Vertices and Edges are identified internally by indexes. Those can be inserted as properties with the options "{{{--insert-vertex-index-property}}}" and "{{{--insert-edge-index-property}}}", which take as argument the name by which the property will be called.

  === Removal of Parallel Edges ===

  Parallel edges (i.e. edges that share the same source and target) can be removed from the graph with the option "{{{--remove-parallel-edges}}}", so that only one of the parallel edges remain (it is undefined which one).

  ------

  == Correlations ==

  === Vertex Correlation ===

  The vertex correlation histogram is a bidimensional histogram defined as

  [[Equation(\[C(k,k')=\sum_{u,v}A_{uv}[k_u=k][k_v=k']\])]], where [[Equation($\mathbf{A}$)]] is the adjacency matrix. It is obtainable with the "{{{--vertex-correlation-histogram}}}" option, which takes three parameters separated by "|": First degree type ([[Equation($k_u$)]]), second degree type ([[Equation($k_v$)]]) and a file name. The degree types can be `in-degree`, `out-degree` and `total-degree`. It can also be the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --vertex-correlation="in-degree|out-degree|deg-corr"
  $ cat deg-corr
  0.0     1.0     1
  0.0     2.0     1
  1.0     1.0     3
  2.0     1.0     3
  }}}

  It is also possible to obtain the correlation in an alternative fashion, which a lot of times is more convenient, and that is the average nearest neighbours degree, given by

  [[Equation(\[ \bar{k}(k)=\frac{\sum_{u,v}A_{uv}k_v[k_u=k]}{\sum_{u,v}A_{uv}[k_u=k]}\])]].

  It is obtainable with the "`--average-nearest-neighbours-correlation`" option, which takes three parameters separated by "|": degree type of the origin vertex, degree type of the neighbours and a file name. Origin and neighbour degree type can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:

  {{{
  $ graph-tool --load example.xml --average-nearest-neighbours-correlation="total-degree|in-degree|deg-corr"
  $ cat deg-corr
  1.0     1.5     0.5
  2.0     2.0     0.0
  3.0     1.8     0.2
  }}}

  The third column above is the standard deviation of the average in the second column.

  === Edge Correlation ===

  When edges have scalar properties, it is possible to generate a 3-dimensional correlation histogram defined as:

  [[Equation(\[ P(k,m,k')=\sum_{e}[k_{s(e)}=k][k_{t(e)}=k'][p(e)=m]}\])]], where [[Equation($e$)]] are the edges of the graph, [[Equation(\[s(e)\])]] and [[Equation(\[t(e)\])]] are the source and target vertex of edge [[Equation($e$)]], and [[Equation(\[p(e)\])]] is some property of the edge.

  This can be obtained with the "`--edge-vertex-correlation-histogram`" option which takes four arguments separated by "|": Source degree type, edge property and target degree type. The source and target degree types can be "`in-degree`", "`out-degree`" and "`total-degree`", as well as the name of any scalar vertex property available.

  Example:
  {{{
  $ graph-tool --load example.xml --edge-vertex-correlation-histogram="in-degree|weight|out-degree|edge-corr"
  $ cat edge-corr
  0.0     0.2     2.0     1
  0.0     1.2     1.0     1
  1.0     2.0     1.0     1
  1.0     5.5     1.0     1
  1.0     10.1    1.0     1
  2.0     0.1     1.0     1
  2.0     0.5     1.0     1
  2.0     0.8     1.0     1
  }}}

  == Mixing Patterns ==

  === Assortativity Coefficient ===

  The assortativity coefficient tells in a concise fashion how vertices of different types are preferentially connected amongst themselves, and is defined by

  [[Equation(\[r = \frac{\sum_i e_{ii} - \sum_i a_i b_i}{1-\sum_i a_i b_i}\])]] where [[Equation(\[a_i=\sum_je_{ij}\])]] and [[Equation(\[b_j=\sum_ie_{ij}\])]], and [[Equation($e_{ij}$)]] is the fraction of edges from a vertex of type [[Equation($i$)]] to a vertex of type [[Equation($j$)]].

  It is obtained by the option `--assortativity-coefficient`", which takes two arguments: the property used to identify different types and a file name, separated by "|". The property may be any scalar vertex property in the graph, as well a "`in-degree`", "`out-degree`" and "`total-degree`".

  Example:

  {{{
  $ graph-tool --load example.xml --assortativity-coefficient="total-degree|-"
  assortativity coefficient:      0.492063        0.252221
  }}}

  The first value is the assortativity coefficient, and the second is the variance, obtained with the [http://en.wikipedia.org/wiki/Resampling_%28statistics%29#Jackknife jackknife method].

  === Scalar Assortativity Coefficient ===

  If the types of vertices are scalar properties, the following coefficient may be more useful:

  [[Equation(\[r = \frac{\sum_{xy} xy(e_{xy} - a_x b_y)}{\sigma_a\sigma_b}\])]] where [[Equation(\[a_x=\sum_ye_{xy}\])]] and [[Equation(\[b_y=\sum_xe_{xy}\])]], and [[Equation($e_{xy}$)]] is the fraction of edges from a vertex of type [[Equation($x$)]] to a vertex of type [[Equation($y$)]]. It can be obtained with the "`--scalar-assortativity-coefficient`" option, which takes the same parameters as the [[ref(Assortativity Coefficient)]]. Example:

  {{{
  $ graph-tool --load example.xml --scalar-assortativity-coefficient="total-degree|-"
  scalar assortativity coefficient:       -0.241202       0.292476
  }}}

  The first value is the scalar assortativity coefficient, and the second is the variance, obtained with the [http://en.wikipedia.org/wiki/Resampling_%28statistics%29#Jackknife jackknife method].

  -------

  == Clustering ==

  === Local Clustering ===

  The local (vertex) clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(1)}_v = \frac{k(k-1)}{2N_c}\])]], where [[Equation($k$)]] is the degree of the vertex, and [[Equation($N_c$)]] is the number of edges between the neighbours of the vertex. This value can be calculated and set to a vertex property with the command "`--set-local-clustering-to-property`", which takes the property name as parameter. Example:

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --vertex-histogram="clustering|clust"
  $ cat clust
  0.0     4
  0.333333333333  3
  }}}

  It is possible to obtain the clustering coefficient for the whole graph by using the `--average-vertex-property` option :

  {{{
  $ graph-tool --load example.xml --set-local-clustering-to-property=clustering --average-vertex-property="clustering|-"
  average vertex property:        0.142857        0.062348
  }}}

  The first value is the clustering coefficient, and the second is the standard deviation.

  === Global Clustering ===

  The global clustering coefficient is defined on an undirected graph as 

  [[Equation(\[C^{(2)} = \frac{3N_t}{N_c}\])]], where [[Equation($N_t$)]] is the number of triangles in the graph and [[Equation($N_c$)]] is the number of connected triplets. It can be obtained with the "`--global-clustering-coefficient`" option, which takes a file name as a parameter, or "`-`" for terminal output. Example:

  {{{
  $ graph-tool --load example.xml --global-clustering-coefficient=- 
  global clustering coefficient:  0.230769        0.030769
  }}}

  The first value is the global clustering coefficient, and the second value is the variance using the [http://en.wikipedia.org/wiki/Resampling_(statistics)#Jackknife jackknife method] on the vertices.
  --------

  == Layout ==

  graph-tool includes also a couple of layout algorithms, which saves vertex position coordinates into a vertex property, which later can be used by [http://www.graphviz.org/ graphviz] to draw the graph.

  === Spring-Block ===

  This implements the [http://www.boost.org/libs/graph/doc/fruchterman_reingold.html Fruchterman-Reingold] spring-block layout algorithm. It is available through the "`--compute-spring-block-layout`" option, which takes two arguments: the maximum number of iterations and an optional seed value (which will be taken from the computer clock if not supplied). The positions will be recorded in the "pos" property.

  == Gursoy-Atun ==

  This implements the [http://www.boost.org/libs/graph/doc/gursoy_atun_layout.html Gursoy-Atun] layout algorithm, which can provide for an interesting alternative to force-directed layouts. It is called with the "`--compute-gursoy-atun-layout`" option, and takes the same parameters as the spring-block layout above.

  ------

  == Random Graph Generation ==

  This section is described in RandomGraphGeneration. 

  ------

  == Graph History ==

  Graphs sometimes have dynamical properties related to them. Sometimes they grow or change somehow during time. It is often interesting to see how its various properties also change with time. In graph tool this is possible through the usage of properties, filtering, and the "`--history`" option. The history option takes three parameters, which function just like a "`for` loop": the initial statement, a condition to be checked every iteration, and a step statement. The variables defined and modified in the parameters of this option are available to be used by the other options that follow it. Using graph properties and filtering, snapshots of the graph can be generated. It all becomes clearer with an example. Consider the following graph, called "`example-time.xml`":

  {{{
  #!html
  <div style="float: right;">
  }}}
  {{{
  #!graphviz
  digraph G {
  start="12";
  1->2 [label = "  1  ", len=0.6];
  2->3 [label = "  2  ", len=0.6];
  3->7 [label = "  3  ", len=0.6];
  4->5 [label = "  4  ", len=0.6];
  5->6 [label = "  5  ", len=0.6];
  5->3 [label = "  6  ", len=0.6];
  6->7 [label = "  7  ", len=0.6];
  7->2 [label = "  8  ", len=0.6];
  }
  }}}
  {{{
  #!html
  </div>
  }}}


  {{{
  #!xml
  <?xml version="1.0" encoding="UTF-8"?>
  <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing\.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
    <key id="d1" for="edge" attr.name="time" attr.type="int"/>
    <graph id="G" edgedefault="directed">
      <node id="n0"/>
      <node id="n1"/>
      <node id="n2"/>
      <node id="n3"/>
      <node id="n4"/>
      <node id="n5"/>
      <node id="n6"/>
      <edge id="e0" source="n0" target="n1">
        <data key="d1">1</data>
      </edge>
      <edge id="e1" source="n1" target="n2">
        <data key="d1">2</data>
      </edge>
      <edge id="e2" source="n2" target="n6">
        <data key="d1">3</data>
      </edge>
      <edge id="e3" source="n3" target="n4">
        <data key="d1">4</data>
      </edge>
      <edge id="e4" source="n4" target="n5">
        <data key="d1">5</data>
      </edge>
      <edge id="e5" source="n4" target="n2">
        <data key="d1">6</data>
      </edge>
      <edge id="e6" source="n5" target="n6">
        <data key="d1">7</data>
      </edge>
      <edge id="e7" source="n6" target="n1">
        <data key="d1">8</data>
      </edge>
    </graph>
  </graphml>
  }}}

  There's an edge property called time which goes from 1 to 8. So in order to calculate, for instance, the number of edges and the degree distribution over time, one could do the following:

  {{{
  $ graph-tool --load example-time.xml --history="t=1|t<9|t+=1" --edge-range-filter="time|1 %t" --vertex-histogram="total-degree|deg-history" --number-of-edges="num-edges-history"
  $ cat num-edges-history 
  0       1
  1       2
  2       3
  3       4
  4       5
  5       6
  6       7
  7       8
  $ cat deg-history
  0       0.0     5
  0       1.0     2
  1       0.0     4
  1       1.0     2
  1       2.0     1
  2       0.0     3
  2       1.0     2
  2       2.0     2
  3       0.0     1
  3       1.0     4
  3       2.0     2
  4       1.0     4
  4       2.0     3
  5       1.0     4
  5       2.0     1
  5       3.0     2
  6       1.0     2
  6       2.0     3
  6       3.0     2
  7       1.0     2
  7       2.0     1
  7       3.0     4
  }}}

  The variables defined in the "`--history`" option are reachable in the options that follow it by prefixing them with "`%`". Each saved file contains the history of the measured property, with each line prefixed by the history iteration number (not the variable(s) used in the "`--history`" option). In the case above, "`num-edges-history`" contains the number of edges in each iteration and "`deg-history`" contains the degree distribution with each iteration. It should be clear with the above example that this feature is reasonably general, since combined with generic filtering, it is possible to obtain quite arbitrary "histories" of the graph. The syntax of the history specification is any valid [http://www.python.org python] statement.


  === Resuming history computations ===

  For large graphs history computations can take quite a long time. During this time things in general can go wrong, such as a power outage. For this reason graph-tool supports resuming of history computations, where partial results already contained in the history files are automatically skipped and not recalculated. Therefore, if you change the history rules or the graph, you must remember to delete the old history files or to save to new ones, otherwise they'll still contain old information.

  Before data is saved to the history files, partial history results are kept in temporary files, which get periodically copied over to the final files. The frequency of this update can be changed with the "`--history-rate`" option, which takes a number as a parameter followed by "`s`","`m`","`h`" or "`d`" to indicate seconds, minutes, hours or days, respectively. The default value is "`1h`".


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\geq j}\sum_{k'\geq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''', '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the invert of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.

  pjk, pjk_ceil, pjk_m, inv_pjk_ceil, corr, corr_ceil, corr_m,inv_corr_ceil, undirected, directed, progress, seed.


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\geq j}\sum_{k'\geq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\geq j'}\sum_{k''\geq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     blah
   '''directed'''::
     blah
   '''progress'''::
     blah
   '''seed''':
     blah


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\geq j}\sum_{k'\geq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\geq j'}\sum_{k''\geq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  == Examples ==

  === Uncorrelated Graphs ==

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%, misses: 2)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  global clustering coefficient:  0.000412        0.000000
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\geq j}\sum_{k'\geq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\geq j'}\sum_{k''\geq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  == Examples ==

  === Uncorrelated Graphs ===

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%, misses: 2)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  global clustering coefficient:          0.000412        0.000000
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]

  So, things seem to make sense so far.  Let's try with something more unusual... Suppose you want different in and out degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%, misses: 2)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  global clustering coefficient:          0.000640        0.000000
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\geq j}\sum_{k'\geq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\geq j'}\sum_{k''\geq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  ---------

  == Examples ==

  === Uncorrelated Graphs ===

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%, misses: 2)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  global clustering coefficient:          0.000412        0.000000
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]

  So, things seem to make sense so far.  Let's try with something more unusual... Suppose you want different in and out degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%, misses: 2)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  global clustering coefficient:          0.000640        0.000000
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\geq j}\sum_{k'\geq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\geq j'}\sum_{k''\geq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  ---------

  == Examples ==

  === Uncorrelated Graphs ===

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  global clustering coefficient:          0.000412        0.000000
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]

  So, things seem to make sense so far.  Let's try with something more unusual... Suppose you want different in and out degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  global clustering coefficient:          0.000640        0.000000
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]

  Suppose we want some other expression for the degree distribution that we want to specify ourselves. Supose our in-degree distribution is composed of two poisson distributions with different averages, and the out-degree distribution is a power law. Our in-degree distribution can be written as such:

  [[Equation(\[p(j)=\frac{e^{-m_1}m_1^j+e^{-m_2}m_2^j}{2j!}\])]]. The cumulative distribution is then [[Equation(\[P(j)=\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}\])]].

  The inverse of the cumulative distribution is the solution of [[Equation(\[\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}-P=0\])]] for [[Equation($j$)]]. We can use "`fsolve`" function from the [http://www.scipy.org scipy] package (which is included automatically if available) to write it as such:
  {{{
  fsolve(lambda j: (gammaincc(j,m1)+gammaincc(j,m2))/2-p, (m1+m2)/2.0)
  }}}


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\geq j}\sum_{k'\geq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\geq j'}\sum_{k''\geq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  ---------

  == Examples ==

  === Uncorrelated Graphs ===

  ==== Independent and equal in-out distributions ====

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  global clustering coefficient:          0.000412        0.000000
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]



  So, things seem to make sense so far.  Let's try with something a little bit more unusual...

  ==== Independent but different in-out distributions ====

  Suppose you want different in- and out-degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  global clustering coefficient:          0.000640        0.000000
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]

  ==== More elaborate in-out distributions ====

  Suppose we want some other expression for the degree distribution that we want to specify ourselves. Supose our in-degree distribution is composed of two poisson distributions with different averages, and the out-degree distribution is an exponential. Our in-degree distribution can be written as such:

  [[Equation(\[p(j)=\frac{e^{-m_1}m_1^j+e^{-m_2}m_2^j}{2j!}\])]]. The cumulative distribution is then [[Equation(\[P(j)=\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}\])]].

  The inverse of the cumulative distribution is the solution of [[Equation(\[\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}-P=0\])]] for [[Equation($j$)]]. We can use "`fsolve`" function from the [http://www.scipy.org scipy] package (which is included automatically if available) to write it as such:
  {{{
  fsolve(lambda j: (gammaincc(j,m1)+gammaincc(j,m2))/2-p, (m1+m2)/2.0)
  }}}

  We can generate the graph with the following command:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(fsolve(lambda j: (gammaincc(j,4)+gammaincc(j,20))/2-p, (12)/2.0)-0.5+1e-11,inv_exponential(r,12))\",progress" --save graph3.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 241062 of 241062 (100%)
  }}}

  The "`-0.5+1e-11`" term added above is just to make up for a rounding effect. We can get the same measurements as before,

  {{{
  $ graph-tool --load graph3.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        241062
  global clustering coefficient:          0.002157        0.000000
  scalar assortativity coefficient:       -0.000600       0.002038
  }}}

  [[Image(degree-2poissons.png, nolink)]] [[Image(degree-uncorrelation3.png, nolink)]]

  ==== Combined in- and out-degree distributions ====

  ==== Undirected Graphs ====

  === Correlated Graphs ===
  ==== Undirected Graphs ====
  ==== Directed Graphs ====


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\leq j}\sum_{k'\leq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\leq j'}\sum_{k''\leq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  ---------

  == Examples ==

  === Uncorrelated Graphs ===

  ==== Independent and equal in-out distributions ====

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  global clustering coefficient:          0.000412        0.000000
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]



  So, things seem to make sense so far.  Let's try with something a little bit more unusual...

  ==== Independent but different in-out distributions ====

  Suppose you want different in- and out-degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  global clustering coefficient:          0.000640        0.000000
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]

  ==== More elaborate in-out distributions ====

  Suppose we want some other expression for the degree distribution that we want to specify ourselves. Supose our in-degree distribution is composed of two poisson distributions with different averages, and the out-degree distribution is an exponential. Our in-degree distribution can be written as such:

  [[Equation(\[p(j)=\frac{e^{-m_1}m_1^j+e^{-m_2}m_2^j}{2j!}\])]]. The cumulative distribution is then [[Equation(\[P(j)=\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}\])]].

  The inverse of the cumulative distribution is the solution of [[Equation(\[\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}-P=0\])]] for [[Equation($j$)]]. We can use "`fsolve`" function from the [http://www.scipy.org scipy] package (which is included automatically if available) to write it as such:
  {{{
  fsolve(lambda j: (gammaincc(j,m1)+gammaincc(j,m2))/2-p, (m1+m2)/2.0)
  }}}

  We can generate the graph with the following command:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(fsolve(lambda j: (gammaincc(j,4)+gammaincc(j,20))/2-p, (12)/2.0)-0.5+1e-11,inv_exponential(r,12))\",progress" --save graph3.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 241062 of 241062 (100%)
  }}}

  The "`-0.5+1e-11`" term added above is just to make up for a rounding effect. We can get the same measurements as before,

  {{{
  $ graph-tool --load graph3.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --global-clustering-coefficient=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        241062
  global clustering coefficient:          0.002157        0.000000
  scalar assortativity coefficient:       -0.000600       0.002038
  }}}

  [[Image(degree-2poissons.png, nolink)]] [[Image(degree-uncorrelation3.png, nolink)]]

  ==== Combined in- and out-degree distributions ====

  Generating combined, i.e. not independent, in- and out-degree distributions is a little bit more complicated. Here it is described a relatively simple example. Suppose we want to generate the following joint degree distribution

  [[Equation(\[ p(j,k) = \frac{1}{2}\frac{e^{-m_1}m_1^j}{j!}\frac{e^{-m_1}m_1^k}{k!} + \frac{1}{2}\frac{e^{-m_2}m_2^j}{j!}\frac{e^{-m_2}m_2^k}{k!}\])]].

  ==== Undirected Graphs ====

  -------

  === Correlated Graphs ===
  ==== Undirected Graphs ====
  ==== Directed Graphs ====


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\leq j}\sum_{k'\leq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\leq j'}\sum_{k''\leq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  ---------

  == Examples ==

  === Uncorrelated Graphs ===

  ==== Independent and equal in-out distributions ====

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]



  So, things seem to make sense so far.  Let's try with something a little bit more unusual...

  ==== Independent but different in-out distributions ====

  Suppose you want different in- and out-degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]

  ==== More elaborate in-out distributions ====

  Suppose we want some other expression for the degree distribution that we want to specify ourselves. Supose our in-degree distribution is composed of two poisson distributions with different averages, and the out-degree distribution is an exponential. Our in-degree distribution can be written as such:

  [[Equation(\[p(j)=\frac{e^{-m_1}m_1^j+e^{-m_2}m_2^j}{2j!}\])]]. The cumulative distribution is then [[Equation(\[P(j)=\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}\])]].

  The inverse of the cumulative distribution is the solution of [[Equation(\[\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}-P=0\])]] for [[Equation($j$)]]. We can use "`fsolve`" function from the [http://www.scipy.org scipy] package (which is included automatically if available) to write it as such:
  {{{
  fsolve(lambda j: (gammaincc(j,m1)+gammaincc(j,m2))/2-p, (m1+m2)/2.0)
  }}}

  We can generate the graph with the following command:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(fsolve(lambda j: (gammaincc(j,4)+gammaincc(j,20))/2-p, (12)/2.0)-0.5+1e-11,inv_exponential(r,12))\",progress" --save graph3.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 241062 of 241062 (100%)
  }}}

  The "`-0.5+1e-11`" term added above is just to make up for a rounding effect. We can get the same measurements as before,

  {{{
  $ graph-tool --load graph3.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        241062
  scalar assortativity coefficient:       -0.000600       0.002038
  }}}

  [[Image(degree-2poissons.png, nolink)]] [[Image(degree-uncorrelation3.png, nolink)]]

  ==== Combined in- and out-degree distributions ====

  Generating combined, i.e. not independent, in- and out-degree distributions is a little bit more complicated. Here it is described a relatively simple example. Suppose we want to generate the following joint degree distribution, which is the combination of two independent poisson distributions,

  [[Equation(\[ p(j,k) = \frac{1}{2}\frac{e^{-m_1}m_1^j}{j!}\frac{e^{-m_1}m_1^k}{k!} + \frac{1}{2}\frac{e^{-m_2}m_2^j}{j!}\frac{e^{-m_2}m_2^k}{k!}\])]].

  The cumulative degree distribution is the following,

  [[Equation(\[ P(j,k) = \frac{1}{2}\frac{\Gamma(j+1,m_1)\Gamma(k+1,m_1)}{j!k!} + \frac{1}{2}\frac{\Gamma(j+1,m_2)\Gamma(k+1,m_2)}{j!k!} \])]], which is already complicated to find the inverse (which will be some sort of curve in the jk-plane).

  So in order to sample from this distribution, it will be necessary to write something more complicated than an expression which can be squeezed in the "`inv_pjk_ceil`" option. For this reason, it is possible to define the sampling function in a file first, and then tell graph-tool to load it. Here's the definition of "`inv_pjk_ceil`" which will sample from the above distribution, defined in a file called "`joint_poissons.py`":

  {{{
  #!python
  from random import *

  def inv_pjk_ceil(p,r):
      if random() > 0.5:
          return (int(round(inv_poisson(p,4))),int(round(inv_poisson(r,4))))
      else:
          return (int(round(inv_poisson(p,20))),int(round(inv_poisson(r,20))))
  }}}

  This can be just about any valid python program that defines the function "`inv_pjk_ceil(p,r)`", which can include other packages and so forth. This way it is possible to implement just about any sampling routine. With this file in place, the graph can be generated with the following command

  {{{
   ../src/graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"file:joint_poissons.py\",progress" --save graph4.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 240456 of 240456 (100%)
  }}}

  When the "`inv_pjk_ceil`" parameter begins with "file:", it instructs the program to load it from the specified file. We can then check if eveything is correct:
  {{{
  $ graph-tool --load graph4.xml.bz2 --combined-degree-histogram="combined-degree-histogram"  --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-" 
  number of vertices:     20000
  number of edges:        240456
  scalar assortativity coefficient:       0.000398        0.002032
  }}}

  Below are plotted the theoretical and generated joint degree histograms,

  [[Image(joint-poissons-theoretical.png, nolink)]] [[Image(joint-poissons-generated.png, nolink)]]

  Not too bad.

  ==== Undirected Graphs ====

  -------

  === Correlated Graphs ===
  ==== Undirected Graphs ====
  ==== Directed Graphs ====


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\leq j}\sum_{k'\leq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\leq j'}\sum_{k''\leq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  ---------

  == Examples ==

  === Uncorrelated Graphs ===

  ==== Independent and equal in-out distributions ====

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]



  So, things seem to make sense so far.  Let's try with something a little bit more unusual...

  ==== Independent but different in-out distributions ====

  Suppose you want different in- and out-degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]

  ==== More elaborate in-out distributions ====

  Suppose we want some other expression for the degree distribution that we want to specify ourselves. Supose our in-degree distribution is composed of two poisson distributions with different averages, and the out-degree distribution is an exponential. Our in-degree distribution can be written as such:

  [[Equation(\[p(j)=\frac{e^{-m_1}m_1^j+e^{-m_2}m_2^j}{2j!}\])]]. The cumulative distribution is then [[Equation(\[P(j)=\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}\])]].

  The inverse of the cumulative distribution is the solution of [[Equation(\[\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}-P=0\])]] for [[Equation($j$)]]. We can use "`fsolve`" function from the [http://www.scipy.org scipy] package (which is included automatically if available) to write it as such:
  {{{
  fsolve(lambda j: (gammaincc(j,m1)+gammaincc(j,m2))/2-p, (m1+m2)/2.0)
  }}}

  We can generate the graph with the following command:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(fsolve(lambda j: (gammaincc(j,4)+gammaincc(j,20))/2-p, (12)/2.0)-0.5+1e-11,inv_exponential(r,12))\",progress" --save graph3.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 241062 of 241062 (100%)
  }}}

  The "`-0.5+1e-11`" term added above is just to make up for a rounding effect. We can get the same measurements as before,

  {{{
  $ graph-tool --load graph3.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        241062
  scalar assortativity coefficient:       -0.000600       0.002038
  }}}

  [[Image(degree-2poissons.png, nolink)]] [[Image(degree-uncorrelation3.png, nolink)]]

  ==== Combined in- and out-degree distributions ====

  Generating combined, i.e. not independent, in- and out-degree distributions is a little bit more complicated. Here it is described a relatively simple example. Suppose we want to generate the following joint degree distribution, which is the combination of two independent poisson distributions,

  [[Equation(\[ p(j,k) = \frac{1}{2}\frac{e^{-m_1}m_1^j}{j!}\frac{e^{-m_1}m_1^k}{k!} + \frac{1}{2}\frac{e^{-m_2}m_2^j}{j!}\frac{e^{-m_2}m_2^k}{k!}\])]].

  The cumulative degree distribution is the following,

  [[Equation(\[ P(j,k) = \frac{1}{2}\frac{\Gamma(j+1,m_1)\Gamma(k+1,m_1)}{j!k!} + \frac{1}{2}\frac{\Gamma(j+1,m_2)\Gamma(k+1,m_2)}{j!k!} \])]], which is already complicated to find the inverse (which will be some sort of curve in the jk-plane).

  So in order to sample from this distribution, it will be necessary to write something more complicated than an expression which can be squeezed in the "`inv_pjk_ceil`" option. For this reason, it is possible to define the sampling function in a file first, and then tell graph-tool to load it. Here's the definition of "`inv_pjk_ceil`" which will sample from the above distribution, defined in a file called "`joint_poissons.py`":

  {{{
  #!python
  from random import *

  def inv_pjk_ceil(p,r):
      if random() > 0.5:
          return (int(round(inv_poisson(p,4))),int(round(inv_poisson(r,4))))
      else:
          return (int(round(inv_poisson(p,20))),int(round(inv_poisson(r,20))))
  }}}

  This can be just about any valid python program that defines the function "`inv_pjk_ceil(p,r)`", which can include other packages and so forth. This way it is possible to implement just about any sampling routine. With this file in place, the graph can be generated with the following command

  {{{
   ../src/graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"file:joint_poissons.py\",progress" --save graph4.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 240456 of 240456 (100%)
  }}}

  When the "`inv_pjk_ceil`" parameter begins with "file:", it instructs the program to load it from the specified file. We can then check if eveything is correct:
  {{{
  $ graph-tool --load graph4.xml.bz2 --combined-degree-histogram="combined-degree-histogram"  --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-" 
  number of vertices:     20000
  number of edges:        240456
  scalar assortativity coefficient:       0.000398        0.002032
  }}}

  Below are plotted the theoretical and generated joint degree histograms,

  [[Image(joint-poissons-theoretical.png, nolink)]] [[Image(joint-poissons-generated.png, nolink)]]

  Voilà... Not too shabby.

  ==== Undirected Graphs ====

  -------

  === Correlated Graphs ===
  ==== Undirected Graphs ====
  ==== Directed Graphs ====


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\leq j}\sum_{k'\leq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\leq j'}\sum_{k''\leq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  ---------

  == Tutorial & Examples ==

  === Uncorrelated Graphs ===

  ==== Independent and equal in-out distributions ====

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]



  So, things seem to make sense so far.  Let's try with something a little bit more unusual...

  ==== Independent but different in-out distributions ====

  Suppose you want different in- and out-degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]

  ==== More elaborate in-out distributions ====

  Suppose we want some other expression for the degree distribution that we want to specify ourselves. Supose our in-degree distribution is composed of two poisson distributions with different averages, and the out-degree distribution is an exponential. Our in-degree distribution can be written as such:

  [[Equation(\[p(j)=\frac{e^{-m_1}m_1^j+e^{-m_2}m_2^j}{2j!}\])]]. The cumulative distribution is then [[Equation(\[P(j)=\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}\])]].

  The inverse of the cumulative distribution is the solution of [[Equation(\[\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}-P=0\])]] for [[Equation($j$)]]. We can use "`fsolve`" function from the [http://www.scipy.org scipy] package (which is included automatically if available) to write it as such:
  {{{
  fsolve(lambda j: (gammaincc(j,m1)+gammaincc(j,m2))/2-p, (m1+m2)/2.0)
  }}}

  We can generate the graph with the following command:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(fsolve(lambda j: (gammaincc(j,4)+gammaincc(j,20))/2-p, (12)/2.0)-0.5+1e-11,inv_exponential(r,12))\",progress" --save graph3.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 241062 of 241062 (100%)
  }}}

  The "`-0.5+1e-11`" term added above is just to make up for a rounding effect. We can get the same measurements as before,

  {{{
  $ graph-tool --load graph3.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        241062
  scalar assortativity coefficient:       -0.000600       0.002038
  }}}

  [[Image(degree-2poissons.png, nolink)]] [[Image(degree-uncorrelation3.png, nolink)]]

  ==== Combined in- and out-degree distributions ====

  Generating combined, i.e. not independent, in- and out-degree distributions is a little bit more complicated. Here it is described a relatively simple example. Suppose we want to generate the following joint degree distribution, which is the combination of two independent poisson distributions,

  [[Equation(\[ p(j,k) = \frac{1}{2}\frac{e^{-m_1}m_1^j}{j!}\frac{e^{-m_1}m_1^k}{k!} + \frac{1}{2}\frac{e^{-m_2}m_2^j}{j!}\frac{e^{-m_2}m_2^k}{k!}\])]].

  The cumulative degree distribution is the following,

  [[Equation(\[ P(j,k) = \frac{1}{2}\frac{\Gamma(j+1,m_1)\Gamma(k+1,m_1)}{j!k!} + \frac{1}{2}\frac{\Gamma(j+1,m_2)\Gamma(k+1,m_2)}{j!k!} \])]], which is already complicated to find the inverse (which will be some sort of curve in the jk-plane).

  So in order to sample from this distribution, it will be necessary to write something more complicated than an expression which can be squeezed in the "`inv_pjk_ceil`" option. For this reason, it is possible to define the sampling function in a file first, and then tell graph-tool to load it. Here's the definition of "`inv_pjk_ceil`" which will sample from the above distribution, defined in a file called "`joint_poissons.py`":

  {{{
  #!python
  from random import *

  def inv_pjk_ceil(p,r):
      if random() > 0.5:
          return (int(round(inv_poisson(p,4))),int(round(inv_poisson(r,4))))
      else:
          return (int(round(inv_poisson(p,20))),int(round(inv_poisson(r,20))))
  }}}

  This can be just about any valid python program that defines the function "`inv_pjk_ceil(p,r)`", which can include other packages and so forth. This way it is possible to implement just about any sampling routine. With this file in place, the graph can be generated with the following command

  {{{
   ../src/graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"file:joint_poissons.py\",progress" --save graph4.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 240456 of 240456 (100%)
  }}}

  When the "`inv_pjk_ceil`" parameter begins with "file:", it instructs the program to load it from the specified file. We can then check if eveything is correct:
  {{{
  $ graph-tool --load graph4.xml.bz2 --combined-degree-histogram="combined-degree-histogram"  --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-" 
  number of vertices:     20000
  number of edges:        240456
  scalar assortativity coefficient:       0.000398        0.002032
  }}}

  Below are plotted the theoretical and generated joint degree histograms,

  [[Image(joint-poissons-theoretical.png, nolink)]] [[Image(joint-poissons-generated.png, nolink)]]

  Voilà... Not too shabby.

  ==== Undirected Graphs ====

  A litte writeup about undirected graphs...

  -------

  === Correlated Graphs ===

  {{{
  #!html
  <div class="note">
  }}}
  ==== Important Note ====
  Degree correlations are dependent on the degree distribution. That means that not all degree correlations are possible, given a degree distribution. Therefore you must make sure that the degree correlation you're asking the program to generate is actually possible with the given degree distribution. If it's not, the obtained correlation is obviously not going to match what you asked, but that's not a bug. And even if the correlation is possible, it may even be required to make averages over several graphs, in order to obtain the expected correlation.
  {{{
  #!html
  </div>
  }}}

  ==== Undirected Graphs ====

  Let's take the simplest example, when all that is wanted in the end is an undirected graph with some degree correlation. In this case, when all that matters is the total degree of the vertices when it comes to degree correlations, the parameter "`undirected`" should be passed to the "`--correlated-configurational-model`" option.

  Since the degree distribution dictates what kind of correlations are possible, let's try here an homogeneous degree distribution [[Equation(\[P(k)=\frac{1}{100}[k<100]\])]], where all degrees up to 100 are equaly probable. That should give us some room over the degree correlation.

  ===== Assortative Degree Mixing =====

  So, here we'll generate a degree correlation so that vertices of a given type are connected to other vertices of similar type. We must define exactly what correlation we want, and we do this with the correlation function [[Equation(\[P(j',k'|j,k)\])]] which gives the probability that a random edge leaving a vertex with degrees [[Equation($j$)]] and [[Equation($k$)]] will connect to a vertex with degrees  [[Equation($j'$)]] and [[Equation($k'$)]]. Here we'll define the following,

  [[Equation(\[P(j',k'|j,k)=\frac{e^{-(j+k)}(j+k)^{j'+k'}}{(j'+k')!}\])]], which is a Poisson distribution with average [[Equation(\[j+k\])]], so that on average vertices will connect with other vertices of the same degree, leading to perfect assortative graph.

  We can generate such graph with the following command:
  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(r*p*100,(1-r)*p*100)\",inv_corr_ceil=\"(r*inv_poisson(p,j+k),(1-r)*inv_poisson(p,j+k))\",undirected,progress" --save graph.xml.bz2 
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 498225 of 498225 (100%)
  }}}

  And now we can check what was generated:

  {{{
  $ graph-tool --load graph.xml.bz2 --undirected --vertex-histogram="total-degree|degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        498225
  scalar assortativity coefficient:       0.926743        0.005064
  }}}

  The assortativity coefficient looks good. Here's the degree histogram and nearest neighbour correlation

  [[Image(uniform-degree-histogram.png, nolink)]] [[Image(degree-correlation-linear.png, nolink)]]

  Looks like it makes sense...

  ===== Disassortative Degree Mixing =====

  Let's try the other way, i.e., vertices of a given type connecting with the ones which are the most different. Let's define it the following way:

  [[Equation(\[P(j',k'|j,k)=\frac{e^{-(101-(j+k))}((101-(j+k))^{j'+k'}}{(j'+k')!}\])]], which, like above, is a Poisson distribution, but the average degree this time is [[Equation(\[101-(j+k)\])]], which means that, for instance, on average vertices of degree 100 will connect to vertices of degree 1, and vice versa. So let's try it:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(r*p*100,(1-r)*p*100)\",inv_corr_ceil=\"(r*inv_poisson(p,101-(j+k)),(1-r)*inv_poisson(p,101-(j+k)))\",undirected,progress" --save graph.xml.bz2 
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 503958 of 503958 (100%)
  }}}

  Checking the graph...

  {{{
  $ graph-tool --load graph.xml.bz2 --undirected --vertex-histogram="total-degree|degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        503958
  scalar assortativity coefficient:       -0.284408       0.005967
  }}}

  The assortativity coefficient is negative, which makes sense, but otherwise its absolute value is a little lower than expected with the specified correlation. Below are the degree histogram and neighbour correlation.

  [[Image(uniform-degree-histogram2.png, nolink)]] [[Image(degree-correlation-not-linear.png, nolink)]]

  Oops. What's wrong with the neighbour correlation? Wasn't it supposed to be linear? Well if you rembember the [[ref(Important Note)]] above, you'll realize that in this case the correlation we asked for is simply not possible. For instance, if all the vertices with degree 100 were connected mostly with vertices of degree 1, it would be necessary to have 100 times more vertices of degree 1 than of degree 100. Since the degree distribution is homogeneous, this is not possible. Let's try again, but this time with a more convenient degree distribution:

  [[Equation(\[P(k)=\frac{2}{100^2}(100-k)[k<100]\])]]

  ==== Directed Graphs ====


name: RandomGraphGeneration
author: count0
ipnr: 201.52.69.185
text:
  [[PageOutline]]
  = Random Graph Generation =

  graph-tool supports generation of random directed graphs with arbitrary degree distributions, based on the [http://arxiv.org/abs/cond-mat/0007235/ configurational model], with the addition of arbitrary degree correlations. The graph is generated with the "`--correlated-configurational-model`" option, which can take several parameters separated by commas. Here's a list of the parameters with a brief description:

  == Parameters ==
   '''`N`'''::
     The number of vertices in the network. This paramenter is mandatory.
   '''pjk'''::
     The joint '''''cumulative''''' degree distribution [[Equation(\[P(j,k) = \sum_{j'\leq j}\sum_{k'\leq k} p(j',k')\])]] of the graph. This parameter is only used when the inverse of this function cannot be easily provided in the '''inv_pjk_ceil''' parameter. In that case a propper "ceil" function must be chosen and its inverse must be specified in the '''inv_pjk_ceil''' parameter instead, as well as the '''pjk_ceil''' and '''pjk_m''' parameters.
   '''pjk_ceil'''::
     This is the ceil function for the '''pjk''' parameter, which must be specified if '''pjk''' cannot be easily inverted. Defaults to  '''pjk(j,k)''' if unspecified.
   '''pjk_m'''::
     This is the maximum ratio '''pjk_ceil/pjk'''. Defaults to 1.0.
   '''inv_pjk_ceil''':: 
     This is the inverse of the cumulative ceil joint degree distribution (or the distribution itself when it's inversible). This is the parameter which will be more frequently used when setting the joint degree distribution, and is a required parameter. It sould be defined as a [http://www.python.org python] expression, defining a tuple of size 2 for the sampled (j,k) degrees. The parameters are two random variables `p` and `r`, uniformly distributed in the range [0,1[.  Some predefined functions include "`inv_poisson(p,m)`" for an inverse poisson function with average "`m`", "`inv_exponential(p,m)`" for an inverse exponential distribution with average "`m`", and "`inv_power_law(p,b)`" for an inverse power-law distribution with exponent "`-b`". See below for various examples of how to use this parameter.
   '''corr'''::
     This is the cumulative correlation distribution, defined as [[Equation(\[P(j',k'|j,k) = \sum_{j''\leq j'}\sum_{k''\leq k'} p(j'',k''|j,k)\])]], where [[Equation(\[p(j',k'|j,k)\])]] is the probability that a randomly chosen edge leaving a (j,k) vertex will be connected to a (j',k') vertex. This parameter should only be used when the inverse of this function cannot be directly provided in the '''inv_corr_ceil''' parameters. In that case, like with the joint degree distribution, the '''corr_ceil''', '''corr_m''' and '''inv_corr_ceil''' parameters must be properly set.
    '''corr_ceil'''::
     This is the ceil function for the '''corr''' paramenter, which must be specified if '''corr''' cannot be easily inverted. Defaults to '''corr(jl,kl,j,k)''' if unspecified.
   '''corr_m'''::
     This is the maximum ratio '''corr_ceil/corr'''. Defaults to 1.0.
   '''inv_corr_ceil'''::
     This is the inverse of the cumulative ceil correlation distribution (or the distribution itself, as defined above, if inversible). The available variables are `j` and `k`, for the in and out degree of the origin, and two random variables `p` and `r`. This defaults to the uncorrelated case '''inv_corr_ceil=inv_pjk_ceil(p,r)'''. See below for examples.
   '''undirected'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices with the closest total degree j+k.
   '''directed'''::
     This option controls how edge targets are chosen in respect to their in and out degrees. If an edge is supposed to connect to a vertex with (j,k), but no such vertex exists, this options says it should connect randomly to one of the vertices which is closest in the jk-plane. This is the default.
   '''progress'''::
     This option displays useful progress information in the terminal.
   '''seed'''::
     This options sets the seed value for the random number generator. It is taken from the computer clock if unspecified.

  ---------

  == Tutorial & Examples ==

  === Uncorrelated Graphs ===

  ==== Independent and equal in-out distributions ====

  Let's start with a simple uncorrelated graph with poisson degree distribution, to get our feets wet:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_poisson(p,5),inv_poisson(r,5))\",progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99744 of 99744 (100%)
  }}}

  The generated graph is then saved in "`graph.xml.bz2`". We can get some measurements out of it to see if things make sense or not:

  {{{
  $ graph-tool --load graph.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99744
  scalar assortativity coefficient:       -0.000422       0.003175
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-poisson.png, nolink)]] [[Image(degree-uncorrelation.png, nolink)]]



  So, things seem to make sense so far.  Let's try with something a little bit more unusual...

  ==== Independent but different in-out distributions ====

  Suppose you want different in- and out-degree distributions, like one exponential, and the other a poisson:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(inv_exponential(p,5),inv_poisson(r,5))\",progress" --save graph2.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 99731 of 99731 (100%)
  }}}

  Getting the same measurements...

  {{{
  $ graph-tool --load graph2.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        99731
  scalar assortativity coefficient:       0.003840        0.003188
  }}}

  Below are ploted the degree distributions and degree correlation obtained with the above command.

  [[Image(degree-exp-poisson.png, nolink)]] [[Image(degree-uncorrelation2.png, nolink)]]

  ==== More elaborate in-out distributions ====

  Suppose we want some other expression for the degree distribution that we want to specify ourselves. Supose our in-degree distribution is composed of two poisson distributions with different averages, and the out-degree distribution is an exponential. Our in-degree distribution can be written as such:

  [[Equation(\[p(j)=\frac{e^{-m_1}m_1^j+e^{-m_2}m_2^j}{2j!}\])]]. The cumulative distribution is then [[Equation(\[P(j)=\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}\])]].

  The inverse of the cumulative distribution is the solution of [[Equation(\[\frac{\Gamma(j+1,m_1) + \Gamma(j+1,m_2)}{2j!}-P=0\])]] for [[Equation($j$)]]. We can use "`fsolve`" function from the [http://www.scipy.org scipy] package (which is included automatically if available) to write it as such:
  {{{
  fsolve(lambda j: (gammaincc(j,m1)+gammaincc(j,m2))/2-p, (m1+m2)/2.0)
  }}}

  We can generate the graph with the following command:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(fsolve(lambda j: (gammaincc(j,4)+gammaincc(j,20))/2-p, (12)/2.0)-0.5+1e-11,inv_exponential(r,12))\",progress" --save graph3.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 241062 of 241062 (100%)
  }}}

  The "`-0.5+1e-11`" term added above is just to make up for a rounding effect. We can get the same measurements as before,

  {{{
  $ graph-tool --load graph3.xml.bz2 --vertex-histogram="in-degree|in-degree-histogram" --vertex-histogram="out-degree|out-degree-histogram" --vertex-histogram="total-degree|total-degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        241062
  scalar assortativity coefficient:       -0.000600       0.002038
  }}}

  [[Image(degree-2poissons.png, nolink)]] [[Image(degree-uncorrelation3.png, nolink)]]

  ==== Combined in- and out-degree distributions ====

  Generating combined, i.e. not independent, in- and out-degree distributions is a little bit more complicated. Here it is described a relatively simple example. Suppose we want to generate the following joint degree distribution, which is the combination of two independent poisson distributions,

  [[Equation(\[ p(j,k) = \frac{1}{2}\frac{e^{-m_1}m_1^j}{j!}\frac{e^{-m_1}m_1^k}{k!} + \frac{1}{2}\frac{e^{-m_2}m_2^j}{j!}\frac{e^{-m_2}m_2^k}{k!}\])]].

  The cumulative degree distribution is the following,

  [[Equation(\[ P(j,k) = \frac{1}{2}\frac{\Gamma(j+1,m_1)\Gamma(k+1,m_1)}{j!k!} + \frac{1}{2}\frac{\Gamma(j+1,m_2)\Gamma(k+1,m_2)}{j!k!} \])]], which is already complicated to find the inverse (which will be some sort of curve in the jk-plane).

  So in order to sample from this distribution, it will be necessary to write something more complicated than an expression which can be squeezed in the "`inv_pjk_ceil`" option. For this reason, it is possible to define the sampling function in a file first, and then tell graph-tool to load it. Here's the definition of "`inv_pjk_ceil`" which will sample from the above distribution, defined in a file called "`joint_poissons.py`":

  {{{
  #!python
  from random import *

  def inv_pjk_ceil(p,r):
      if random() > 0.5:
          return (int(round(inv_poisson(p,4))),int(round(inv_poisson(r,4))))
      else:
          return (int(round(inv_poisson(p,20))),int(round(inv_poisson(r,20))))
  }}}

  This can be just about any valid python program that defines the function "`inv_pjk_ceil(p,r)`", which can include other packages and so forth. This way it is possible to implement just about any sampling routine. With this file in place, the graph can be generated with the following command

  {{{
   ../src/graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"file:joint_poissons.py\",progress" --save graph4.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 240456 of 240456 (100%)
  }}}

  When the "`inv_pjk_ceil`" parameter begins with "file:", it instructs the program to load it from the specified file. We can then check if eveything is correct:
  {{{
  $ graph-tool --load graph4.xml.bz2 --combined-degree-histogram="combined-degree-histogram"  --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-" 
  number of vertices:     20000
  number of edges:        240456
  scalar assortativity coefficient:       0.000398        0.002032
  }}}

  Below are plotted the theoretical and generated joint degree histograms,

  [[Image(joint-poissons-theoretical.png, nolink)]] [[Image(joint-poissons-generated.png, nolink)]]

  Voilà... Not too shabby.

  ==== Undirected Graphs ====

  A litte writeup about undirected graphs...

  -------

  === Correlated Graphs ===

  {{{
  #!html
  <div class="note">
  }}}
  ==== Important Note ====
  Degree correlations are dependent on the degree distribution. That means that not all degree correlations are possible, given a degree distribution. Therefore you must make sure that the degree correlation you're asking the program to generate is actually possible with the given degree distribution. If it's not, the obtained correlation is obviously not going to match what you asked, but that's not a bug. And even if the correlation is possible, it may even be required to make averages over several graphs, in order to obtain the expected correlation.
  {{{
  #!html
  </div>
  }}}

  ==== Undirected Graphs ====

  Let's take the simplest example, when all that is wanted in the end is an undirected graph with some degree correlation. In this case, when all that matters is the total degree of the vertices when it comes to degree correlations, the parameter "`undirected`" should be passed to the "`--correlated-configurational-model`" option.

  Since the degree distribution dictates what kind of correlations are possible, let's try here an homogeneous degree distribution [[Equation(\[P(k)=\frac{1}{100}[k<100]\])]], where all degrees up to 100 are equaly probable. That should give us some room over the degree correlation.

  ===== Assortative Degree Mixing =====

  So, here we'll generate a degree correlation so that vertices of a given type are connected to other vertices of similar type. We must define exactly what correlation we want, and we do this with the correlation function [[Equation(\[P(j',k'|j,k)\])]] which gives the probability that a random edge leaving a vertex with degrees [[Equation($j$)]] and [[Equation($k$)]] will connect to a vertex with degrees  [[Equation($j'$)]] and [[Equation($k'$)]]. Here we'll define the following,

  [[Equation(\[P(j',k'|j,k)=\frac{e^{-(j+k)}(j+k)^{j'+k'}}{(j'+k')!}\])]], which is a Poisson distribution with average [[Equation(\[j+k\])]], so that on average vertices will connect with other vertices of the same degree, leading to perfect assortative graph.

  We can generate such graph with the following command:
  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(r*p*100,(1-r)*p*100)\",inv_corr_ceil=\"(r*inv_poisson(p,j+k),(1-r)*inv_poisson(p,j+k))\",undirected,progress" --save graph.xml.bz2 
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 498225 of 498225 (100%)
  }}}

  And now we can check what was generated:

  {{{
  $ graph-tool --load graph.xml.bz2 --undirected --vertex-histogram="total-degree|degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        498225
  scalar assortativity coefficient:       0.926743        0.005064
  }}}

  The assortativity coefficient looks good. Here's the degree histogram and nearest neighbour correlation

  [[Image(uniform-degree-histogram.png, nolink)]] [[Image(degree-correlation-linear.png, nolink)]]

  Looks like it makes sense...

  ===== Disassortative Degree Mixing =====

  Let's try the other way, i.e., vertices of a given type connecting with the ones which are the most different. Let's define it the following way:

  [[Equation(\[P(j',k'|j,k)=\frac{e^{-(101-(j+k))}((101-(j+k))^{j'+k'}}{(j'+k')!}\])]], which, like above, is a Poisson distribution, but the average degree this time is [[Equation(\[101-(j+k)\])]], which means that, for instance, on average vertices of degree 100 will connect to vertices of degree 1, and vice versa. So let's try it:

  {{{
  $ graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(r*p*100,(1-r)*p*100)\",inv_corr_ceil=\"(r*inv_poisson(p,101-(j+k)),(1-r)*inv_poisson(p,101-(j+k)))\",undirected,progress" --save graph.xml.bz2 
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 503958 of 503958 (100%)
  }}}

  Checking the graph...

  {{{
  $ graph-tool --load graph.xml.bz2 --undirected --vertex-histogram="total-degree|degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        503958
  scalar assortativity coefficient:       -0.284408       0.005967
  }}}

  The assortativity coefficient is negative, which makes sense, but otherwise its absolute value is a little lower than expected with the specified correlation. Below are the degree histogram and neighbour correlation.

  [[Image(uniform-degree-histogram2.png, nolink)]] [[Image(degree-correlation-not-linear.png, nolink)]]

  Oops. What's wrong with the neighbour correlation? Wasn't it supposed to be linear? Well if you rembember the [[ref(Important Note)]] above, you'll realize that in this case the correlation we asked for is simply not possible. For instance, if all the vertices with degree 100 were connected mostly with vertices of degree 1, it would be necessary to have 100 times more vertices of degree 1 than of degree 100. Since the degree distribution is homogeneous, this is not possible. Let's try again, but this time with a more convenient degree distribution:

  [[Equation(\[P(k)=\frac{2}{100^2}(100-k)[k<100]\])]]

  Generating the graph:
  {{{
  ./src/graph-tool --correlated-configurational-model="N=20000,inv_pjk_ceil=\"(r*(199-sqrt(199**2 -4*100**2*0.99*p))/2,(1-r)*(199-sqrt(199**2 -4*100**2*0.99*p))/2)\",inv_corr_ceil=\"(r*inv_poisson(p,101-(j+k)),(1-r)*inv_poisson(p,101-(j+k)))\",undirected,progress" --save graph.xml.bz2
  adding vertices: 20000 of 20000 (100%)
  fixing average degrees: 0
  adding edges: 330393 of 330393 (100%)
  }}}

  Checking it:
  {{{
  $ graph-tool --load graph.xml.bz2 --undirected --vertex-histogram="total-degree|degree-histogram" --average-nearest-neighbours-correlation="total-degree|total-degree|total-degree-correlation" --number-of-vertices=- --number-of-edges=- --scalar-assortativity-coefficient="total-degree|-"
  number of vertices:     20000
  number of edges:        330393
  scalar assortativity coefficient:       -0.928880       0.005233
  }}}

  The assortativity coefficient is telling a good story. Let's check the rest:

  [[Image(decreasing-degree-histogram.png, nolink)]] [[Image(degree-correlation-linear2.png, nolink)]]

  Looks better.

  ==== Directed Graphs ====


