diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 0cfb616..d729c30 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-10-21T17:57:30","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-11-06T20:24:01","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/dev/api/index.html b/dev/api/index.html index cf71c3b..c82205a 100644 --- a/dev/api/index.html +++ b/dev/api/index.html @@ -1,5 +1,5 @@ -API reference · MetaGraphsNext.jl

API reference

Docstrings

MetaGraphsNext.DOTFormatType
struct DOTFormat <: AbstractGraphFormat end

If all metadata types support pairs or are Nothing, you can save MetaGraphs in DOTFormat.

source
MetaGraphsNext.MetaGraphType
MetaGraph{
+API reference · MetaGraphsNext.jl

API reference

Docstrings

MetaGraphsNext.DOTFormatType
struct DOTFormat <: AbstractGraphFormat end

If all metadata types support pairs or are Nothing, you can save MetaGraphs in DOTFormat.

source
MetaGraphsNext.MetaGraphType
MetaGraph{
     Code<:Integer,
     Graph<:AbstractGraph{Code},
     Label,
@@ -8,7 +8,7 @@
     GraphData,
     WeightFunction,
     Weight
-} <: AbstractGraph{Code}

A graph type with custom vertex labels containing vertex-, edge- and graph-level metadata.

Vertex labels have type Label, while vertex (resp. edge, resp. graph) metadata has type VertexData (resp. EdgeData, resp. GraphData). It is recommended not to set Label to an integer type, so as to avoid confusion between vertex labels (which do not change as the graph evolves) and vertex codes (which have type Code<:Integer and can change as the graph evolves).

Fields

  • graph::Graph: underlying, data-less graph with vertex codes of type Code
  • vertex_labels::Dict{Code,Label}: dictionary mapping vertex codes to vertex labels
  • vertex_properties::Dict{Label,Tuple{Code,VertexData}}: dictionary mapping vertex labels to vertex codes & metadata
  • edge_data::Dict{Tuple{Label,Label},EdgeData}: dictionary mapping edge labels such as (label_u, label_v) to edge metadata
  • graph_data::GraphData: metadata for the graph object as a whole
  • weight_function::WeightFunction: function computing edge weight from edge metadata, its output must have the same type as default_weight
  • default_weight::Weight: default weight used when an edge doesn't exist
source
MetaGraphsNext.MetaGraphMethod
MetaGraph(
+} <: AbstractGraph{Code}

A graph type with custom vertex labels containing vertex-, edge- and graph-level metadata.

Vertex labels have type Label, while vertex (resp. edge, resp. graph) metadata has type VertexData (resp. EdgeData, resp. GraphData). It is recommended not to set Label to an integer type, so as to avoid confusion between vertex labels (which do not change as the graph evolves) and vertex codes (which have type Code<:Integer and can change as the graph evolves).

Fields

  • graph::Graph: underlying, data-less graph with vertex codes of type Code
  • vertex_labels::Dict{Code,Label}: dictionary mapping vertex codes to vertex labels
  • vertex_properties::Dict{Label,Tuple{Code,VertexData}}: dictionary mapping vertex labels to vertex codes & metadata
  • edge_data::Dict{Tuple{Label,Label},EdgeData}: dictionary mapping edge labels such as (label_u, label_v) to edge metadata
  • graph_data::GraphData: metadata for the graph object as a whole
  • weight_function::WeightFunction: function computing edge weight from edge metadata, its output must have the same type as default_weight
  • default_weight::Weight: default weight used when an edge doesn't exist
source
MetaGraphsNext.MetaGraphMethod
MetaGraph(
     graph;
     label_type,
     vertex_data_type=Nothing,
@@ -16,14 +16,14 @@
     graph_data=nothing,
     weight_function=edge_data -> 1.0,
     default_weight=1.0
-)

Construct an empty MetaGraph based on an empty graph, initializing storage with metadata types given as keyword arguments.

Warning

This constructor uses keyword arguments for convenience, which means it is type-unstable.

source
MetaGraphsNext.MetaGraphMethod
MetaGraph(
+)

Construct an empty MetaGraph based on an empty graph, initializing storage with metadata types given as keyword arguments.

Warning

This constructor uses keyword arguments for convenience, which means it is type-unstable.

source
MetaGraphsNext.MetaGraphMethod
MetaGraph(
     graph,
     vertices_description,
     edges_description,
     graph_data=nothing,
     weight_function=edge_data -> 1.0,
     default_weight=1.0,
-)

Construct a non-empty MetaGraph based on a non-empty graph with specified vertex and edge data, given as positional arguments.

The data must be given as follows:

  • vertices_description is a vector of pairs label => data (the code of a vertex will correspond to its rank in the list)
  • edges_description is a vector of pairs (label1, label2) => data

Furthermore, these arguments must be coherent with the graph argument, i.e. describe the same set of vertices and edges.

source
MetaGraphsNext.MetaGraphMethod
MetaGraph(
+)

Construct a non-empty MetaGraph based on a non-empty graph with specified vertex and edge data, given as positional arguments.

The data must be given as follows:

  • vertices_description is a vector of pairs label => data (the code of a vertex will correspond to its rank in the list)
  • edges_description is a vector of pairs (label1, label2) => data

Furthermore, these arguments must be coherent with the graph argument, i.e. describe the same set of vertices and edges.

source
MetaGraphsNext.MetaGraphMethod
MetaGraph(
     graph,
     label_type,
     vertex_data_type=Nothing,
@@ -31,4 +31,4 @@
     graph_data=nothing,
     weight_function=edge_data -> 1.0,
     default_weight=1.0
-)

Construct an empty MetaGraph based on an empty graph, initializing storage with metadata types given as positional arguments.

source
Base.delete!Method
delete!(meta_graph, label_1, label_2)

Delete edge (label_1, label_2).

source
Base.getindexMethod
getindex(meta_graph, label_1, label_2)

Return edge metadata for the edge between label_1 and label_2.

source
Base.getindexMethod
getindex(meta_weights::MetaWeights, code_1, code_2)

Get the weight of edge (code_1, code_2).

source
Base.haskeyMethod
haskey(meta_graph, label_1, label_2)

Determine whether a metagraph `metagraphcontains an edge fromlabel1tolabel2`.

The order of label_1 and label_2 only matters if meta_graph is a digraph.

source
Base.haskeyMethod
haskey(meta_graph, label)

Determine whether a metagraph `metagraphcontains the vertexlabel`.

source
Base.setindex!Method
setindex!(meta_graph, data, label_1, label_2)

Set edge metadata for (label_1, label_2) to data.

source
Base.setindex!Method
setindex!(meta_graph, data, label)

Set vertex metadata for label to data.

source
Graphs.SimpleGraphs.add_edge!Method
add_edge!(meta_graph, label_1, label_2, data)

Add an edge (label_1, label_2) to MetaGraph meta_graph with metadata data. If the EdgeData type of meta_graph is Nothing, data can be omitted.

Return true if the edge has been added, false otherwise. If one of the labels does not exist, nothing happens and false is returned (the label is not inserted). If (label_1, label_2) already exists, its data is updated to data and false is returned nonetheless.

source
Graphs.SimpleGraphs.add_vertex!Method
add_vertex!(meta_graph, label, data)

Add a vertex to MetaGraph meta_graph with label label having metadata data. If the VertexData type of meta_graph is Nothing, data can be omitted.

Return true if the vertex has been added, false in case the label already exists or vertex was not added.

source
Graphs.weightsMethod
weights(meta_graph)

Return a matrix-like MetaWeights object containing the edge weights for metagraph meta_graph.

source
MetaGraphsNext._copy_props!Method
_copy_props!(old_meta_graph, new_meta_graph, code_map)

Copy properties from old_meta_graph to new_meta_graph following vertex map code_map.

source
MetaGraphsNext.all_neighbor_labelsMethod
all_neighbor_labels(meta_graph, label)

Iterate through all labels of all neighbors of the vertex code with label label, in the same order as the codes obtained by all_neighbors(meta_graph, code).

source
MetaGraphsNext.arrangeFunction
arrange(graph, label_1, label_2)

Sort two vertex labels in a default order (useful to uniquely express undirected edges). For undirected graphs, the default order is based on the labels themselves to be robust to vertex re-coding, so the labels need to support <.

source
MetaGraphsNext.code_forMethod
code_for(meta_graph::MetaGraph, label)

Find the vertex code (or index) associated with label label.

This can be useful to pass to methods inherited from Graphs. Note, however, that vertex codes can be reassigned after vertex deletion.

source
MetaGraphsNext.edge_labelsMethod
edge_labels(meta_graph)

Iterate through all tuples of edge labels, in the same order as the tuples of codes obtained by edges(meta_graph).

source
MetaGraphsNext.inneighbor_labelsMethod
inneighbor_labels(meta_graph, label)

Iterate through all labels of inneighbors of the vertex code with label label, in the same order as the codes obtained by inneighbors(meta_graph, code).

source
MetaGraphsNext.label_forMethod
label_for(meta_graph::MetaGraph, code)

Find the label associated with code code.

This can be useful to interpret the results of methods inherited from Graphs. Note, however, that vertex codes can be reassigned after vertex deletion.

source
MetaGraphsNext.labelsMethod
labels(meta_graph)

Iterate through all vertex labels, in the same order as the codes obtained by vertices(meta_graph).

source
MetaGraphsNext.neighbor_labelsMethod
neighbor_labels(meta_graph, label)

Iterate through all labels of neighbors of the vertex code with label label, in the same order as the codes obtained by neighbors(meta_graph, code).

source
MetaGraphsNext.outneighbor_labelsMethod
outneighbor_labels(meta_graph, label)

Iterate through all labels of outneighbors of the vertex code with label label, in the same order as the codes obtained by outneighbors(meta_graph, code).

source
MetaGraphsNext.set_data!Method
set_data!(meta_graph, label_1, label_2, data)

Set edge metadata for (label_1, label_2) to data.

Return true if the operation succeeds, and false if meta_graph has no such edge.

source
MetaGraphsNext.set_data!Method
set_data!(meta_graph, label, data)

Set vertex metadata for label to data.

Return true if the operation succeeds, and false if meta_graph has no such vertex.

source
Base.haskeyFunction
haskey(meta_graph, label)

Determine whether a metagraph `metagraphcontains the vertexlabel`.

source
haskey(meta_graph, label_1, label_2)

Determine whether a metagraph `metagraphcontains an edge fromlabel1tolabel2`.

The order of label_1 and label_2 only matters if meta_graph is a digraph.

source
Base.getindexFunction
getindex(meta_graph)

Return meta_graph metadata.

source
getindex(meta_graph, label)

Return vertex metadata for label.

source
getindex(meta_graph, label_1, label_2)

Return edge metadata for the edge between label_1 and label_2.

source
getindex(meta_weights::MetaWeights, code_1, code_2)

Get the weight of edge (code_1, code_2).

source
Base.setindex!Function
setindex!(meta_graph, data, label)

Set vertex metadata for label to data.

source
setindex!(meta_graph, data, label_1, label_2)

Set edge metadata for (label_1, label_2) to data.

source
Base.delete!Function
delete!(meta_graph, label)

Delete vertex label.

source
delete!(meta_graph, label_1, label_2)

Delete edge (label_1, label_2).

source
Graphs.SimpleGraphs.add_vertex!Function
add_vertex!(meta_graph, label, data)

Add a vertex to MetaGraph meta_graph with label label having metadata data. If the VertexData type of meta_graph is Nothing, data can be omitted.

Return true if the vertex has been added, false in case the label already exists or vertex was not added.

source
Graphs.SimpleGraphs.add_edge!Function
add_edge!(meta_graph, label_1, label_2, data)

Add an edge (label_1, label_2) to MetaGraph meta_graph with metadata data. If the EdgeData type of meta_graph is Nothing, data can be omitted.

Return true if the edge has been added, false otherwise. If one of the labels does not exist, nothing happens and false is returned (the label is not inserted). If (label_1, label_2) already exists, its data is updated to data and false is returned nonetheless.

source
Graphs.weightsFunction
weights(meta_graph)

Return a matrix-like MetaWeights object containing the edge weights for metagraph meta_graph.

source

Index

+)

Construct an empty MetaGraph based on an empty graph, initializing storage with metadata types given as positional arguments.

source
Base.delete!Method
delete!(meta_graph, label_1, label_2)

Delete edge (label_1, label_2).

source
Base.getindexMethod
getindex(meta_graph, label_1, label_2)

Return edge metadata for the edge between label_1 and label_2.

source
Base.getindexMethod
getindex(meta_weights::MetaWeights, code_1, code_2)

Get the weight of edge (code_1, code_2).

source
Base.haskeyMethod
haskey(meta_graph, label_1, label_2)

Determine whether a MetaGraph meta_graph contains an edge from label_1 to label_2.

The order of label_1 and label_2 only matters if meta_graph is a digraph.

source
Base.haskeyMethod
haskey(meta_graph, label)

Determine whether a MetaGraph meta_graph contains the vertex label.

source
Base.setindex!Method
setindex!(meta_graph, data, label_1, label_2)

Set edge metadata for (label_1, label_2) to data.

source
Base.setindex!Method
setindex!(meta_graph, data, label)

Set vertex metadata for label to data.

source
Graphs.SimpleGraphs.add_edge!Method
add_edge!(meta_graph, label_1, label_2, data)

Add an edge (label_1, label_2) to MetaGraph meta_graph with metadata data. If the EdgeData type of meta_graph is Nothing, data can be omitted.

Return true if the edge has been added, false otherwise. If one of the labels does not exist, nothing happens and false is returned (the label is not inserted). If (label_1, label_2) already exists, its data is updated to data and false is returned nonetheless.

source
Graphs.SimpleGraphs.add_vertex!Method
add_vertex!(meta_graph, label, data)

Add a vertex to MetaGraph meta_graph with label label having metadata data. If the VertexData type of meta_graph is Nothing, data can be omitted.

Return true if the vertex has been added, false in case the label already exists or vertex was not added.

source
Graphs.weightsMethod
weights(meta_graph)

Return a matrix-like MetaWeights object containing the edge weights for metagraph meta_graph.

source
MetaGraphsNext._copy_props!Method
_copy_props!(old_meta_graph, new_meta_graph, code_map)

Copy properties from old_meta_graph to new_meta_graph following vertex map code_map.

source
MetaGraphsNext.all_neighbor_labelsMethod
all_neighbor_labels(meta_graph, label)

Iterate through all labels of all neighbors of the vertex code with label label, in the same order as the codes obtained by all_neighbors(meta_graph, code).

source
MetaGraphsNext.arrangeFunction
arrange(graph, label_1, label_2)

Sort two vertex labels in a default order (useful to uniquely express undirected edges). For undirected graphs, the default order is based on the labels themselves to be robust to vertex re-coding, so the labels need to support <.

source
MetaGraphsNext.code_forMethod
code_for(meta_graph::MetaGraph, label)

Find the vertex code (or index) associated with label label.

This can be useful to pass to methods inherited from Graphs. Note, however, that vertex codes can be reassigned after vertex deletion.

source
MetaGraphsNext.edge_labelsMethod
edge_labels(meta_graph)

Iterate through all tuples of edge labels, in the same order as the tuples of codes obtained by edges(meta_graph).

source
MetaGraphsNext.inneighbor_labelsMethod
inneighbor_labels(meta_graph, label)

Iterate through all labels of inneighbors of the vertex code with label label, in the same order as the codes obtained by inneighbors(meta_graph, code).

source
MetaGraphsNext.label_forMethod
label_for(meta_graph::MetaGraph, code)

Find the label associated with code code.

This can be useful to interpret the results of methods inherited from Graphs. Note, however, that vertex codes can be reassigned after vertex deletion.

source
MetaGraphsNext.labelsMethod
labels(meta_graph)

Iterate through all vertex labels, in the same order as the codes obtained by vertices(meta_graph).

source
MetaGraphsNext.neighbor_labelsMethod
neighbor_labels(meta_graph, label)

Iterate through all labels of neighbors of the vertex code with label label, in the same order as the codes obtained by neighbors(meta_graph, code).

source
MetaGraphsNext.outneighbor_labelsMethod
outneighbor_labels(meta_graph, label)

Iterate through all labels of outneighbors of the vertex code with label label, in the same order as the codes obtained by outneighbors(meta_graph, code).

source
MetaGraphsNext.set_data!Method
set_data!(meta_graph, label_1, label_2, data)

Set edge metadata for (label_1, label_2) to data.

Return true if the operation succeeds, and false if meta_graph has no such edge.

source
MetaGraphsNext.set_data!Method
set_data!(meta_graph, label, data)

Set vertex metadata for label to data.

Return true if the operation succeeds, and false if meta_graph has no such vertex.

source
Base.haskeyFunction
haskey(meta_graph, label)

Determine whether a MetaGraph meta_graph contains the vertex label.

source
haskey(meta_graph, label_1, label_2)

Determine whether a MetaGraph meta_graph contains an edge from label_1 to label_2.

The order of label_1 and label_2 only matters if meta_graph is a digraph.

source
Base.getindexFunction
getindex(meta_graph)

Return meta_graph metadata.

source
getindex(meta_graph, label)

Return vertex metadata for label.

source
getindex(meta_graph, label_1, label_2)

Return edge metadata for the edge between label_1 and label_2.

source
getindex(meta_weights::MetaWeights, code_1, code_2)

Get the weight of edge (code_1, code_2).

source
Base.setindex!Function
setindex!(meta_graph, data, label)

Set vertex metadata for label to data.

source
setindex!(meta_graph, data, label_1, label_2)

Set edge metadata for (label_1, label_2) to data.

source
Base.delete!Function
delete!(meta_graph, label)

Delete vertex label.

source
delete!(meta_graph, label_1, label_2)

Delete edge (label_1, label_2).

source
Graphs.SimpleGraphs.add_vertex!Function
add_vertex!(meta_graph, label, data)

Add a vertex to MetaGraph meta_graph with label label having metadata data. If the VertexData type of meta_graph is Nothing, data can be omitted.

Return true if the vertex has been added, false in case the label already exists or vertex was not added.

source
Graphs.SimpleGraphs.add_edge!Function
add_edge!(meta_graph, label_1, label_2, data)

Add an edge (label_1, label_2) to MetaGraph meta_graph with metadata data. If the EdgeData type of meta_graph is Nothing, data can be omitted.

Return true if the edge has been added, false otherwise. If one of the labels does not exist, nothing happens and false is returned (the label is not inserted). If (label_1, label_2) already exists, its data is updated to data and false is returned nonetheless.

source
Graphs.weightsFunction
weights(meta_graph)

Return a matrix-like MetaWeights object containing the edge weights for metagraph meta_graph.

source

Index

diff --git a/dev/index.html b/dev/index.html index 0f75a10..e7c1fde 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · MetaGraphsNext.jl

MetaGraphsNext.jl

Welcome to MetaGraphsNext.jl, a type-stable replacement for MetaGraphs.jl. It allows you to create graphs with vertex and edge metadata, on which you can unleash the full power of the Graphs.jl ecosystem.

Getting started

To install the package, open the Julia REPL and type

julia> using Pkg; Pkg.add("MetaGraphsNext")
+Home · MetaGraphsNext.jl

MetaGraphsNext.jl

Welcome to MetaGraphsNext.jl, a type-stable replacement for MetaGraphs.jl. It allows you to create graphs with vertex and edge metadata, on which you can unleash the full power of the Graphs.jl ecosystem.

Getting started

To install the package, open the Julia REPL and type

julia> using Pkg; Pkg.add("MetaGraphsNext")
diff --git a/dev/search_index.js b/dev/search_index.js index 691abcd..9fdb070 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"EditURL = \"../../../test/tutorial/5_benchmark.jl\"","category":"page"},{"location":"tutorial/5_benchmark/#Benchmark","page":"Benchmark","title":"Benchmark","text":"","category":"section"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"Here we compare the performance of MetaGraphsNext.jl with its predecessor MetaGraphs.jl.","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"using BenchmarkTools\nusing Graphs\nusing InteractiveUtils\nusing MetaGraphs: MetaGraphs\nusing MetaGraphsNext: MetaGraphsNext","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"The benchmarking task is two-fold:","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"Build a complete graph with random boolean metadata on the vertices (active) and float metadata on the edges (distance)\nCompute the sum of distances for all edges whose endpoints are both active.","category":"page"},{"location":"tutorial/5_benchmark/#Graph-construction","page":"Benchmark","title":"Graph construction","text":"","category":"section"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function build_incremental_metagraphsnext(n)\n g = Graph(0)\n mg = MetaGraphsNext.MetaGraph(\n g;\n label_type=Int, # this will throw a warning\n vertex_data_type=Bool,\n edge_data_type=Float64,\n )\n for li in 1:n\n mg[li] = rand(Bool)\n end\n for li in 1:n, lj in 1:(li - 1)\n mg[li, lj] = rand(Float64)\n end\n return mg\nend;\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function build_bulk_metagraphsnext(n)\n g = complete_graph(n)\n vertices_description = [li => rand(Bool) for li in 1:n]\n edges_description = [(li, lj) => rand(Float64) for li in 1:n for lj in 1:(li - 1)]\n mg = MetaGraphsNext.MetaGraph(g, vertices_description, edges_description;)\n return mg\nend;\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function build_metagraphs(n)\n g = complete_graph(n)\n mg = MetaGraphs.MetaGraph(g)\n for i in 1:n\n MetaGraphs.set_prop!(mg, i, :active, rand(Bool))\n end\n for i in 1:n, j in 1:(i - 1)\n MetaGraphs.set_prop!(mg, i, j, :distance, rand(Float64))\n end\n return mg\nend;\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@btime build_incremental_metagraphsnext(100);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@btime build_bulk_metagraphsnext(100);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@btime build_metagraphs(100);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/#Graph-exploitation","page":"Benchmark","title":"Graph exploitation","text":"","category":"section"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function sum_active_edges_metagraphsnext(mg)\n S = 0.0\n for (li, lj) in MetaGraphsNext.edge_labels(mg)\n active_i = mg[li]\n active_j = mg[lj]\n distance_ij = mg[li, lj]\n if active_i && active_j\n S += distance_ij\n end\n end\n return S\nend","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function sum_active_edges_metagraphs(mg)\n S = 0.0\n for e in edges(mg)\n i, j = src(e), dst(e)\n active_i = MetaGraphs.get_prop(mg, i, :active)\n active_j = MetaGraphs.get_prop(mg, j, :active)\n distance_ij = MetaGraphs.get_prop(mg, i, j, :distance)\n if active_i && active_j\n S += distance_ij\n end\n end\n return S\nend","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"mg1 = build_incremental_metagraphsnext(100);\n@btime sum_active_edges_metagraphsnext($mg1);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"mg2 = build_metagraphs(100);\n@btime sum_active_edges_metagraphs($mg2);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"The difference in performance can be explained by type instability.","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@code_warntype sum_active_edges_metagraphsnext(mg1);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@code_warntype sum_active_edges_metagraphs(mg2);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"This page was generated using Literate.jl.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"EditURL = \"../../../test/tutorial/1_basics.jl\"","category":"page"},{"location":"tutorial/1_basics/#Basics","page":"Basics","title":"Basics","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"using Graphs\nusing MetaGraphsNext","category":"page"},{"location":"tutorial/1_basics/#Creating-an-empty-MetaGraph","page":"Basics","title":"Creating an empty MetaGraph","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"We provide a convenience constructor for creating empty graphs, which looks as follows:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors = MetaGraph(\n Graph(); # underlying graph structure\n label_type=Symbol, # color name\n vertex_data_type=NTuple{3,Int}, # RGB code\n edge_data_type=Symbol, # result of the addition between two colors\n graph_data=\"additive colors\", # tag for the whole graph\n)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"The label_type argument defines how vertices will be referred to. It can be anything you want, provided that pairs of labels can be compared with <. Integer types are generally discouraged, to avoid confusion with the vertex codes used by Graphs.jl. The vertex_data_type and edge_data_type type determine what kind of data will be associated with each vertex and edge. Finally, graph_data can contain an arbitrary object associated with the graph as a whole.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"If you don't care about labels at all, using the integer vertex codes as labels may be reasonable. Just keep in mind that labels do not change with vertex deletion, whereas vertex codes get decreased, so the coherence will be broken.","category":"page"},{"location":"tutorial/1_basics/#Modifying-the-graph","page":"Basics","title":"Modifying the graph","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"Modifications of graph elements and the associated metadata can always be done using setindex! (as in a dictionary) with the relevant labels.","category":"page"},{"location":"tutorial/1_basics/#Vertices","page":"Basics","title":"Vertices","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"Use setindex! with one key to add a new vertex with the given label and metadata. If a vertex with the given label does not exist, it will be created automatically. Otherwise, the function will simply modify the metadata for the existing vertex.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[:red] = (255, 0, 0);\ncolors[:green] = (0, 255, 0);\ncolors[:blue] = (0, 0, 255);\nnothing #hide","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"Note that you cannot use labels or metadata that is incoherent with the types you specified at construction.","category":"page"},{"location":"tutorial/1_basics/#Edges","page":"Basics","title":"Edges","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"Use setindex! with two keys to add a new edge between the given labels and containing the given metadata. Beware that this time, an edge will only be added when both node labels already exist in the graph.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[:red, :green] = :yellow;\ncolors[:red, :blue] = :magenta;\ncolors[:green, :blue] = :cyan;\nnothing #hide","category":"page"},{"location":"tutorial/1_basics/#Creating-a-non-empty-MetaGraph","page":"Basics","title":"Creating a non-empty MetaGraph","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"There is an alternative constructor which allows you to build and fill the graph in one fell swoop. Here's how it works:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"graph = Graph(Edge.([(1, 2), (1, 3), (2, 3)]))\nvertices_description = [:red => (255, 0, 0), :green => (0, 255, 0), :blue => (0, 0, 255)]\nedges_description = [\n (:red, :green) => :yellow, (:red, :blue) => :magenta, (:green, :blue) => :cyan\n]\n\ncolors2 = MetaGraph(graph, vertices_description, edges_description, \"additive colors\")\ncolors2 == colors","category":"page"},{"location":"tutorial/1_basics/#Accessing-graph-properties","page":"Basics","title":"Accessing graph properties","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"To retrieve graph properties, we still follow a dictionary-like interface based on labels.","category":"page"},{"location":"tutorial/1_basics/#Existence","page":"Basics","title":"Existence","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"To check the presence of a vertex or edge, use haskey:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"haskey(colors, :red)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"haskey(colors, :black)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"haskey(colors, :red, :green) && haskey(colors, :green, :red)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"!haskey(colors, :red, :black)","category":"page"},{"location":"tutorial/1_basics/#Metadata","page":"Basics","title":"Metadata","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"All kinds of metadata can be accessed with getindex:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[:blue]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[:green, :blue]","category":"page"},{"location":"tutorial/1_basics/#Using-vertex-codes","page":"Basics","title":"Using vertex codes","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"In the absence of removal, vertex codes correspond to order of insertion in the underlying graph. They are the ones used by most algorithms in the Graphs.jl ecosystem.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"code_for(colors, :red)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"code_for(colors, :blue)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"You can retrieve the associated labels as follows:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"label_for(colors, 1)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"label_for(colors, 3)","category":"page"},{"location":"tutorial/1_basics/#Listing-labels","page":"Basics","title":"Listing labels","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"The functions labels, edge_labels, (in/out)neighbor_labels iterate through labels the same way that vertices, edges and (in/out)neighbors iterate through codes.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"collect(labels(colors))","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"collect(edge_labels(colors))","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"collect(neighbor_labels(colors, :red))","category":"page"},{"location":"tutorial/1_basics/#Handling-weights","page":"Basics","title":"Handling weights","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"You can use the weight_function field to specify a function which will transform edge metadata into a weight. This weight must always have the same type as the default_weight, which is the value returned in case an edge does not exist.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weighted = MetaGraph(\n Graph();\n label_type=Symbol,\n edge_data_type=Float64,\n weight_function=ed -> ed^2,\n default_weight=Inf,\n);\n\nweighted[:alice] = nothing;\nweighted[:bob] = nothing;\nweighted[:charlie] = nothing;\n\nweighted[:alice, :bob] = 2.0;\nweighted[:bob, :charlie] = 3.0;\nnothing #hide","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weight_matrix = Graphs.weights(weighted)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"default_weight(weighted)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"size(weight_matrix)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weight_matrix[1, 2]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weight_matrix[2, 3]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weight_matrix[1, 3]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"wf = get_weight_function(weighted)\nwf(4.0)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"You can then use all functions from Graphs.jl that require weighted graphs (see the rest of the tutorial).","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"This page was generated using Literate.jl.","category":"page"},{"location":"api/#API-reference","page":"API reference","title":"API reference","text":"","category":"section"},{"location":"api/#Docstrings","page":"API reference","title":"Docstrings","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [MetaGraphsNext]","category":"page"},{"location":"api/#MetaGraphsNext.MetaGraphsNext","page":"API reference","title":"MetaGraphsNext.MetaGraphsNext","text":"MetaGraphsNext\n\nA package for graphs with vertex labels and metadata in Julia. Its main export is the MetaGraph type.\n\n\n\n\n\n","category":"module"},{"location":"api/#MetaGraphsNext.DOTFormat","page":"API reference","title":"MetaGraphsNext.DOTFormat","text":"struct DOTFormat <: AbstractGraphFormat end\n\nIf all metadata types support pairs or are Nothing, you can save MetaGraphs in DOTFormat.\n\n\n\n\n\n","category":"type"},{"location":"api/#MetaGraphsNext.MGFormat","page":"API reference","title":"MetaGraphsNext.MGFormat","text":"struct MGFormat <: AbstractGraphFormat end\n\nYou can save MetaGraphs in a MGFormat, currently based on JLD2.\n\n\n\n\n\n","category":"type"},{"location":"api/#MetaGraphsNext.MetaGraph","page":"API reference","title":"MetaGraphsNext.MetaGraph","text":"MetaGraph{\n Code<:Integer,\n Graph<:AbstractGraph{Code},\n Label,\n VertexData,\n EdgeData,\n GraphData,\n WeightFunction,\n Weight\n} <: AbstractGraph{Code}\n\nA graph type with custom vertex labels containing vertex-, edge- and graph-level metadata.\n\nVertex labels have type Label, while vertex (resp. edge, resp. graph) metadata has type VertexData (resp. EdgeData, resp. GraphData). It is recommended not to set Label to an integer type, so as to avoid confusion between vertex labels (which do not change as the graph evolves) and vertex codes (which have type Code<:Integer and can change as the graph evolves).\n\nFields\n\ngraph::Graph: underlying, data-less graph with vertex codes of type Code\nvertex_labels::Dict{Code,Label}: dictionary mapping vertex codes to vertex labels\nvertex_properties::Dict{Label,Tuple{Code,VertexData}}: dictionary mapping vertex labels to vertex codes & metadata\nedge_data::Dict{Tuple{Label,Label},EdgeData}: dictionary mapping edge labels such as (label_u, label_v) to edge metadata\ngraph_data::GraphData: metadata for the graph object as a whole\nweight_function::WeightFunction: function computing edge weight from edge metadata, its output must have the same type as default_weight\ndefault_weight::Weight: default weight used when an edge doesn't exist\n\n\n\n\n\n","category":"type"},{"location":"api/#MetaGraphsNext.MetaGraph-Tuple{Any}","page":"API reference","title":"MetaGraphsNext.MetaGraph","text":"MetaGraph(\n graph;\n label_type,\n vertex_data_type=Nothing,\n edge_data_type=Nothing,\n graph_data=nothing,\n weight_function=edge_data -> 1.0,\n default_weight=1.0\n)\n\nConstruct an empty MetaGraph based on an empty graph, initializing storage with metadata types given as keyword arguments.\n\nwarning: Warning\nThis constructor uses keyword arguments for convenience, which means it is type-unstable.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.MetaGraph-Union{Tuple{EdgeData}, Tuple{VertexData}, Tuple{Label}, Tuple{Code}, Tuple{AbstractGraph{Code}, Array{Pair{Label, VertexData}, 1}, Array{Pair{Tuple{Label, Label}, EdgeData}, 1}}, Tuple{AbstractGraph{Code}, Array{Pair{Label, VertexData}, 1}, Array{Pair{Tuple{Label, Label}, EdgeData}, 1}, Any}, Tuple{AbstractGraph{Code}, Array{Pair{Label, VertexData}, 1}, Array{Pair{Tuple{Label, Label}, EdgeData}, 1}, Any, Any}, Tuple{AbstractGraph{Code}, Array{Pair{Label, VertexData}, 1}, Array{Pair{Tuple{Label, Label}, EdgeData}, 1}, Any, Any, Any}} where {Code, Label, VertexData, EdgeData}","page":"API reference","title":"MetaGraphsNext.MetaGraph","text":"MetaGraph(\n graph,\n vertices_description,\n edges_description,\n graph_data=nothing,\n weight_function=edge_data -> 1.0,\n default_weight=1.0,\n)\n\nConstruct a non-empty MetaGraph based on a non-empty graph with specified vertex and edge data, given as positional arguments.\n\nThe data must be given as follows:\n\nvertices_description is a vector of pairs label => data (the code of a vertex will correspond to its rank in the list)\nedges_description is a vector of pairs (label1, label2) => data\n\nFurthermore, these arguments must be coherent with the graph argument, i.e. describe the same set of vertices and edges.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.MetaGraph-Union{Tuple{EdgeData}, Tuple{VertexData}, Tuple{Label}, Tuple{Code}, Tuple{AbstractGraph{Code}, Type{Label}}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}, Type{EdgeData}}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}, Type{EdgeData}, Any}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}, Type{EdgeData}, Any, Any}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}, Type{EdgeData}, Any, Any, Any}} where {Code, Label, VertexData, EdgeData}","page":"API reference","title":"MetaGraphsNext.MetaGraph","text":"MetaGraph(\n graph,\n label_type,\n vertex_data_type=Nothing,\n edge_data_type=Nothing,\n graph_data=nothing,\n weight_function=edge_data -> 1.0,\n default_weight=1.0\n)\n\nConstruct an empty MetaGraph based on an empty graph, initializing storage with metadata types given as positional arguments.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.delete!-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Base.delete!","text":"delete!(meta_graph, label_1, label_2)\n\nDelete edge (label_1, label_2).\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.delete!-Tuple{MetaGraph, Any}","page":"API reference","title":"Base.delete!","text":"delete!(meta_graph, label)\n\nDelete vertex label.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.getindex-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Base.getindex","text":"getindex(meta_graph, label_1, label_2)\n\nReturn edge metadata for the edge between label_1 and label_2.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.getindex-Tuple{MetaGraph, Any}","page":"API reference","title":"Base.getindex","text":"getindex(meta_graph, label)\n\nReturn vertex metadata for label.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.getindex-Tuple{MetaGraphsNext.MetaWeights, Integer, Integer}","page":"API reference","title":"Base.getindex","text":"getindex(meta_weights::MetaWeights, code_1, code_2)\n\nGet the weight of edge (code_1, code_2).\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.getindex-Tuple{MetaGraph}","page":"API reference","title":"Base.getindex","text":"getindex(meta_graph)\n\nReturn meta_graph metadata.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.haskey-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Base.haskey","text":"haskey(meta_graph, label_1, label_2)\n\nDetermine whether a metagraph `metagraphcontains an edge fromlabel1tolabel2`.\n\nThe order of label_1 and label_2 only matters if meta_graph is a digraph.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.haskey-Tuple{MetaGraph, Any}","page":"API reference","title":"Base.haskey","text":"haskey(meta_graph, label)\n\nDetermine whether a metagraph `metagraphcontains the vertexlabel`.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.setindex!-Tuple{MetaGraph, Any, Any, Any}","page":"API reference","title":"Base.setindex!","text":"setindex!(meta_graph, data, label_1, label_2)\n\nSet edge metadata for (label_1, label_2) to data.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.setindex!-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Base.setindex!","text":"setindex!(meta_graph, data, label)\n\nSet vertex metadata for label to data.\n\n\n\n\n\n","category":"method"},{"location":"api/#Graphs.SimpleGraphs.add_edge!-Tuple{MetaGraph, Any, Any, Any}","page":"API reference","title":"Graphs.SimpleGraphs.add_edge!","text":"add_edge!(meta_graph, label_1, label_2, data)\n\nAdd an edge (label_1, label_2) to MetaGraph meta_graph with metadata data. If the EdgeData type of meta_graph is Nothing, data can be omitted.\n\nReturn true if the edge has been added, false otherwise. If one of the labels does not exist, nothing happens and false is returned (the label is not inserted). If (label_1, label_2) already exists, its data is updated to data and false is returned nonetheless.\n\n\n\n\n\n","category":"method"},{"location":"api/#Graphs.SimpleGraphs.add_vertex!-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Graphs.SimpleGraphs.add_vertex!","text":"add_vertex!(meta_graph, label, data)\n\nAdd a vertex to MetaGraph meta_graph with label label having metadata data. If the VertexData type of meta_graph is Nothing, data can be omitted.\n\nReturn true if the vertex has been added, false in case the label already exists or vertex was not added.\n\n\n\n\n\n","category":"method"},{"location":"api/#Graphs.weights-Tuple{MetaGraph}","page":"API reference","title":"Graphs.weights","text":"weights(meta_graph)\n\nReturn a matrix-like MetaWeights object containing the edge weights for metagraph meta_graph.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext._copy_props!-Tuple{MetaGraph, MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext._copy_props!","text":"_copy_props!(old_meta_graph, new_meta_graph, code_map)\n\nCopy properties from old_meta_graph to new_meta_graph following vertex map code_map.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.all_neighbor_labels-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.all_neighbor_labels","text":"all_neighbor_labels(meta_graph, label)\n\nIterate through all labels of all neighbors of the vertex code with label label, in the same order as the codes obtained by all_neighbors(meta_graph, code).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.arrange","page":"API reference","title":"MetaGraphsNext.arrange","text":"arrange(graph, label_1, label_2)\n\nSort two vertex labels in a default order (useful to uniquely express undirected edges). For undirected graphs, the default order is based on the labels themselves to be robust to vertex re-coding, so the labels need to support <.\n\n\n\n\n\n","category":"function"},{"location":"api/#MetaGraphsNext.code_for-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.code_for","text":"code_for(meta_graph::MetaGraph, label)\n\nFind the vertex code (or index) associated with label label.\n\nThis can be useful to pass to methods inherited from Graphs. Note, however, that vertex codes can be reassigned after vertex deletion.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.default_weight-Tuple{MetaGraph}","page":"API reference","title":"MetaGraphsNext.default_weight","text":"default_weight(meta_graph)\n\nReturn the default weight for metagraph meta_graph.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.edge_labels-Tuple{MetaGraph}","page":"API reference","title":"MetaGraphsNext.edge_labels","text":"edge_labels(meta_graph)\n\nIterate through all tuples of edge labels, in the same order as the tuples of codes obtained by edges(meta_graph).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.get_weight_function-Tuple{MetaGraph}","page":"API reference","title":"MetaGraphsNext.get_weight_function","text":"get_weight_function(meta_graph)\n\nReturn the weight function for metagraph meta_graph.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.inneighbor_labels-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.inneighbor_labels","text":"inneighbor_labels(meta_graph, label)\n\nIterate through all labels of inneighbors of the vertex code with label label, in the same order as the codes obtained by inneighbors(meta_graph, code).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.label_for-Tuple{MetaGraph, Integer}","page":"API reference","title":"MetaGraphsNext.label_for","text":"label_for(meta_graph::MetaGraph, code)\n\nFind the label associated with code code.\n\nThis can be useful to interpret the results of methods inherited from Graphs. Note, however, that vertex codes can be reassigned after vertex deletion.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.labels-Tuple{MetaGraph}","page":"API reference","title":"MetaGraphsNext.labels","text":"labels(meta_graph)\n\nIterate through all vertex labels, in the same order as the codes obtained by vertices(meta_graph).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.neighbor_labels-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.neighbor_labels","text":"neighbor_labels(meta_graph, label)\n\nIterate through all labels of neighbors of the vertex code with label label, in the same order as the codes obtained by neighbors(meta_graph, code).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.outneighbor_labels-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.outneighbor_labels","text":"outneighbor_labels(meta_graph, label)\n\nIterate through all labels of outneighbors of the vertex code with label label, in the same order as the codes obtained by outneighbors(meta_graph, code).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.set_data!-Tuple{MetaGraph, Any, Any, Any}","page":"API reference","title":"MetaGraphsNext.set_data!","text":"set_data!(meta_graph, label_1, label_2, data)\n\nSet edge metadata for (label_1, label_2) to data.\n\nReturn true if the operation succeeds, and false if meta_graph has no such edge.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.set_data!-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"MetaGraphsNext.set_data!","text":"set_data!(meta_graph, label, data)\n\nSet vertex metadata for label to data.\n\nReturn true if the operation succeeds, and false if meta_graph has no such vertex.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.weighttype-Union{Tuple{MetaGraph{<:Any, <:Any, <:Any, <:Any, <:Any, <:Any, <:Any, Weight}}, Tuple{Weight}} where Weight","page":"API reference","title":"MetaGraphsNext.weighttype","text":"weighttype(meta_graph)\n\nReturn the weight type for metagraph meta_graph.\n\n\n\n\n\n","category":"method"},{"location":"api/","page":"API reference","title":"API reference","text":"haskey\ngetindex\nsetindex!\ndelete!","category":"page"},{"location":"api/#Base.haskey","page":"API reference","title":"Base.haskey","text":"haskey(meta_graph, label)\n\nDetermine whether a metagraph `metagraphcontains the vertexlabel`.\n\n\n\n\n\nhaskey(meta_graph, label_1, label_2)\n\nDetermine whether a metagraph `metagraphcontains an edge fromlabel1tolabel2`.\n\nThe order of label_1 and label_2 only matters if meta_graph is a digraph.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.getindex","page":"API reference","title":"Base.getindex","text":"getindex(meta_graph)\n\nReturn meta_graph metadata.\n\n\n\n\n\ngetindex(meta_graph, label)\n\nReturn vertex metadata for label.\n\n\n\n\n\ngetindex(meta_graph, label_1, label_2)\n\nReturn edge metadata for the edge between label_1 and label_2.\n\n\n\n\n\ngetindex(meta_weights::MetaWeights, code_1, code_2)\n\nGet the weight of edge (code_1, code_2).\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.setindex!","page":"API reference","title":"Base.setindex!","text":"setindex!(meta_graph, data, label)\n\nSet vertex metadata for label to data.\n\n\n\n\n\nsetindex!(meta_graph, data, label_1, label_2)\n\nSet edge metadata for (label_1, label_2) to data.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.delete!","page":"API reference","title":"Base.delete!","text":"delete!(meta_graph, label)\n\nDelete vertex label.\n\n\n\n\n\ndelete!(meta_graph, label_1, label_2)\n\nDelete edge (label_1, label_2).\n\n\n\n\n\n","category":"function"},{"location":"api/","page":"API reference","title":"API reference","text":"add_vertex!\nadd_edge!\nweights","category":"page"},{"location":"api/#Graphs.SimpleGraphs.add_vertex!","page":"API reference","title":"Graphs.SimpleGraphs.add_vertex!","text":"add_vertex!(meta_graph, label, data)\n\nAdd a vertex to MetaGraph meta_graph with label label having metadata data. If the VertexData type of meta_graph is Nothing, data can be omitted.\n\nReturn true if the vertex has been added, false in case the label already exists or vertex was not added.\n\n\n\n\n\n","category":"function"},{"location":"api/#Graphs.SimpleGraphs.add_edge!","page":"API reference","title":"Graphs.SimpleGraphs.add_edge!","text":"add_edge!(meta_graph, label_1, label_2, data)\n\nAdd an edge (label_1, label_2) to MetaGraph meta_graph with metadata data. If the EdgeData type of meta_graph is Nothing, data can be omitted.\n\nReturn true if the edge has been added, false otherwise. If one of the labels does not exist, nothing happens and false is returned (the label is not inserted). If (label_1, label_2) already exists, its data is updated to data and false is returned nonetheless.\n\n\n\n\n\n","category":"function"},{"location":"api/#Graphs.weights","page":"API reference","title":"Graphs.weights","text":"weights(meta_graph)\n\nReturn a matrix-like MetaWeights object containing the edge weights for metagraph meta_graph.\n\n\n\n\n\n","category":"function"},{"location":"api/#Index","page":"API reference","title":"Index","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"EditURL = \"../../../test/tutorial/3_files.jl\"","category":"page"},{"location":"tutorial/3_files/#File-storage","page":"File storage","title":"File storage","text":"","category":"section"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"using Graphs\nusing MetaGraphsNext","category":"page"},{"location":"tutorial/3_files/#MGFormat","page":"File storage","title":"MGFormat","text":"","category":"section"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"MetaGraphsNext.jl overloads Graphs.savegraph to write graphs in a custom format called MGFormat, which is based on JLD2. It is not very readable, but it does give the right result when we load it back.","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"example = MetaGraph(Graph(), Symbol);\n\nexample2 = mktemp() do file, io\n savegraph(file, example)\n loadgraph(file, \"something\", MGFormat())\nend\n\nexample2 == example","category":"page"},{"location":"tutorial/3_files/#DOTFormat","page":"File storage","title":"DOTFormat","text":"","category":"section"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"MetaGraphsNext.jl also support the more standard DOT encoding, which is used as follows.","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"simple = MetaGraph(Graph(), Symbol);\n\nsimple[:a] = nothing;\nsimple[:b] = nothing;\nsimple[:a, :b] = nothing;\n\nsimple_str = mktemp() do file, io\n savegraph(file, simple, DOTFormat())\n read(file, String)\nend\n\nsimple_str_true = \"\"\"\ngraph T {\n \"a\"\n \"b\"\n \"a\" -- \"b\"\n}\n\"\"\"\n\nsimple_str == simple_str_true","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"complicated = MetaGraph(\n DiGraph();\n label_type=Symbol,\n vertex_data_type=Dict{Symbol,Int},\n edge_data_type=Dict{Symbol,Int},\n graph_data=(tagged=true,),\n);\n\ncomplicated[:a] = Dict(:code_1 => 1, :code_2 => 2);\n\ncomplicated[:b] = Dict(:code => 2);\n\ncomplicated[:a, :b] = Dict(:code => 12);\n\ncomplicated_str = mktemp() do file, io\n savegraph(file, complicated, DOTFormat())\n read(file, String)\nend\n\ncomplicated_str_true = \"\"\"\ndigraph G {\n tagged = true\n \"a\" [code_1 = 1, code_2 = 2]\n \"b\" [code = 2]\n \"a\" -> \"b\" [code = 12]\n}\n\"\"\"","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"with_spaces = MetaGraph(\n DiGraph();\n label_type=String,\n vertex_data_type=Dict{Symbol,String},\n edge_data_type=Dict{Symbol,String},\n)\n\nwith_spaces[\"a b\"] = Dict(:label => \"A B\")\n\nwith_spaces[\"c d\"] = Dict(:label => \"C D\")\n\nwith_spaces[\"a b\", \"c d\"] = Dict(:label => \"A B to C D\")\n\nwith_spaces_str = mktemp() do file, io\n savegraph(file, with_spaces, DOTFormat())\n read(file, String)\nend\n\nwith_spaces_str_true = \"\"\"\ndigraph G {\n \"a b\" [label = \"A B\"]\n \"c d\" [label = \"C D\"]\n \"a b\" -> \"c d\" [label = \"A B to C D\"]\n}\n\"\"\"\n\nwith_spaces_str == with_spaces_str_true","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"This page was generated using Literate.jl.","category":"page"},{"location":"#MetaGraphsNext.jl","page":"Home","title":"MetaGraphsNext.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Welcome to MetaGraphsNext.jl, a type-stable replacement for MetaGraphs.jl. It allows you to create graphs with vertex and edge metadata, on which you can unleash the full power of the Graphs.jl ecosystem.","category":"page"},{"location":"#Getting-started","page":"Home","title":"Getting started","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To install the package, open the Julia REPL and type","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.add(\"MetaGraphsNext\")","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"EditURL = \"../../../test/tutorial/2_graphs.jl\"","category":"page"},{"location":"tutorial/2_graphs/#Graphs.jl-interface","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"","category":"section"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"using Graphs\nusing MetaGraphsNext","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"MetaGraphs inherit many methods from Graphs.jl. In general, inherited methods refer to vertices by codes, not labels, for compatibility with the AbstractGraph interface.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Note that vertex codes get reassigned after rem_vertex! operations to remain contiguous, so we recommend systematically converting to and from labels.","category":"page"},{"location":"tutorial/2_graphs/#Undirected-graphs","page":"Graphs.jl interface","title":"Undirected graphs","text":"","category":"section"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We can make MetaGraphs based on (undirected) Graphs.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"cities = MetaGraph(\n Graph();\n label_type=Symbol,\n vertex_data_type=String,\n edge_data_type=Int,\n graph_data=nothing,\n weight_function=identity,\n);\nnothing #hide","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Let us add some cities and the distance between them:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"cities[:Paris] = \"France\";\ncities[:London] = \"UK\";\ncities[:Berlin] = \"Germany\";\ncities[:Paris, :London] = 344;\ncities[:Paris, :Berlin] = 878;\nnothing #hide","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"The general properties of the graph are as expected:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"is_directed(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"eltype(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"edgetype(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We can check the set of vertices:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"nv(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"collect(vertices(cities))","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"has_vertex(cities, 2)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"has_vertex(cities, 4)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Note that we can't add the same city (i.e. vertex label) twice:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"add_vertex!(cities, :London, \"Italy\")","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"nv(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"cities[:London]","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We then check the set of edges:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"ne(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"collect(edges(cities))","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"has_edge(cities, 1, 2)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"has_edge(cities, 2, 3)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"From this initial graph, we can create some others:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"copy(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"zero(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Since cities is a weighted graph, we can leverage the whole Graphs.jl machinery of graph analysis and traversal:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"diameter(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"ds = dijkstra_shortest_paths(cities, 2)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Finally, let us remove some edges and vertices","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"rem_edge!(cities, 1, 3);\nrem_vertex!(cities, 3);\nhas_vertex(cities, 1) && !has_vertex(cities, 3)","category":"page"},{"location":"tutorial/2_graphs/#Directed-graphs","page":"Graphs.jl interface","title":"Directed graphs","text":"","category":"section"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We can make MetaGraphs based on DiGraphs as well.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"rock_paper_scissors = MetaGraph(DiGraph(); label_type=Symbol, edge_data_type=String);\n\nfor label in [:rock, :paper, :scissors]\n rock_paper_scissors[label] = nothing\nend\n\nrock_paper_scissors[:rock, :scissors] = \"rock beats scissors\"\nrock_paper_scissors[:scissors, :paper] = \"scissors beat paper\"\nrock_paper_scissors[:paper, :rock] = \"paper beats rock\";\nnothing #hide","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We see that the underlying graph has changed:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"is_directed(rock_paper_scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Directed graphs can be reversed:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"haskey(rock_paper_scissors, :scissors, :rock)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"haskey(reverse(rock_paper_scissors), :scissors, :rock)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Let us take a subgraph induced by a subset of vertices:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"rock_paper, _ = induced_subgraph(rock_paper_scissors, [1, 2])","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"issubset(rock_paper, rock_paper_scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"haskey(rock_paper, :paper, :rock)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"haskey(rock_paper, :rock, :scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Subgraphs can also be induced by a subset of edges.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"subtree_edges = collect(edges(rock_paper_scissors))[2:3]\nrock_paper_scissors_subtree, _ = induced_subgraph(rock_paper_scissors, subtree_edges)\nissubset(rock_paper_scissors_subtree, rock_paper_scissors)\nne(rock_paper_scissors_subtree)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"nv(rock_paper_scissors_subtree)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"[rock_paper_scissors_subtree[e...] for e in edge_labels(rock_paper_scissors_subtree)]","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Checking that a graph is a subset of another is not supported yet. For example, an induced subgraph may appear as not a subset of the original graph, if vertex codes were modified.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"issubset(rock_paper_scissors_subtree, rock_paper_scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"rock_scissors, _ = induced_subgraph(rock_paper_scissors, [1, 3])\nissubset(rock_scissors, rock_paper_scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"This page was generated using Literate.jl.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"EditURL = \"../../../test/tutorial/4_type_stability.jl\"","category":"page"},{"location":"tutorial/4_type_stability/#Type-stability","page":"Type stability","title":"Type stability","text":"","category":"section"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"using Graphs\nusing MetaGraphs: MetaGraphs\nusing MetaGraphsNext","category":"page"},{"location":"tutorial/4_type_stability/#Constructor-and-access","page":"Type stability","title":"Constructor and access","text":"","category":"section"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"In the previous examples, we used a MetaGraph constructor which receives type parameters as keyword arguments. This was done for ease of exposition, but it may impede type inference, and hence reduce performance.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"colors = MetaGraph(\n Graph(); # underlying graph structure\n label_type=Symbol, # color name\n vertex_data_type=NTuple{3,Int}, # RGB code\n edge_data_type=Symbol, # result of the addition between two colors\n graph_data=\"additive colors\", # tag for the whole graph\n)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"While casual users probably won't care, if your goal is performance, you might need to proceed differently.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Option 1: wrap the constructor in a helper function to trigger constant propagation.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"function colors_constructor()\n return MetaGraph(\n Graph();\n label_type=Symbol,\n vertex_data_type=NTuple{3,Int},\n edge_data_type=Symbol,\n graph_data=\"additive colors\",\n )\nend\n\ncolors_constructor()","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Option 2: switch to another constructor that uses positional arguments (be careful with the order!)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraph(Graph(), Symbol, NTuple{3,Int}, Symbol, \"additive colors\")","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Option 3: use the constructor for a non-empty graph instead.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"vertices_description = [:red => (255, 0, 0), :green => (0, 255, 0), :blue => (0, 0, 255)]\nedges_description = [\n (:red, :green) => :yellow, (:red, :blue) => :magenta, (:green, :blue) => :cyan\n]\nMetaGraph(cycle_graph(3), vertices_description, edges_description, \"additive colors\")","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Once Julia can infer the full type of the MetaGraph, accessing vertex and edge metadata also becomes type-stable.","category":"page"},{"location":"tutorial/4_type_stability/#Comparison-with-MetaGraphs.jl","page":"Type stability","title":"Comparison with MetaGraphs.jl","text":"","category":"section"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"In the older package MetaGraphs.jl that we used as inspiration, data types are not specified in the graph structure. Their choice allows more flexibility and an arbitrary number of attributes which the user does not need to anticipate at construction.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"colors_unstable = MetaGraphs.MetaGraph(cycle_graph(3))","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Here is how one would add data and labels to colors_unstable.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.set_indexing_prop!(colors_unstable, :label)\n\nMetaGraphs.set_prop!(colors_unstable, :graph_tag, \"additive colors\")\n\nMetaGraphs.set_props!(colors_unstable, 1, Dict(:label => :red, :rgb_code => (255, 0, 0)))\nMetaGraphs.set_props!(colors_unstable, 2, Dict(:label => :green, :rgb_code => (0, 255, 0)))\nMetaGraphs.set_props!(colors_unstable, 3, Dict(:label => :blue, :rgb_code => (0, 0, 255)))\n\nMetaGraphs.set_prop!(colors_unstable, 1, 2, :addition_result, :yellow)\nMetaGraphs.set_prop!(colors_unstable, 1, 3, :addition_result, :magenta)\nMetaGraphs.set_prop!(colors_unstable, 2, 3, :addition_result, :cyan);\nnothing #hide","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"One can retrieve the vertex index (which we called code) using any indexing property.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"colors_unstable[:green, :label]","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Then we can access vertex properties...","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.get_prop(colors_unstable, 2, :rgb_code)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.props(colors_unstable, 2)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"... and edge properties.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.get_prop(colors_unstable, 2, 3, :addition_result)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.props(colors_unstable, 2, 3)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"The fact that the outputs of these calls to props are of type Dict{Symbol, Any} is at the root of the problem. It means that if we use their values in any subsequent algorithms, we introduce type instability in our code (due to Any). MetaGraphsNext.jl overcomes this obstacle thanks to a more precise storage method.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"This page was generated using Literate.jl.","category":"page"}] +[{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"EditURL = \"../../../test/tutorial/5_benchmark.jl\"","category":"page"},{"location":"tutorial/5_benchmark/#Benchmark","page":"Benchmark","title":"Benchmark","text":"","category":"section"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"Here we compare the performance of MetaGraphsNext.jl with its predecessor MetaGraphs.jl.","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"using BenchmarkTools\nusing Graphs\nusing InteractiveUtils\nusing MetaGraphs: MetaGraphs\nusing MetaGraphsNext: MetaGraphsNext","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"The benchmarking task is two-fold:","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"Build a complete graph with random boolean metadata on the vertices (active) and float metadata on the edges (distance)\nCompute the sum of distances for all edges whose endpoints are both active.","category":"page"},{"location":"tutorial/5_benchmark/#Graph-construction","page":"Benchmark","title":"Graph construction","text":"","category":"section"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function build_incremental_metagraphsnext(n)\n g = Graph(0)\n mg = MetaGraphsNext.MetaGraph(\n g;\n label_type=Int, # this will throw a warning\n vertex_data_type=Bool,\n edge_data_type=Float64,\n )\n for li in 1:n\n mg[li] = rand(Bool)\n end\n for li in 1:n, lj in 1:(li - 1)\n mg[li, lj] = rand(Float64)\n end\n return mg\nend;\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function build_bulk_metagraphsnext(n)\n g = complete_graph(n)\n vertices_description = [li => rand(Bool) for li in 1:n]\n edges_description = [(li, lj) => rand(Float64) for li in 1:n for lj in 1:(li - 1)]\n mg = MetaGraphsNext.MetaGraph(g, vertices_description, edges_description;)\n return mg\nend;\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function build_metagraphs(n)\n g = complete_graph(n)\n mg = MetaGraphs.MetaGraph(g)\n for i in 1:n\n MetaGraphs.set_prop!(mg, i, :active, rand(Bool))\n end\n for i in 1:n, j in 1:(i - 1)\n MetaGraphs.set_prop!(mg, i, j, :distance, rand(Float64))\n end\n return mg\nend;\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@btime build_incremental_metagraphsnext(100);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@btime build_bulk_metagraphsnext(100);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@btime build_metagraphs(100);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/#Graph-exploitation","page":"Benchmark","title":"Graph exploitation","text":"","category":"section"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function sum_active_edges_metagraphsnext(mg)\n S = 0.0\n for (li, lj) in MetaGraphsNext.edge_labels(mg)\n active_i = mg[li]\n active_j = mg[lj]\n distance_ij = mg[li, lj]\n if active_i && active_j\n S += distance_ij\n end\n end\n return S\nend","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"function sum_active_edges_metagraphs(mg)\n S = 0.0\n for e in edges(mg)\n i, j = src(e), dst(e)\n active_i = MetaGraphs.get_prop(mg, i, :active)\n active_j = MetaGraphs.get_prop(mg, j, :active)\n distance_ij = MetaGraphs.get_prop(mg, i, j, :distance)\n if active_i && active_j\n S += distance_ij\n end\n end\n return S\nend","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"mg1 = build_incremental_metagraphsnext(100);\n@btime sum_active_edges_metagraphsnext($mg1);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"mg2 = build_metagraphs(100);\n@btime sum_active_edges_metagraphs($mg2);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"The difference in performance can be explained by type instability.","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@code_warntype sum_active_edges_metagraphsnext(mg1);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"@code_warntype sum_active_edges_metagraphs(mg2);\nnothing #hide","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"","category":"page"},{"location":"tutorial/5_benchmark/","page":"Benchmark","title":"Benchmark","text":"This page was generated using Literate.jl.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"EditURL = \"../../../test/tutorial/1_basics.jl\"","category":"page"},{"location":"tutorial/1_basics/#Basics","page":"Basics","title":"Basics","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"using Graphs\nusing MetaGraphsNext","category":"page"},{"location":"tutorial/1_basics/#Creating-an-empty-MetaGraph","page":"Basics","title":"Creating an empty MetaGraph","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"We provide a convenience constructor for creating empty graphs, which looks as follows:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors = MetaGraph(\n Graph(); # underlying graph structure\n label_type=Symbol, # color name\n vertex_data_type=NTuple{3,Int}, # RGB code\n edge_data_type=Symbol, # result of the addition between two colors\n graph_data=\"additive colors\", # tag for the whole graph\n)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"The label_type argument defines how vertices will be referred to. It can be anything you want, provided that pairs of labels can be compared with <. Integer types are generally discouraged, to avoid confusion with the vertex codes used by Graphs.jl. The vertex_data_type and edge_data_type type determine what kind of data will be associated with each vertex and edge. Finally, graph_data can contain an arbitrary object associated with the graph as a whole.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"If you don't care about labels at all, using the integer vertex codes as labels may be reasonable. Just keep in mind that labels do not change with vertex deletion, whereas vertex codes get decreased, so the coherence will be broken.","category":"page"},{"location":"tutorial/1_basics/#Modifying-the-graph","page":"Basics","title":"Modifying the graph","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"Modifications of graph elements and the associated metadata can always be done using setindex! (as in a dictionary) with the relevant labels.","category":"page"},{"location":"tutorial/1_basics/#Vertices","page":"Basics","title":"Vertices","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"Use setindex! with one key to add a new vertex with the given label and metadata. If a vertex with the given label does not exist, it will be created automatically. Otherwise, the function will simply modify the metadata for the existing vertex.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[:red] = (255, 0, 0);\ncolors[:green] = (0, 255, 0);\ncolors[:blue] = (0, 0, 255);\nnothing #hide","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"Note that you cannot use labels or metadata that is incoherent with the types you specified at construction.","category":"page"},{"location":"tutorial/1_basics/#Edges","page":"Basics","title":"Edges","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"Use setindex! with two keys to add a new edge between the given labels and containing the given metadata. Beware that this time, an edge will only be added when both node labels already exist in the graph.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[:red, :green] = :yellow;\ncolors[:red, :blue] = :magenta;\ncolors[:green, :blue] = :cyan;\nnothing #hide","category":"page"},{"location":"tutorial/1_basics/#Creating-a-non-empty-MetaGraph","page":"Basics","title":"Creating a non-empty MetaGraph","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"There is an alternative constructor which allows you to build and fill the graph in one fell swoop. Here's how it works:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"graph = Graph(Edge.([(1, 2), (1, 3), (2, 3)]))\nvertices_description = [:red => (255, 0, 0), :green => (0, 255, 0), :blue => (0, 0, 255)]\nedges_description = [\n (:red, :green) => :yellow, (:red, :blue) => :magenta, (:green, :blue) => :cyan\n]\n\ncolors2 = MetaGraph(graph, vertices_description, edges_description, \"additive colors\")\ncolors2 == colors","category":"page"},{"location":"tutorial/1_basics/#Accessing-graph-properties","page":"Basics","title":"Accessing graph properties","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"To retrieve graph properties, we still follow a dictionary-like interface based on labels.","category":"page"},{"location":"tutorial/1_basics/#Existence","page":"Basics","title":"Existence","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"To check the presence of a vertex or edge, use haskey:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"haskey(colors, :red)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"haskey(colors, :black)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"haskey(colors, :red, :green) && haskey(colors, :green, :red)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"!haskey(colors, :red, :black)","category":"page"},{"location":"tutorial/1_basics/#Metadata","page":"Basics","title":"Metadata","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"All kinds of metadata can be accessed with getindex:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[:blue]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"colors[:green, :blue]","category":"page"},{"location":"tutorial/1_basics/#Using-vertex-codes","page":"Basics","title":"Using vertex codes","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"In the absence of removal, vertex codes correspond to order of insertion in the underlying graph. They are the ones used by most algorithms in the Graphs.jl ecosystem.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"code_for(colors, :red)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"code_for(colors, :blue)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"You can retrieve the associated labels as follows:","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"label_for(colors, 1)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"label_for(colors, 3)","category":"page"},{"location":"tutorial/1_basics/#Listing-labels","page":"Basics","title":"Listing labels","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"The functions labels, edge_labels, (in/out)neighbor_labels iterate through labels the same way that vertices, edges and (in/out)neighbors iterate through codes.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"collect(labels(colors))","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"collect(edge_labels(colors))","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"collect(neighbor_labels(colors, :red))","category":"page"},{"location":"tutorial/1_basics/#Handling-weights","page":"Basics","title":"Handling weights","text":"","category":"section"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"You can use the weight_function field to specify a function which will transform edge metadata into a weight. This weight must always have the same type as the default_weight, which is the value returned in case an edge does not exist.","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weighted = MetaGraph(\n Graph();\n label_type=Symbol,\n edge_data_type=Float64,\n weight_function=ed -> ed^2,\n default_weight=Inf,\n);\n\nweighted[:alice] = nothing;\nweighted[:bob] = nothing;\nweighted[:charlie] = nothing;\n\nweighted[:alice, :bob] = 2.0;\nweighted[:bob, :charlie] = 3.0;\nnothing #hide","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weight_matrix = Graphs.weights(weighted)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"default_weight(weighted)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"size(weight_matrix)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weight_matrix[1, 2]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weight_matrix[2, 3]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"weight_matrix[1, 3]","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"wf = get_weight_function(weighted)\nwf(4.0)","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"You can then use all functions from Graphs.jl that require weighted graphs (see the rest of the tutorial).","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"","category":"page"},{"location":"tutorial/1_basics/","page":"Basics","title":"Basics","text":"This page was generated using Literate.jl.","category":"page"},{"location":"api/#API-reference","page":"API reference","title":"API reference","text":"","category":"section"},{"location":"api/#Docstrings","page":"API reference","title":"Docstrings","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"Modules = [MetaGraphsNext]","category":"page"},{"location":"api/#MetaGraphsNext.MetaGraphsNext","page":"API reference","title":"MetaGraphsNext.MetaGraphsNext","text":"MetaGraphsNext\n\nA package for graphs with vertex labels and metadata in Julia. Its main export is the MetaGraph type.\n\n\n\n\n\n","category":"module"},{"location":"api/#MetaGraphsNext.DOTFormat","page":"API reference","title":"MetaGraphsNext.DOTFormat","text":"struct DOTFormat <: AbstractGraphFormat end\n\nIf all metadata types support pairs or are Nothing, you can save MetaGraphs in DOTFormat.\n\n\n\n\n\n","category":"type"},{"location":"api/#MetaGraphsNext.MGFormat","page":"API reference","title":"MetaGraphsNext.MGFormat","text":"struct MGFormat <: AbstractGraphFormat end\n\nYou can save MetaGraphs in a MGFormat, currently based on JLD2.\n\n\n\n\n\n","category":"type"},{"location":"api/#MetaGraphsNext.MetaGraph","page":"API reference","title":"MetaGraphsNext.MetaGraph","text":"MetaGraph{\n Code<:Integer,\n Graph<:AbstractGraph{Code},\n Label,\n VertexData,\n EdgeData,\n GraphData,\n WeightFunction,\n Weight\n} <: AbstractGraph{Code}\n\nA graph type with custom vertex labels containing vertex-, edge- and graph-level metadata.\n\nVertex labels have type Label, while vertex (resp. edge, resp. graph) metadata has type VertexData (resp. EdgeData, resp. GraphData). It is recommended not to set Label to an integer type, so as to avoid confusion between vertex labels (which do not change as the graph evolves) and vertex codes (which have type Code<:Integer and can change as the graph evolves).\n\nFields\n\ngraph::Graph: underlying, data-less graph with vertex codes of type Code\nvertex_labels::Dict{Code,Label}: dictionary mapping vertex codes to vertex labels\nvertex_properties::Dict{Label,Tuple{Code,VertexData}}: dictionary mapping vertex labels to vertex codes & metadata\nedge_data::Dict{Tuple{Label,Label},EdgeData}: dictionary mapping edge labels such as (label_u, label_v) to edge metadata\ngraph_data::GraphData: metadata for the graph object as a whole\nweight_function::WeightFunction: function computing edge weight from edge metadata, its output must have the same type as default_weight\ndefault_weight::Weight: default weight used when an edge doesn't exist\n\n\n\n\n\n","category":"type"},{"location":"api/#MetaGraphsNext.MetaGraph-Tuple{Any}","page":"API reference","title":"MetaGraphsNext.MetaGraph","text":"MetaGraph(\n graph;\n label_type,\n vertex_data_type=Nothing,\n edge_data_type=Nothing,\n graph_data=nothing,\n weight_function=edge_data -> 1.0,\n default_weight=1.0\n)\n\nConstruct an empty MetaGraph based on an empty graph, initializing storage with metadata types given as keyword arguments.\n\nwarning: Warning\nThis constructor uses keyword arguments for convenience, which means it is type-unstable.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.MetaGraph-Union{Tuple{EdgeData}, Tuple{VertexData}, Tuple{Label}, Tuple{Code}, Tuple{AbstractGraph{Code}, Array{Pair{Label, VertexData}, 1}, Array{Pair{Tuple{Label, Label}, EdgeData}, 1}}, Tuple{AbstractGraph{Code}, Array{Pair{Label, VertexData}, 1}, Array{Pair{Tuple{Label, Label}, EdgeData}, 1}, Any}, Tuple{AbstractGraph{Code}, Array{Pair{Label, VertexData}, 1}, Array{Pair{Tuple{Label, Label}, EdgeData}, 1}, Any, Any}, Tuple{AbstractGraph{Code}, Array{Pair{Label, VertexData}, 1}, Array{Pair{Tuple{Label, Label}, EdgeData}, 1}, Any, Any, Any}} where {Code, Label, VertexData, EdgeData}","page":"API reference","title":"MetaGraphsNext.MetaGraph","text":"MetaGraph(\n graph,\n vertices_description,\n edges_description,\n graph_data=nothing,\n weight_function=edge_data -> 1.0,\n default_weight=1.0,\n)\n\nConstruct a non-empty MetaGraph based on a non-empty graph with specified vertex and edge data, given as positional arguments.\n\nThe data must be given as follows:\n\nvertices_description is a vector of pairs label => data (the code of a vertex will correspond to its rank in the list)\nedges_description is a vector of pairs (label1, label2) => data\n\nFurthermore, these arguments must be coherent with the graph argument, i.e. describe the same set of vertices and edges.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.MetaGraph-Union{Tuple{EdgeData}, Tuple{VertexData}, Tuple{Label}, Tuple{Code}, Tuple{AbstractGraph{Code}, Type{Label}}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}, Type{EdgeData}}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}, Type{EdgeData}, Any}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}, Type{EdgeData}, Any, Any}, Tuple{AbstractGraph{Code}, Type{Label}, Type{VertexData}, Type{EdgeData}, Any, Any, Any}} where {Code, Label, VertexData, EdgeData}","page":"API reference","title":"MetaGraphsNext.MetaGraph","text":"MetaGraph(\n graph,\n label_type,\n vertex_data_type=Nothing,\n edge_data_type=Nothing,\n graph_data=nothing,\n weight_function=edge_data -> 1.0,\n default_weight=1.0\n)\n\nConstruct an empty MetaGraph based on an empty graph, initializing storage with metadata types given as positional arguments.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.delete!-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Base.delete!","text":"delete!(meta_graph, label_1, label_2)\n\nDelete edge (label_1, label_2).\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.delete!-Tuple{MetaGraph, Any}","page":"API reference","title":"Base.delete!","text":"delete!(meta_graph, label)\n\nDelete vertex label.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.getindex-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Base.getindex","text":"getindex(meta_graph, label_1, label_2)\n\nReturn edge metadata for the edge between label_1 and label_2.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.getindex-Tuple{MetaGraph, Any}","page":"API reference","title":"Base.getindex","text":"getindex(meta_graph, label)\n\nReturn vertex metadata for label.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.getindex-Tuple{MetaGraphsNext.MetaWeights, Integer, Integer}","page":"API reference","title":"Base.getindex","text":"getindex(meta_weights::MetaWeights, code_1, code_2)\n\nGet the weight of edge (code_1, code_2).\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.getindex-Tuple{MetaGraph}","page":"API reference","title":"Base.getindex","text":"getindex(meta_graph)\n\nReturn meta_graph metadata.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.haskey-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Base.haskey","text":"haskey(meta_graph, label_1, label_2)\n\nDetermine whether a MetaGraph meta_graph contains an edge from label_1 to label_2.\n\nThe order of label_1 and label_2 only matters if meta_graph is a digraph.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.haskey-Tuple{MetaGraph, Any}","page":"API reference","title":"Base.haskey","text":"haskey(meta_graph, label)\n\nDetermine whether a MetaGraph meta_graph contains the vertex label.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.setindex!-Tuple{MetaGraph, Any, Any, Any}","page":"API reference","title":"Base.setindex!","text":"setindex!(meta_graph, data, label_1, label_2)\n\nSet edge metadata for (label_1, label_2) to data.\n\n\n\n\n\n","category":"method"},{"location":"api/#Base.setindex!-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Base.setindex!","text":"setindex!(meta_graph, data, label)\n\nSet vertex metadata for label to data.\n\n\n\n\n\n","category":"method"},{"location":"api/#Graphs.SimpleGraphs.add_edge!-Tuple{MetaGraph, Any, Any, Any}","page":"API reference","title":"Graphs.SimpleGraphs.add_edge!","text":"add_edge!(meta_graph, label_1, label_2, data)\n\nAdd an edge (label_1, label_2) to MetaGraph meta_graph with metadata data. If the EdgeData type of meta_graph is Nothing, data can be omitted.\n\nReturn true if the edge has been added, false otherwise. If one of the labels does not exist, nothing happens and false is returned (the label is not inserted). If (label_1, label_2) already exists, its data is updated to data and false is returned nonetheless.\n\n\n\n\n\n","category":"method"},{"location":"api/#Graphs.SimpleGraphs.add_vertex!-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"Graphs.SimpleGraphs.add_vertex!","text":"add_vertex!(meta_graph, label, data)\n\nAdd a vertex to MetaGraph meta_graph with label label having metadata data. If the VertexData type of meta_graph is Nothing, data can be omitted.\n\nReturn true if the vertex has been added, false in case the label already exists or vertex was not added.\n\n\n\n\n\n","category":"method"},{"location":"api/#Graphs.weights-Tuple{MetaGraph}","page":"API reference","title":"Graphs.weights","text":"weights(meta_graph)\n\nReturn a matrix-like MetaWeights object containing the edge weights for metagraph meta_graph.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext._copy_props!-Tuple{MetaGraph, MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext._copy_props!","text":"_copy_props!(old_meta_graph, new_meta_graph, code_map)\n\nCopy properties from old_meta_graph to new_meta_graph following vertex map code_map.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.all_neighbor_labels-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.all_neighbor_labels","text":"all_neighbor_labels(meta_graph, label)\n\nIterate through all labels of all neighbors of the vertex code with label label, in the same order as the codes obtained by all_neighbors(meta_graph, code).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.arrange","page":"API reference","title":"MetaGraphsNext.arrange","text":"arrange(graph, label_1, label_2)\n\nSort two vertex labels in a default order (useful to uniquely express undirected edges). For undirected graphs, the default order is based on the labels themselves to be robust to vertex re-coding, so the labels need to support <.\n\n\n\n\n\n","category":"function"},{"location":"api/#MetaGraphsNext.code_for-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.code_for","text":"code_for(meta_graph::MetaGraph, label)\n\nFind the vertex code (or index) associated with label label.\n\nThis can be useful to pass to methods inherited from Graphs. Note, however, that vertex codes can be reassigned after vertex deletion.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.default_weight-Tuple{MetaGraph}","page":"API reference","title":"MetaGraphsNext.default_weight","text":"default_weight(meta_graph)\n\nReturn the default weight for metagraph meta_graph.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.edge_labels-Tuple{MetaGraph}","page":"API reference","title":"MetaGraphsNext.edge_labels","text":"edge_labels(meta_graph)\n\nIterate through all tuples of edge labels, in the same order as the tuples of codes obtained by edges(meta_graph).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.get_weight_function-Tuple{MetaGraph}","page":"API reference","title":"MetaGraphsNext.get_weight_function","text":"get_weight_function(meta_graph)\n\nReturn the weight function for metagraph meta_graph.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.inneighbor_labels-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.inneighbor_labels","text":"inneighbor_labels(meta_graph, label)\n\nIterate through all labels of inneighbors of the vertex code with label label, in the same order as the codes obtained by inneighbors(meta_graph, code).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.label_for-Tuple{MetaGraph, Integer}","page":"API reference","title":"MetaGraphsNext.label_for","text":"label_for(meta_graph::MetaGraph, code)\n\nFind the label associated with code code.\n\nThis can be useful to interpret the results of methods inherited from Graphs. Note, however, that vertex codes can be reassigned after vertex deletion.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.labels-Tuple{MetaGraph}","page":"API reference","title":"MetaGraphsNext.labels","text":"labels(meta_graph)\n\nIterate through all vertex labels, in the same order as the codes obtained by vertices(meta_graph).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.neighbor_labels-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.neighbor_labels","text":"neighbor_labels(meta_graph, label)\n\nIterate through all labels of neighbors of the vertex code with label label, in the same order as the codes obtained by neighbors(meta_graph, code).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.outneighbor_labels-Tuple{MetaGraph, Any}","page":"API reference","title":"MetaGraphsNext.outneighbor_labels","text":"outneighbor_labels(meta_graph, label)\n\nIterate through all labels of outneighbors of the vertex code with label label, in the same order as the codes obtained by outneighbors(meta_graph, code).\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.set_data!-Tuple{MetaGraph, Any, Any, Any}","page":"API reference","title":"MetaGraphsNext.set_data!","text":"set_data!(meta_graph, label_1, label_2, data)\n\nSet edge metadata for (label_1, label_2) to data.\n\nReturn true if the operation succeeds, and false if meta_graph has no such edge.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.set_data!-Tuple{MetaGraph, Any, Any}","page":"API reference","title":"MetaGraphsNext.set_data!","text":"set_data!(meta_graph, label, data)\n\nSet vertex metadata for label to data.\n\nReturn true if the operation succeeds, and false if meta_graph has no such vertex.\n\n\n\n\n\n","category":"method"},{"location":"api/#MetaGraphsNext.weighttype-Union{Tuple{MetaGraph{<:Any, <:Any, <:Any, <:Any, <:Any, <:Any, <:Any, Weight}}, Tuple{Weight}} where Weight","page":"API reference","title":"MetaGraphsNext.weighttype","text":"weighttype(meta_graph)\n\nReturn the weight type for metagraph meta_graph.\n\n\n\n\n\n","category":"method"},{"location":"api/","page":"API reference","title":"API reference","text":"haskey\ngetindex\nsetindex!\ndelete!","category":"page"},{"location":"api/#Base.haskey","page":"API reference","title":"Base.haskey","text":"haskey(meta_graph, label)\n\nDetermine whether a MetaGraph meta_graph contains the vertex label.\n\n\n\n\n\nhaskey(meta_graph, label_1, label_2)\n\nDetermine whether a MetaGraph meta_graph contains an edge from label_1 to label_2.\n\nThe order of label_1 and label_2 only matters if meta_graph is a digraph.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.getindex","page":"API reference","title":"Base.getindex","text":"getindex(meta_graph)\n\nReturn meta_graph metadata.\n\n\n\n\n\ngetindex(meta_graph, label)\n\nReturn vertex metadata for label.\n\n\n\n\n\ngetindex(meta_graph, label_1, label_2)\n\nReturn edge metadata for the edge between label_1 and label_2.\n\n\n\n\n\ngetindex(meta_weights::MetaWeights, code_1, code_2)\n\nGet the weight of edge (code_1, code_2).\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.setindex!","page":"API reference","title":"Base.setindex!","text":"setindex!(meta_graph, data, label)\n\nSet vertex metadata for label to data.\n\n\n\n\n\nsetindex!(meta_graph, data, label_1, label_2)\n\nSet edge metadata for (label_1, label_2) to data.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.delete!","page":"API reference","title":"Base.delete!","text":"delete!(meta_graph, label)\n\nDelete vertex label.\n\n\n\n\n\ndelete!(meta_graph, label_1, label_2)\n\nDelete edge (label_1, label_2).\n\n\n\n\n\n","category":"function"},{"location":"api/","page":"API reference","title":"API reference","text":"add_vertex!\nadd_edge!\nweights","category":"page"},{"location":"api/#Graphs.SimpleGraphs.add_vertex!","page":"API reference","title":"Graphs.SimpleGraphs.add_vertex!","text":"add_vertex!(meta_graph, label, data)\n\nAdd a vertex to MetaGraph meta_graph with label label having metadata data. If the VertexData type of meta_graph is Nothing, data can be omitted.\n\nReturn true if the vertex has been added, false in case the label already exists or vertex was not added.\n\n\n\n\n\n","category":"function"},{"location":"api/#Graphs.SimpleGraphs.add_edge!","page":"API reference","title":"Graphs.SimpleGraphs.add_edge!","text":"add_edge!(meta_graph, label_1, label_2, data)\n\nAdd an edge (label_1, label_2) to MetaGraph meta_graph with metadata data. If the EdgeData type of meta_graph is Nothing, data can be omitted.\n\nReturn true if the edge has been added, false otherwise. If one of the labels does not exist, nothing happens and false is returned (the label is not inserted). If (label_1, label_2) already exists, its data is updated to data and false is returned nonetheless.\n\n\n\n\n\n","category":"function"},{"location":"api/#Graphs.weights","page":"API reference","title":"Graphs.weights","text":"weights(meta_graph)\n\nReturn a matrix-like MetaWeights object containing the edge weights for metagraph meta_graph.\n\n\n\n\n\n","category":"function"},{"location":"api/#Index","page":"API reference","title":"Index","text":"","category":"section"},{"location":"api/","page":"API reference","title":"API reference","text":"","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"EditURL = \"../../../test/tutorial/3_files.jl\"","category":"page"},{"location":"tutorial/3_files/#File-storage","page":"File storage","title":"File storage","text":"","category":"section"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"using Graphs\nusing MetaGraphsNext","category":"page"},{"location":"tutorial/3_files/#MGFormat","page":"File storage","title":"MGFormat","text":"","category":"section"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"MetaGraphsNext.jl overloads Graphs.savegraph to write graphs in a custom format called MGFormat, which is based on JLD2. It is not very readable, but it does give the right result when we load it back.","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"example = MetaGraph(Graph(), Symbol);\n\nexample2 = mktemp() do file, io\n savegraph(file, example)\n loadgraph(file, \"something\", MGFormat())\nend\n\nexample2 == example","category":"page"},{"location":"tutorial/3_files/#DOTFormat","page":"File storage","title":"DOTFormat","text":"","category":"section"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"MetaGraphsNext.jl also support the more standard DOT encoding, which is used as follows.","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"simple = MetaGraph(Graph(), Symbol);\n\nsimple[:a] = nothing;\nsimple[:b] = nothing;\nsimple[:a, :b] = nothing;\n\nsimple_str = mktemp() do file, io\n savegraph(file, simple, DOTFormat())\n read(file, String)\nend\n\nsimple_str_true = \"\"\"\ngraph T {\n \"a\"\n \"b\"\n \"a\" -- \"b\"\n}\n\"\"\"\n\nsimple_str == simple_str_true","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"complicated = MetaGraph(\n DiGraph();\n label_type=Symbol,\n vertex_data_type=Dict{Symbol,Int},\n edge_data_type=Dict{Symbol,Int},\n graph_data=(tagged=true,),\n);\n\ncomplicated[:a] = Dict(:code_1 => 1, :code_2 => 2);\n\ncomplicated[:b] = Dict(:code => 2);\n\ncomplicated[:a, :b] = Dict(:code => 12);\n\ncomplicated_str = mktemp() do file, io\n savegraph(file, complicated, DOTFormat())\n read(file, String)\nend\n\ncomplicated_str_true = \"\"\"\ndigraph G {\n tagged = true\n \"a\" [code_1 = 1, code_2 = 2]\n \"b\" [code = 2]\n \"a\" -> \"b\" [code = 12]\n}\n\"\"\"","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"with_spaces = MetaGraph(\n DiGraph();\n label_type=String,\n vertex_data_type=Dict{Symbol,String},\n edge_data_type=Dict{Symbol,String},\n)\n\nwith_spaces[\"a b\"] = Dict(:label => \"A B\")\n\nwith_spaces[\"c d\"] = Dict(:label => \"C D\")\n\nwith_spaces[\"a b\", \"c d\"] = Dict(:label => \"A B to C D\")\n\nwith_spaces_str = mktemp() do file, io\n savegraph(file, with_spaces, DOTFormat())\n read(file, String)\nend\n\nwith_spaces_str_true = \"\"\"\ndigraph G {\n \"a b\" [label = \"A B\"]\n \"c d\" [label = \"C D\"]\n \"a b\" -> \"c d\" [label = \"A B to C D\"]\n}\n\"\"\"\n\nwith_spaces_str == with_spaces_str_true","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"","category":"page"},{"location":"tutorial/3_files/","page":"File storage","title":"File storage","text":"This page was generated using Literate.jl.","category":"page"},{"location":"#MetaGraphsNext.jl","page":"Home","title":"MetaGraphsNext.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Welcome to MetaGraphsNext.jl, a type-stable replacement for MetaGraphs.jl. It allows you to create graphs with vertex and edge metadata, on which you can unleash the full power of the Graphs.jl ecosystem.","category":"page"},{"location":"#Getting-started","page":"Home","title":"Getting started","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To install the package, open the Julia REPL and type","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.add(\"MetaGraphsNext\")","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"EditURL = \"../../../test/tutorial/2_graphs.jl\"","category":"page"},{"location":"tutorial/2_graphs/#Graphs.jl-interface","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"","category":"section"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"using Graphs\nusing MetaGraphsNext","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"MetaGraphs inherit many methods from Graphs.jl. In general, inherited methods refer to vertices by codes, not labels, for compatibility with the AbstractGraph interface.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Note that vertex codes get reassigned after rem_vertex! operations to remain contiguous, so we recommend systematically converting to and from labels.","category":"page"},{"location":"tutorial/2_graphs/#Undirected-graphs","page":"Graphs.jl interface","title":"Undirected graphs","text":"","category":"section"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We can make MetaGraphs based on (undirected) Graphs.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"cities = MetaGraph(\n Graph();\n label_type=Symbol,\n vertex_data_type=String,\n edge_data_type=Int,\n graph_data=nothing,\n weight_function=identity,\n);\nnothing #hide","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Let us add some cities and the distance between them:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"cities[:Paris] = \"France\";\ncities[:London] = \"UK\";\ncities[:Berlin] = \"Germany\";\ncities[:Paris, :London] = 344;\ncities[:Paris, :Berlin] = 878;\nnothing #hide","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"The general properties of the graph are as expected:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"is_directed(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"eltype(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"edgetype(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We can check the set of vertices:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"nv(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"collect(vertices(cities))","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"has_vertex(cities, 2)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"has_vertex(cities, 4)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Note that we can't add the same city (i.e. vertex label) twice:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"add_vertex!(cities, :London, \"Italy\")","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"nv(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"cities[:London]","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We then check the set of edges:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"ne(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"collect(edges(cities))","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"has_edge(cities, 1, 2)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"has_edge(cities, 2, 3)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"From this initial graph, we can create some others:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"copy(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"zero(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Since cities is a weighted graph, we can leverage the whole Graphs.jl machinery of graph analysis and traversal:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"diameter(cities)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"ds = dijkstra_shortest_paths(cities, 2)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Finally, let us remove some edges and vertices","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"rem_edge!(cities, 1, 3);\nrem_vertex!(cities, 3);\nhas_vertex(cities, 1) && !has_vertex(cities, 3)","category":"page"},{"location":"tutorial/2_graphs/#Directed-graphs","page":"Graphs.jl interface","title":"Directed graphs","text":"","category":"section"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We can make MetaGraphs based on DiGraphs as well.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"rock_paper_scissors = MetaGraph(DiGraph(); label_type=Symbol, edge_data_type=String);\n\nfor label in [:rock, :paper, :scissors]\n rock_paper_scissors[label] = nothing\nend\n\nrock_paper_scissors[:rock, :scissors] = \"rock beats scissors\"\nrock_paper_scissors[:scissors, :paper] = \"scissors beat paper\"\nrock_paper_scissors[:paper, :rock] = \"paper beats rock\";\nnothing #hide","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"We see that the underlying graph has changed:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"is_directed(rock_paper_scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Directed graphs can be reversed:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"haskey(rock_paper_scissors, :scissors, :rock)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"haskey(reverse(rock_paper_scissors), :scissors, :rock)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Let us take a subgraph induced by a subset of vertices:","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"rock_paper, _ = induced_subgraph(rock_paper_scissors, [1, 2])","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"issubset(rock_paper, rock_paper_scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"haskey(rock_paper, :paper, :rock)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"haskey(rock_paper, :rock, :scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Subgraphs can also be induced by a subset of edges.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"subtree_edges = collect(edges(rock_paper_scissors))[2:3]\nrock_paper_scissors_subtree, _ = induced_subgraph(rock_paper_scissors, subtree_edges)\nissubset(rock_paper_scissors_subtree, rock_paper_scissors)\nne(rock_paper_scissors_subtree)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"nv(rock_paper_scissors_subtree)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"[rock_paper_scissors_subtree[e...] for e in edge_labels(rock_paper_scissors_subtree)]","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"Checking that a graph is a subset of another is not supported yet. For example, an induced subgraph may appear as not a subset of the original graph, if vertex codes were modified.","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"issubset(rock_paper_scissors_subtree, rock_paper_scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"rock_scissors, _ = induced_subgraph(rock_paper_scissors, [1, 3])\nissubset(rock_scissors, rock_paper_scissors)","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"","category":"page"},{"location":"tutorial/2_graphs/","page":"Graphs.jl interface","title":"Graphs.jl interface","text":"This page was generated using Literate.jl.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"EditURL = \"../../../test/tutorial/4_type_stability.jl\"","category":"page"},{"location":"tutorial/4_type_stability/#Type-stability","page":"Type stability","title":"Type stability","text":"","category":"section"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"using Graphs\nusing MetaGraphs: MetaGraphs\nusing MetaGraphsNext","category":"page"},{"location":"tutorial/4_type_stability/#Constructor-and-access","page":"Type stability","title":"Constructor and access","text":"","category":"section"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"In the previous examples, we used a MetaGraph constructor which receives type parameters as keyword arguments. This was done for ease of exposition, but it may impede type inference, and hence reduce performance.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"colors = MetaGraph(\n Graph(); # underlying graph structure\n label_type=Symbol, # color name\n vertex_data_type=NTuple{3,Int}, # RGB code\n edge_data_type=Symbol, # result of the addition between two colors\n graph_data=\"additive colors\", # tag for the whole graph\n)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"While casual users probably won't care, if your goal is performance, you might need to proceed differently.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Option 1: wrap the constructor in a helper function to trigger constant propagation.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"function colors_constructor()\n return MetaGraph(\n Graph();\n label_type=Symbol,\n vertex_data_type=NTuple{3,Int},\n edge_data_type=Symbol,\n graph_data=\"additive colors\",\n )\nend\n\ncolors_constructor()","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Option 2: switch to another constructor that uses positional arguments (be careful with the order!)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraph(Graph(), Symbol, NTuple{3,Int}, Symbol, \"additive colors\")","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Option 3: use the constructor for a non-empty graph instead.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"vertices_description = [:red => (255, 0, 0), :green => (0, 255, 0), :blue => (0, 0, 255)]\nedges_description = [\n (:red, :green) => :yellow, (:red, :blue) => :magenta, (:green, :blue) => :cyan\n]\nMetaGraph(cycle_graph(3), vertices_description, edges_description, \"additive colors\")","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Once Julia can infer the full type of the MetaGraph, accessing vertex and edge metadata also becomes type-stable.","category":"page"},{"location":"tutorial/4_type_stability/#Comparison-with-MetaGraphs.jl","page":"Type stability","title":"Comparison with MetaGraphs.jl","text":"","category":"section"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"In the older package MetaGraphs.jl that we used as inspiration, data types are not specified in the graph structure. Their choice allows more flexibility and an arbitrary number of attributes which the user does not need to anticipate at construction.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"colors_unstable = MetaGraphs.MetaGraph(cycle_graph(3))","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Here is how one would add data and labels to colors_unstable.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.set_indexing_prop!(colors_unstable, :label)\n\nMetaGraphs.set_prop!(colors_unstable, :graph_tag, \"additive colors\")\n\nMetaGraphs.set_props!(colors_unstable, 1, Dict(:label => :red, :rgb_code => (255, 0, 0)))\nMetaGraphs.set_props!(colors_unstable, 2, Dict(:label => :green, :rgb_code => (0, 255, 0)))\nMetaGraphs.set_props!(colors_unstable, 3, Dict(:label => :blue, :rgb_code => (0, 0, 255)))\n\nMetaGraphs.set_prop!(colors_unstable, 1, 2, :addition_result, :yellow)\nMetaGraphs.set_prop!(colors_unstable, 1, 3, :addition_result, :magenta)\nMetaGraphs.set_prop!(colors_unstable, 2, 3, :addition_result, :cyan);\nnothing #hide","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"One can retrieve the vertex index (which we called code) using any indexing property.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"colors_unstable[:green, :label]","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"Then we can access vertex properties...","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.get_prop(colors_unstable, 2, :rgb_code)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.props(colors_unstable, 2)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"... and edge properties.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.get_prop(colors_unstable, 2, 3, :addition_result)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"MetaGraphs.props(colors_unstable, 2, 3)","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"The fact that the outputs of these calls to props are of type Dict{Symbol, Any} is at the root of the problem. It means that if we use their values in any subsequent algorithms, we introduce type instability in our code (due to Any). MetaGraphsNext.jl overcomes this obstacle thanks to a more precise storage method.","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"","category":"page"},{"location":"tutorial/4_type_stability/","page":"Type stability","title":"Type stability","text":"This page was generated using Literate.jl.","category":"page"}] } diff --git a/dev/tutorial/1_basics/index.html b/dev/tutorial/1_basics/index.html index 715c1a6..c9c3861 100644 --- a/dev/tutorial/1_basics/index.html +++ b/dev/tutorial/1_basics/index.html @@ -39,4 +39,4 @@ weighted[:alice, :bob] = 2.0; weighted[:bob, :charlie] = 3.0;
weight_matrix = Graphs.weights(weighted)
MetaWeights of size (3, 3)
default_weight(weighted)
Inf
size(weight_matrix)
(3, 3)
weight_matrix[1, 2]
4.0
weight_matrix[2, 3]
9.0
weight_matrix[1, 3]
Inf
wf = get_weight_function(weighted)
-wf(4.0)
16.0

You can then use all functions from Graphs.jl that require weighted graphs (see the rest of the tutorial).


This page was generated using Literate.jl.

+wf(4.0)
16.0

You can then use all functions from Graphs.jl that require weighted graphs (see the rest of the tutorial).


This page was generated using Literate.jl.

diff --git a/dev/tutorial/2_graphs/index.html b/dev/tutorial/2_graphs/index.html index 41825fb..1820825 100644 --- a/dev/tutorial/2_graphs/index.html +++ b/dev/tutorial/2_graphs/index.html @@ -32,4 +32,4 @@ ne(rock_paper_scissors_subtree)
2
nv(rock_paper_scissors_subtree)
3
[rock_paper_scissors_subtree[e...] for e in edge_labels(rock_paper_scissors_subtree)]
2-element Vector{String}:
  "paper beats rock"
  "scissors beat paper"

Checking that a graph is a subset of another is not supported yet. For example, an induced subgraph may appear as not a subset of the original graph, if vertex codes were modified.

issubset(rock_paper_scissors_subtree, rock_paper_scissors)
false
rock_scissors, _ = induced_subgraph(rock_paper_scissors, [1, 3])
-issubset(rock_scissors, rock_paper_scissors)
false

This page was generated using Literate.jl.

+issubset(rock_scissors, rock_paper_scissors)
false

This page was generated using Literate.jl.

diff --git a/dev/tutorial/3_files/index.html b/dev/tutorial/3_files/index.html index 6de2807..027c56a 100644 --- a/dev/tutorial/3_files/index.html +++ b/dev/tutorial/3_files/index.html @@ -78,4 +78,4 @@ } """ -with_spaces_str == with_spaces_str_true
true

This page was generated using Literate.jl.

+with_spaces_str == with_spaces_str_true
true

This page was generated using Literate.jl.

diff --git a/dev/tutorial/4_type_stability/index.html b/dev/tutorial/4_type_stability/index.html index 86d6183..69e8bfd 100644 --- a/dev/tutorial/4_type_stability/index.html +++ b/dev/tutorial/4_type_stability/index.html @@ -34,4 +34,4 @@ MetaGraphs.set_prop!(colors_unstable, 2, 3, :addition_result, :cyan);

One can retrieve the vertex index (which we called code) using any indexing property.

colors_unstable[:green, :label]
2

Then we can access vertex properties...

MetaGraphs.get_prop(colors_unstable, 2, :rgb_code)
(0, 255, 0)
MetaGraphs.props(colors_unstable, 2)
Dict{Symbol, Any} with 2 entries:
   :rgb_code => (0, 255, 0)
   :label    => :green

... and edge properties.

MetaGraphs.get_prop(colors_unstable, 2, 3, :addition_result)
:cyan
MetaGraphs.props(colors_unstable, 2, 3)
Dict{Symbol, Any} with 1 entry:
-  :addition_result => :cyan

The fact that the outputs of these calls to props are of type Dict{Symbol, Any} is at the root of the problem. It means that if we use their values in any subsequent algorithms, we introduce type instability in our code (due to Any). MetaGraphsNext.jl overcomes this obstacle thanks to a more precise storage method.


This page was generated using Literate.jl.

+ :addition_result => :cyan

The fact that the outputs of these calls to props are of type Dict{Symbol, Any} is at the root of the problem. It means that if we use their values in any subsequent algorithms, we introduce type instability in our code (due to Any). MetaGraphsNext.jl overcomes this obstacle thanks to a more precise storage method.


This page was generated using Literate.jl.

diff --git a/dev/tutorial/5_benchmark/index.html b/dev/tutorial/5_benchmark/index.html index a764fa8..adb1120 100644 --- a/dev/tutorial/5_benchmark/index.html +++ b/dev/tutorial/5_benchmark/index.html @@ -34,7 +34,7 @@ MetaGraphs.set_prop!(mg, i, j, :distance, rand(Float64)) end return mg -end;
@btime build_incremental_metagraphsnext(100);
  510.583 μs (458 allocations: 744.16 KiB)
@btime build_bulk_metagraphsnext(100);
  254.616 μs (274 allocations: 998.67 KiB)
@btime build_metagraphs(100);
  1.101 ms (45901 allocations: 5.08 MiB)

Graph exploitation

function sum_active_edges_metagraphsnext(mg)
+end;
@btime build_incremental_metagraphsnext(100);
  508.635 μs (458 allocations: 744.16 KiB)
@btime build_bulk_metagraphsnext(100);
  272.271 μs (274 allocations: 998.67 KiB)
@btime build_metagraphs(100);
  1.145 ms (45901 allocations: 5.08 MiB)

Graph exploitation

function sum_active_edges_metagraphsnext(mg)
     S = 0.0
     for (li, lj) in MetaGraphsNext.edge_labels(mg)
         active_i = mg[li]
@@ -58,8 +58,8 @@
     end
     return S
 end
sum_active_edges_metagraphs (generic function with 1 method)
mg1 = build_incremental_metagraphsnext(100);
-@btime sum_active_edges_metagraphsnext($mg1);
  178.473 μs (0 allocations: 0 bytes)
mg2 = build_metagraphs(100);
-@btime sum_active_edges_metagraphs($mg2);
  456.222 μs (903 allocations: 14.11 KiB)

The difference in performance can be explained by type instability.

@code_warntype sum_active_edges_metagraphsnext(mg1);
MethodInstance for Main.sum_active_edges_metagraphsnext(::MetaGraph{Int64, SimpleGraph{Int64}, Int64, Bool, Float64, Nothing, MetaGraphsNext.var"#11#13", Float64})
+@btime sum_active_edges_metagraphsnext($mg1);
  190.668 μs (0 allocations: 0 bytes)
mg2 = build_metagraphs(100);
+@btime sum_active_edges_metagraphs($mg2);
  490.360 μs (1540 allocations: 24.06 KiB)

The difference in performance can be explained by type instability.

@code_warntype sum_active_edges_metagraphsnext(mg1);
MethodInstance for Main.sum_active_edges_metagraphsnext(::MetaGraph{Int64, SimpleGraph{Int64}, Int64, Bool, Float64, Nothing, MetaGraphsNext.var"#11#13", Float64})
   from sum_active_edges_metagraphsnext(mg) @ Main 5_benchmark.md:87
 Arguments
   #self#::Core.Const(Main.sum_active_edges_metagraphsnext)
@@ -170,4 +170,4 @@
 └──       goto #7 if not %40
 6 ─       goto #2
 7 ┄ %43 = S::ANY
-└──       return %43

This page was generated using Literate.jl.

+└── return %43

This page was generated using Literate.jl.