API Reference

Core Types and Functions

GraphCore.AdjGraphType
AdjGraph{D} <: GraphInterface

Dynamic graph using adjacency lists (Vector{Vector{Int32}}) for neighbor storage. Optimized for structural mutations with reasonable query performance.

Type Parameters

  • D::Bool: Directedness flag (true = directed, false = undirected)

Fields (Internal - Access via interface methods)

  • neighbors::Vector{Vector{Int32}}: Per-vertex neighbor lists
  • neighbor_to_edge::Vector{Vector{Int32}}: Maps neighbor positions to edge indices (undirected only)
  • num_edges::Int32: Number of (undirected) edges

Construction

Use build_adj_graph() or build_graph(AdjGraph, ...) for safe construction:

# Basic construction
edges = [(1,2), (2,3), (1,3)]
g = build_adj_graph(edges; directed=false)

# Direct type construction with mutation
g = build_graph(AdjGraph, edges; directed=false)
add_edge!(g, 4, 1)  # Efficient dynamic modification

Memory Layout Example

For graph with edges [(1,2), (2,3), (1,3)], undirected:

neighbors = [[2,3], [1,3], [1,2]]           # Vertex 1: neighbors 2,3; Vertex 2: neighbors 1,3, etc.
neighbor_to_edge = [[1,3], [1,2], [3,2]]    # Maps: v1's neighbor 2→edge 1, v1's neighbor 3→edge 3, etc.

Performance Notes

  • Best for: Dynamic graphs with frequent add/remove operations
  • Mutations: O(1) additions, O(degree) removals
  • Memory: ~16-24 bytes per directed edge (vector overhead + pointers)
  • Cache: Good for sparse graphs, less optimal for dense graphs

Mutation Support

# Efficient dynamic operations
new_vertex = add_vertex!(g)           # O(1) - just adds empty vectors
edge_idx = add_edge!(g, u, v)         # O(1) amortized - vector push
success = remove_edge!(g, u, v)       # O(degree) - find and remove
success = remove_vertex!(g, v)        # O(V + incident edges) - updates all references

# ⚠️ Warning: Removals may invalidate edge indices
# External arrays indexed by edges will become inconsistent
source
GraphCore.AdjGraphMethod
AdjGraph(g::GraphInterface) -> AdjGraph

Convert any GraphInterface implementation to an AdjGraph using constructor syntax. This is an idiomatic Julia alternative to to_adj_graph(g).

Examples

# Constructor style (idiomatic)
adj_g = AdjGraph(core_graph)

# Equivalent to conversion function
adj_g = to_adj_graph(core_graph)
source
GraphCore.AdjGraphMethod
AdjGraph{D}(g::GraphInterface) -> AdjGraph{D}

Convert any GraphInterface to an AdjGraph with explicit directedness type parameter. The source graph must have the same directedness as specified by the type parameter.

Examples

# Type-safe conversions (will succeed)
directed_adj = AdjGraph{true}(directed_core_graph)
undirected_adj = AdjGraph{false}(undirected_core_graph)

# Type mismatch (will throw AssertionError)
# AdjGraph{true}(undirected_graph)  # ERROR!
source
GraphCore.CoreGraphType
CoreGraph{D} <: GraphInterface

High-performance graph using Compressed Sparse Row (CSR) storage format.

Type Parameters

  • D::Bool: Directedness flag (true = directed, false = undirected)

Fields (Internal - Access via interface methods)

  • vertex_offsets::Vector{Int32}: CSR row pointers (length = nv + 1)
  • neighbors::Vector{Int32}: Flattened neighbor lists
  • neighbor_to_edge::Vector{Int32}: Maps neighbor positions to undirected edge indices (undirected only)
  • num_edges::Int32: Number of (undirected) edges

Construction

Use build_core_graph() or build_graph(CoreGraph, ...) for safe construction:

# Basic construction
edges = [(1,2), (2,3), (1,3)]
g = build_core_graph(edges; directed=false)

# With validation disabled (faster, but unsafe)
g = build_graph(CoreGraph, edges; directed=false, validate=false)

Memory Layout Example

For graph with edges [(1,2), (2,3), (1,3)], undirected:

vertex_offsets = [1, 3, 6, 8]       # Vertex 1: neighbors[1:2], Vertex 2: neighbors[3:5], etc.
neighbors = [2, 3, 1, 3, 1, 2]      # Flattened: [neighbors(1), neighbors(2), neighbors(3)]
neighbor_to_edge = [1, 3, 1, 2, 3, 2] # Maps each neighbor to its edge index

Performance Notes

  • Best for: Static graphs with frequent neighbor access
  • Avoid for: Graphs requiring frequent structural modifications
  • Memory: ~12-16 bytes per directed edge (depending on architecture)
  • Cache: Excellent locality for neighbor iteration
source
GraphCore.CoreGraphMethod
CoreGraph(g::GraphInterface) -> CoreGraph

Convert any GraphInterface implementation to a CoreGraph using constructor syntax. This is an idiomatic Julia alternative to to_core_graph(g).

Examples

# Constructor style (idiomatic)
core_g = CoreGraph(adj_graph)

# Equivalent to conversion function
core_g = to_core_graph(adj_graph)
source
GraphCore.CoreGraphMethod
CoreGraph{D}(g::GraphInterface) -> CoreGraph{D}

Convert any GraphInterface to a CoreGraph with explicit directedness type parameter. The source graph must have the same directedness as specified by the type parameter.

Examples

# Type-safe conversions (will succeed)
directed_core = CoreGraph{true}(directed_adj_graph)
undirected_core = CoreGraph{false}(undirected_adj_graph)

# Type mismatch (will throw TypeError)
# CoreGraph{true}(undirected_graph)  # ERROR!
source
GraphCore.GraphInterfaceType
GraphInterface <: AbstractGraph{Int32}

Base abstract type for all graphs in the GraphCore ecosystem. All vertices are indexed by Int32 integers 1, 2, ..., num_vertices(g).

source
GraphCore.PropertyGraphType
PropertyGraph{G,V,E} <: PropertyGraphInterface{V,E}

Universal property graph that wraps any base graph type with typed vertex and edge properties.

Type Parameters

  • G<:GraphInterface: Base graph type (CoreGraph, WeightedGraph, AdjGraph, etc.)
  • V: Vertex property type
  • E: Edge property type

Design Benefits

  • Universal wrapper: Works with any GraphInterface implementation
  • Zero-cost delegation: All structural operations forwarded to base graph
  • Type safety: Compile-time property type guarantees
  • Automatic mutations: Inherits mutation capabilities from base graph
  • Memory efficiency: No overhead when properties are unused

Usage Patterns

# Static analysis with CoreGraph base
core_g = build_core_graph(edges; directed=false)
vertex_labels = ["Alice", "Bob", "Charlie"]
edge_types = ["friend", "colleague", "family"]
pg = PropertyGraph(core_g, vertex_labels, edge_types)

# Access patterns
name = pg[1]                           # Vertex property via indexing
edge_type = edge_property(pg, 2)       # Edge property by index
pg[1] = "Alice Updated"                # Property modification

# Dynamic graphs with AdjGraph base
adj_g = build_adj_graph(edges; directed=false)
pg_mut = PropertyGraph(adj_g, vertex_labels, edge_types)

# Efficient mutations (when base graph supports them)
new_vertex = add_vertex!(pg_mut, "David")           # O(1) addition
edge_idx = add_edge!(pg_mut, 1, new_vertex, "buddy")  # O(1) addition

# Combined with weights
weighted_g = build_weighted_graph(edges, weights; directed=false)
pg = PropertyGraph(weighted_g, vertex_labels, edge_types)
# Now has both weights and properties available

Mutation Behavior

# Mutations work when base graph supports them
adj_pg = PropertyGraph(build_adj_graph(edges), v_props, e_props)
add_edge!(adj_pg, u, v, edge_prop)  # ✅ Works - AdjGraph supports mutations

# Mutations fail gracefully when base graph doesn't support them
core_pg = PropertyGraph(build_core_graph(edges), v_props, e_props)
add_edge!(core_pg, u, v, edge_prop)  # ❌ MethodError - CoreGraph is immutable

# Property arrays are automatically maintained during mutations
original_count = length(adj_pg.edge_properties)
edge_idx = add_edge!(adj_pg, u, v, edge_prop)
@assert length(adj_pg.edge_properties) == original_count + 1

Performance Notes

  • Delegation overhead: Typically optimized away by compiler
  • Mutation performance: Same as underlying graph type
  • Property management: Automatic with minimal overhead
  • Memory: Base graph memory + property arrays + small wrapper overhead
source
GraphCore.WeightedAdjGraphType
WeightedAdjGraph{W,D} <: WeightedGraphInterface{W}

Weighted dynamic graph extending AdjGraph with parallel weight storage. Combines the mutation efficiency of adjacency lists with type-safe weights.

Type Parameters

  • W<:Number: Weight type (Float64, Int32, etc.)
  • D::Bool: Directedness flag

Key Features

  • Same mutation performance as AdjGraph for structural operations
  • Type-safe weights with compile-time guarantees
  • Directional weights even for undirected graphs
  • Parallel storage maintaining weight-neighbor correspondence

Weight Semantics

Important: Weights are always directional, even for undirected graphs. This allows asymmetric edge properties while maintaining undirected connectivity.

# For undirected edge with different directional costs:
g = build_weighted_adj_graph([(1,2)], [1.5]; directed=false)
# Internally stores: neighbors[1]=[2], weights[1]=[1.5]
#                   neighbors[2]=[1], weights[2]=[1.5]
# But weights can be modified independently if needed

# Access via directional indexing:
idx_12 = find_directed_edge_index(g, 1, 2)  # Different from (2,1)
idx_21 = find_directed_edge_index(g, 2, 1)
weight_12 = edge_weight(g, idx_12)  # Initial: 1.5
weight_21 = edge_weight(g, idx_21)  # Initial: 1.5 (same value, different storage)

Mutation Examples

edges = [(1,2), (2,3)]
weights = [1.0, 2.0]
g = build_weighted_adj_graph(edges, weights; directed=false)

# Add weighted edge
edge_idx = add_edge!(g, 3, 1, 1.5)  # O(1) amortized

# Efficient weight access during iteration
for (neighbor, weight) in neighbor_weights(g, v)
    process_weighted_neighbor(neighbor, weight)
end
source
GraphCore.WeightedAdjGraphMethod
WeightedAdjGraph(g::WeightedGraphInterface{W}) -> WeightedAdjGraph{W}
WeightedAdjGraph{W}(g::WeightedGraphInterface{W}) -> WeightedAdjGraph{W}
WeightedAdjGraph{W,D}(g::WeightedGraphInterface{W}) -> WeightedAdjGraph{W,D}

Convert any WeightedGraphInterface to a WeightedAdjGraph using constructor syntax. Supports multiple forms with different levels of type specification.

Constructor Forms

  • WeightedAdjGraph(g): Auto-infer weight type and directedness
  • WeightedAdjGraph{W}(g): Explicit weight type parameter
  • WeightedAdjGraph{W,D}(g): Explicit weight type and directedness parameters

Examples

# Basic constructor (auto-infer types)
weighted_adj = WeightedAdjGraph(weighted_core_graph)

# Explicit weight type
weighted_adj = WeightedAdjGraph{Float64}(core_graph)

# Full type specification
# Full type specification with directedness assertion
directed_weighted_adj = WeightedAdjGraph{Float64,true}(directed_weighted_graph)   # ✅ OK
undirected_weighted_adj = WeightedAdjGraph{Float64,false}(undirected_weighted_graph) # ✅ OK
# WeightedAdjGraph{Float64,true}(undirected_graph)  # ❌ ERROR: directedness mismatch

# Equivalent to conversion function
weighted_adj = to_weighted_adj_graph(weighted_core_graph)
source
GraphCore.WeightedGraphType
WeightedGraph{W,D} <: WeightedGraphInterface{W}

Weighted graph extending CoreGraph with parallel weight storage.

Type Parameters

  • W<:Number: Weight type (Float64, Int32, etc.)
  • D::Bool: Directedness flag

Key Features

  • Same performance as CoreGraph for structural operations
  • Type-safe weights with compile-time guarantees
  • Directional weights even for undirected graphs
  • Parallel storage for cache-efficient weight access

Weight Semantics

Important: Weights are always directional, even for undirected graphs. This allows asymmetric edge properties (e.g., different costs per direction).

# For undirected edge (1,2) with weight 1.5:
edge_weight(g, find_directed_edge_index(g, 1, 2)) # → 1.5
edge_weight(g, find_directed_edge_index(g, 2, 1)) # → 1.5 (same value, different index)

# But can be set differently if needed:
weights = [1.5, 2.0]  # Different costs for each direction
g = build_weighted_graph([(1,2), (2,1)], weights; directed=true)

Construction Examples

# Undirected weighted graph
edges = [(1,2), (2,3)]
weights = [1.5, 2.0]
g = build_weighted_graph(edges, weights; directed=false)

# Type-specific construction
g = build_graph(WeightedGraph{Float32}, edges; weights=weights, directed=false)
source
GraphCore.WeightedGraphMethod
WeightedGraph(g::WeightedGraphInterface{W}) -> WeightedGraph{W}
WeightedGraph{W}(g::WeightedGraphInterface{W}) -> WeightedGraph{W}
WeightedGraph{W,D}(g::WeightedGraphInterface{W}) -> WeightedGraph{W,D}

Convert any WeightedGraphInterface to a WeightedGraph using constructor syntax. Supports multiple forms with different levels of type specification.

Constructor Forms

  • WeightedGraph(g): Auto-infer weight type and directedness
  • WeightedGraph{W}(g): Explicit weight type parameter
  • WeightedGraph{W,D}(g): Explicit weight type and directedness parameters (with type assertion)

Examples

# Basic constructor (auto-infer types)
weighted_g = WeightedGraph(weighted_adj_graph)

# Explicit weight type
weighted_g = WeightedGraph{Float64}(adj_graph)

# Full type specification with directedness assertion
directed_weighted = WeightedGraph{Float64,true}(directed_weighted_graph)   # ✅ OK
undirected_weighted = WeightedGraph{Float64,false}(undirected_weighted_graph) # ✅ OK
# WeightedGraph{Float64,true}(undirected_graph)  # ❌ ERROR: directedness mismatch

# Equivalent to conversion function
weighted_g = to_weighted_graph(weighted_adj_graph)
source
GraphCore.WeightedGraphInterfaceType
WeightedGraphInterface <: GraphInterface

Interface for weighted graphs, extending the core graph interface. W is the type of edge weights, typically a numeric type.

source
GraphCore.add_edge!Function
add_edge!(g::GraphInterface, u::Integer, v::Integer, ...) -> Int32

Add an edge from u to v with the optinal properties. Returns the edge index of the newly added edge, or 0 if edge already exists. For undirected graphs, this adds the edge in both directions internally. Only available for mutable graph types.

source
GraphCore.add_edge!Method
add_edge!(g::AdjGraph, u::Integer, v::Integer) -> Int32

Add an edge from u to v and return the edge index (or 0 if already exists).

Performance

  • Time Complexity: O(1) amortized (vector push operations)
  • Space Complexity: O(1) per direction
  • Index Stability: All existing indices remain valid, new edge gets max+1

Behavior Details

  • Directed graphs: Adds only u→v edge
  • Undirected graphs: Adds both u→v and v→u internally with same edge index
  • Duplicate detection: Returns 0 if edge already exists (no modification)
  • Index assignment: New edges get next available index

Examples

g = build_adj_graph([(1,2)]; directed=false)
@assert num_edges(g) == 1

# Add new edge
edge_idx = add_edge!(g, 2, 3)
@assert edge_idx == 2  # Next available index
@assert num_edges(g) == 2
@assert has_edge(g, 2, 3) && has_edge(g, 3, 2)  # Both directions for undirected

# Try duplicate
duplicate_idx = add_edge!(g, 1, 2)
@assert duplicate_idx == 0  # Already exists
@assert num_edges(g) == 2    # No change

Error Conditions

Throws BoundsError if vertices u or v don't exist in the graph. Use add_vertex! first if needed.

source
GraphCore.add_edge!Method
add_edge!(g::CoreGraph, u::Integer, v::Integer) -> Int32

Add an edge from u to v and return the edge index (or 0 if edge already exists).

Efficient Implementation: O(degree) operation that extends the CSR arrays and updates offsets.

For undirected graphs, this adds the edge in both directions internally.

Example

g = build_core_graph([(1,2)]; directed=false)
edge_idx = add_edge!(g, 1, 3)  # Returns edge index
@assert has_edge(g, 1, 3) && has_edge(g, 3, 1)  # Both directions for undirected
source
GraphCore.add_edge!Method
add_edge!(g::WeightedGraph{W}, u::Integer, v::Integer, weight::W) -> Int32

Add a weighted edge from u to v and return the edge index (or 0 if edge already exists).

Efficient Implementation: O(degree) operation that extends the CSR arrays and updates offsets.

source
GraphCore.add_edge!Method
add_edge!(g::PropertyGraph{G,V,E}, u::Integer, v::Integer, edge_prop::E) -> Int32

Add an edge from u to v with the specified edge property. Returns the edge index of the newly added edge, or 0 if edge already exists.

Only available when the base graph type supports add_edge!. Property arrays are automatically maintained.

source
GraphCore.add_edge!Method
add_edge!(g::PropertyGraph{<:WeightedGraphInterface,V,E}, u::Integer, v::Integer,
          weight::W, edge_prop::E) -> Int32

Add a weighted edge from u to v with the specified weight and edge property. Returns the edge index of the newly added edge, or 0 if edge already exists.

Only available when the base graph type supports weighted add_edge!.

source
GraphCore.add_edge!Method
add_edge!(g::WeightedAdjGraph{W}, u::Integer, v::Integer, weight::W) -> Int32

Add a weighted edge from u to v in the graph. Returns the edge index of the newly added edge, or 0 if edge already exists. For undirected graphs, both directions get the same weight.

source
GraphCore.add_vertex!Function
add_vertex!(g::GraphInterface, ...) -> Int32

Add a new vertex with optional properties. Returns the index of the newly added vertex. Only available for mutable graph types.

source
GraphCore.add_vertex!Method
add_vertex!(g::AdjGraph) -> Int32

Add a new isolated vertex to the graph and return its index.

Performance

  • Time Complexity: O(1)
  • Space Complexity: O(1) - just adds empty vectors
  • Index Stability: All existing vertex/edge indices remain valid

Implementation Details

Creates empty neighbor list and empty neighbortoedge mapping. New vertex has no neighbors initially and can be connected via add_edge!.

Examples

g = build_adj_graph([(1,2), (2,3)]; directed=false)
@assert num_vertices(g) == 3

new_v = add_vertex!(g)
@assert new_v == 4
@assert num_vertices(g) == 4
@assert degree(g, new_v) == 0  # Isolated vertex

# Connect new vertex
add_edge!(g, 1, new_v)
@assert degree(g, new_v) == 1
source
GraphCore.add_vertex!Method
add_vertex!(g::CoreGraph) -> Int32

Add a new isolated vertex to the graph and return its index.

Efficient Implementation: O(1) operation that simply extends the vertex_offsets array.

Example

g = build_core_graph([(1,2), (2,3)]; directed=false)
new_vertex = add_vertex!(g)  # Returns 4
@assert num_vertices(g) == 4
@assert length(neighbor_indices(g, new_vertex)) == 0  # Isolated vertex
source
GraphCore.add_vertex!Method
add_vertex!(g::PropertyGraph{G,V,E}, vertex_prop::V) -> Int32

Add a new vertex to the property graph with the specified property. Returns the index of the new vertex.

Only available when the base graph type supports add_vertex!.

source
GraphCore.add_vertex!Method
add_vertex!(g::WeightedAdjGraph{W}) -> Int32 where W

Add a new vertex to the weighted graph and return its index. The new vertex has no neighbors initially.

source
GraphCore.add_vertex!Method
add_vertex!(g::WeightedGraph) -> Int32

Add a new isolated vertex to the weighted graph and return its index.

Efficient Implementation: O(1) operation that simply extends the vertex_offsets array.

source
GraphCore.all_directed_edgesMethod
all_directed_edges(g::GraphInterface) -> Iterator

Return an iterator over all directed edges in the graph.

  • For directed graphs: yields (source, target) pairs for each directed edge
  • For undirected graphs: yields (u, v) and (v, u) pairs for each undirected edge

Examples

for (u, v) in all_directed_edges(g)
    println("Directed edge from ", u, " to ", v)
end
source
GraphCore.all_edgesMethod
all_edges(g::GraphInterface) -> Iterator

Alias for edges(g). Provided for disambiguation when using multiple graph libraries.

See also: edges

source
GraphCore.build_graphMethod
build_graph(::Type{PropertyGraph{G,V,E}}, edges; kwargs...) where {G,V,E}

Build a property graph with vertex and edge properties. The underlying graph type G determines performance characteristics (CoreGraph for CSR, AdjGraph for adjacency list).

Arguments

  • edges: Vector of (u,v) tuples/pairs representing graph edges
  • directed=true: Whether the graph is directed
  • vertex_properties=[]: Properties for each vertex (type V)
  • edge_properties=[]: Properties for each edge (type E)
  • weights=[]: Edge weights (optional)
  • validate=true: Whether to validate inputs

Examples

# Property graph with CoreGraph backend
g = build_graph(PropertyGraph{CoreGraph,String,String}, [(1,2), (2,3)];
                vertex_properties=["A", "B", "C"], edge_properties=["e1", "e2"])

# Property graph with AdjGraph backend for dynamic use
g = build_graph(PropertyGraph{AdjGraph,Int,Symbol}, [(1,2), (2,3)];
                vertex_properties=[1, 2, 3], edge_properties=[:a, :b])
source
GraphCore.build_graphMethod
build_graph(::Type{G}, edges; kwargs...) where {G<:AdjGraphTypes}

Build adjacency list graph optimized for dynamic modifications and mutations.

Arguments

  • edges: Vector of (u,v) tuples/pairs representing graph edges
  • directed=true: Whether to build a directed graph
  • weights=[]: Edge weights (for WeightedAdjGraph types)
  • validate=true: Enable input validation

Performance Characteristics

  • Dynamic-friendly: Efficient vertex/edge additions and removals
  • Memory flexible: Grows naturally, higher overhead than CSR
  • Mutation-optimized: O(1) edge additions, efficient vertex operations

Use AdjGraph types when frequent graph modifications are expected. For static graphs with performance-critical traversals, prefer CoreGraph types.

source
GraphCore.build_graphMethod
build_graph(::Type{G}, edges; kwargs...) -> G

Build a graph from an edge list with comprehensive validation and flexible options.

Arguments

  • edges: Vector of (u,v) tuples/pairs representing graph edges
  • directed=true: Whether to build a directed graph
  • n=0: Number of vertices (0 = auto-detect from edges)
  • weights=[]: Edge weights (for WeightedGraph types)
  • validate=true: Enable input validation (recommended for safety)

Examples

# Basic graphs
g = build_graph(CoreGraph, [(1,2), (2,3)]; directed=false)
wg = build_graph(WeightedGraph{Float64}, [(1,2), (2,3)]; weights=[1.5, 2.0], directed=false)

# Graph with isolated vertices
g = build_graph(CoreGraph, [(1,2)]; n=5, directed=false)  # Creates isolated vertices 3,4,5

# High-performance mode (skip validation)
g = build_graph(CoreGraph, trusted_edges; directed=false, validate=false)

Optimized for CSR representation with efficient construction and memory usage. For dynamic graphs requiring frequent mutations, consider AdjGraph types.

source
GraphCore.build_property_adj_graphMethod
build_property_adj_graph(edges, vertex_properties, edge_properties; directed=true, kwargs...)

Build a PropertyGraph with AdjGraph backend (supports efficient mutations).

Arguments

  • edges: Vector of (u,v) tuples representing graph edges
  • vertex_properties: Vector of vertex properties
  • edge_properties: Vector of edge properties
  • directed=true: Whether to build a directed graph
  • kwargs...: Additional arguments passed to underlying graph construction

Example

edges = [(1,2), (2,3)]
vertex_props = [1, 2, 3]
edge_props = [:a, :b]
pg = build_property_adj_graph(edges, vertex_props, edge_props; directed=false)
source
GraphCore.build_property_graphMethod
build_property_graph(edges, vertex_properties, edge_properties; directed=true, kwargs...)

Build a PropertyGraph with CoreGraph backend.

Arguments

  • edges: Vector of (u,v) tuples representing graph edges
  • vertex_properties: Vector of vertex properties
  • edge_properties: Vector of edge properties
  • directed=true: Whether to build a directed graph
  • kwargs...: Additional arguments passed to underlying graph construction

Example

edges = [(1,2), (2,3), (1,3)]
vertex_props = ["Alice", "Bob", "Charlie"]
edge_props = ["friend", "colleague", "family"]
pg = build_property_graph(edges, vertex_props, edge_props; directed=false)
source
GraphCore.canonicalize_edgesMethod
canonicalize_edges(edges) -> Vector{Tuple{Int,Int}}

Convert symmetric edge format to canonical format for undirected graphs.

Arguments

  • edges: Vector of (u,v) tuples representing edges

Returns

  • Vector of canonical edges where u ≤ v for each edge

Format Conversion

  • Input: [(1,2), (2,1), (2,3), (3,2)] (both directions)
  • Output: [(1,2), (2,3)] (canonical: u ≤ v)

Use when your input has both directions listed for undirected edges. This removes duplicates and ensures a consistent canonical representation.

Example

edges = [(1,2), (2,1), (2,3), (3,2), (1,3), (3,1)]
canonical = GraphCore.canonicalize_edges(edges)
# Result: [(1,2), (1,3), (2,3)]
source
GraphCore.canonicalize_edgesMethod
canonicalize_edges(edges, weights::AbstractVector{W}) -> (canonical_edges, canonical_weights)

Convert symmetric format to canonical, keeping weights for canonical edges only.

Arguments

  • edges: Vector of (u,v) tuples representing edges
  • weights: Vector of weights corresponding to edges

Returns

  • Tuple of (canonicaledges, canonicalweights)

Behavior

When multiple weights exist for the same undirected edge, keeps the first encountered weight. This is useful when processing datasets that list both directions with potentially different weights.

Example

edges = [(1,2), (2,1), (2,3), (3,2)]
weights = [1.5, 1.5, 2.0, 2.1]  # Note: slight difference in last weight
canonical_edges, canonical_weights = GraphCore.canonicalize_edges(edges, weights)
# Result: edges = [(1,2), (2,3)], weights = [1.5, 2.0]
source
GraphCore.degreeMethod
degree(g::GraphInterface, v::Integer) -> Int32

Return the degree of vertex v (number of neighbors).

source
GraphCore.directed_edge_indexFunction
directed_edge_index(g::GraphInterface, v::Integer, i::Integer) -> Int32

Get the directed edge index for the i-th neighbor of vertex v.

Similar to edge_index but for directional properties. Always provides directional indexing even for undirected graphs.

Key difference: For undirected graphs:

  • edge_index(g, u, i) == edge_index(g, v, j) if neighbors are the same edge
  • directed_edge_index(g, u, i) ≠ directed_edge_index(g, v, j) (always directional)

This enables asymmetric properties on undirected graphs (e.g., different costs for traversing an edge in each direction).

source
GraphCore.directed_edge_indicesFunction
directed_edge_indices(g::GraphInterface, v::Integer) -> view or iterator

Return an iterator over the directed edge indices for edges from vertex v. The i-th edge index corresponds to the i-th neighbor in neighbor_indices(g, v). For directed graphs this is the same asdirectededgeindices(g, v)`.

source
GraphCore.directed_edge_indicesMethod
directed_edge_indices(g::GraphInterface) -> UnitRange{Int}

Return a range over all directed edge indices. Suitable for sizing and indexing external directed edge property arrays.

source
GraphCore.edge_indexFunction
edge_index(g::GraphInterface, v::Integer, i::Integer) -> Int32

Get the undirected edge index for the i-th neighbor of vertex v.

This provides O(1) conversion from neighbor position to edge index, enabling efficient indexing into external edge property arrays.

Relationship: edge_index(g, v, i) == find_edge_index(g, v, neighbor_indices(g, v)[i])

Use case: Processing neighbors with associated edge data

edge_weights = Vector{Float64}(undef, num_edges(g))
for (i, neighbor) in enumerate(neighbor_indices(g, v))
    edge_idx = edge_index(g, v, i)           # O(1) - no search needed!
    weight = edge_weights[edge_idx]          # Direct array access
    process_neighbor_with_weight(neighbor, weight)
end

Index stability: Edge indices remain stable during graph analysis, but may be invalidated by structural modifications (add/remove operations).

source
GraphCore.edge_indicesFunction
edge_indices(g::GraphInterface, v::Integer) -> view or iterator

Return an iterator over the undirected edge indices for edges from vertex v. The i-th edge index corresponds to the i-th neighbor in neighbor_indices(g, v).

source
GraphCore.edge_indicesMethod
edge_indices(g::GraphInterface) -> UnitRange{Int}

Return a range over all undirected edge indices. Suitable for sizing and indexing external edge property arrays.

source
GraphCore.edge_propertiesFunction
edge_properties(g::PropertyGraphInterface) -> iterator

Return an iterator over all edge properties in edge index order.

source
GraphCore.edge_propertyFunction
edge_property(g::PropertyGraphInterface, edge_idx::Integer) -> E

Get the property associated with edge at the given edge index. Uses undirected edge indexing (1:num_edges).

source
GraphCore.edge_propertyMethod
edge_property(g::GraphInterface, u::Integer, v::Integer) -> E

Get the property of the edge between u and v. Uses undirected edge indexing - for undirected graphs, this returns the same property regardless of direction.

source
GraphCore.edge_weightFunction
edge_weight(g::WeightedGraphInterface, directed_edge_idx::Integer) -> W
edge_weight(g::WeightedGraphInterface, edge::Pair{<:Integer,<:Integer}) -> W

Get the weight of the directed edge at the given directed edge index. Uses the directional indexing system for O(1) weight lookups. The second form allows querying by vertex pair, equivalent to edge_weight(g, find_edge_index(g, u, v)).

source
GraphCore.edge_weightsFunction
edge_weights(g::WeightedGraphInterface, v::Integer) -> view or iterator
edge_weights(g::WeightedGraphInterface) -> view or iterator

Return weights for edges from vertex v, or all edge weights.

Important: Weights are always directional, even for undirected graphs. This design allows asymmetric weights (e.g., different traversal costs in each direction).

Ordering: The i-th weight corresponds to the i-th neighbor in neighbor_indices(g, v).

Examples

# Process neighbors with weights
for (neighbor, weight) in zip(neighbor_indices(g, v), edge_weights(g, v))
    process_weighted_edge(v, neighbor, weight)
end

# More convenient combined iteration
for (neighbor, weight) in neighbor_weights(g, v)
    process_weighted_edge(v, neighbor, weight)
end
source
GraphCore.edgesMethod
edges(g::GraphInterface) -> Iterator

Return an iterator over all edges in the graph.

  • For directed graphs: yields (source, target) pairs for each directed edge
  • For undirected graphs: yields (u, v) pairs where u ≤ v (each edge once)

Examples

for (u, v) in edges(g)
    println("Edge from ", u, " to ", v)
end

# Collect all edges
edge_list = collect(edges(g))
source
GraphCore.find_directed_edge_indexFunction
find_directed_edge_index(g::GraphInterface, u::Integer, v::Integer) -> Int32

Find the directed edge index for the directed edge from vertices u to v of the graph g. Returns 0 if no such edge exists.

Always directional: find_directed_edge_index(g, u, v) ≠ find_directed_edge_index(g, v, u)

This index is used for directed edge weight access and other directional properties, and for indexing external arrays of size num_directed_edges(g).

source
GraphCore.find_edge_indexFunction
find_edge_index(g::GraphInterface, u::Integer, v::Integer) -> Int32

Find the undirected edge index for the edge between vertices u and v of the graph g. Returns 0 if no such edge exists.

For undirected graphs: find_edge_index(g, u, v) == find_edge_index(g, v, u) For directed graphs: only finds the edge in the specified direction (u -> v)

This index is used for edge property access (shared properties) and for indexing external arrays of size numedges(g). For directed graphs this is the same as `finddirectededgeindex(g, u, v)`

source
GraphCore.has_edgeFunction
has_edge(g::GraphInterface, u::Integer, v::Integer) -> Bool

Test whether there is a directed edge from vertex u to vertex v. For undirected graphs, has_edge(g, u, v) == has_edge(g, v, u).

source
GraphCore.has_vertexFunction
has_vertex(g::GraphInterface, v::Integer) -> Bool

Test whether vertex v exists in the graph. Vertices are always integers in range 1:num_vertices(g).

source
GraphCore.is_directed_graphFunction
is_directed_graph(g::GraphInterface) -> Bool

Return true if the graph is directed, false if undirected. This affects the interpretation of edges and neighbor relationships.

source
GraphCore.neighborFunction
neighbor(g::GraphInterface, v::Integer, i::Integer) -> Int32

Return the i-th neighbor of vertex v in the graph g.

Default implementation provided - concrete types may override for efficiency.

source
GraphCore.neighbor_indicesFunction
neighbor_indices(g::GraphInterface, v::Integer) -> view or iterator

Return an iterator over the neighbor indices of vertex v.

For directed graphs: Returns out-neighbors only For undirected graphs: Returns all neighbors

Performance guarantee: The returned iterator must support:

  • Fast iteration: for neighbor in neighbor_indices(g, v)
  • Length query: length(neighbor_indices(g, v))
  • Index access: neighbor_indices(g, v)[i] (implementation dependent)

Memory efficiency: Implementations should return views when possible to avoid allocation during neighbor traversal.

Examples

# Basic iteration
for neighbor in neighbor_indices(g, v)
    process_neighbor(neighbor)
end

# Combined with indexing for edge properties
for (i, neighbor) in enumerate(neighbor_indices(g, v))
    edge_idx = edge_index(g, v, i)        # O(1) edge index lookup
    process_edge(neighbor, edge_idx)
end
source
GraphCore.neighbor_weightsFunction
neighbor_weights(g::WeightedGraphInterface, v::Integer) -> iterator

Return an iterator over (neighbor_index, weight) pairs for vertex v. More efficient than separate iteration over neighbor_indices(g, v) and edge_weights(g, v).

Usage:

    for (neighbor, weight) in neighbor_weights(g, v)
        # process neighbor and weight together
    end

See also: neighbor_indices, edge_weights

source
GraphCore.num_directed_edgesFunction
num_directed_edges(g::GraphInterface) -> Int32

Return the total number of directed edges in the graph.

  • For undirected graphs: 2 * num_edges(g)
  • For directed graphs: actual count of directed edges

This count determines the size needed for directed edge property arrays.

source
GraphCore.num_edgesFunction
num_edges(g::GraphInterface) -> Int32

Return the number of edges in the graph. For undirected graphs, this counts each edge once. For directed graphs, this counts directed edges.

source
GraphCore.remove_edge!Function
remove_edge!(g::GraphInterface, u::Integer, v::Integer) -> Bool

Remove the edge from u to v. Returns true if successful, false if edge doesn't exist. Only available for mutable graph types.

source
GraphCore.remove_edge!Method
remove_edge!(g::AdjGraph, u::Integer, v::Integer) -> Bool

Remove the edge from u to v from the graph. Returns true if successful, false if edge doesn't exist.

Performance

  • Time Complexity: O(degree(u)) + O(degree(v)) for undirected
  • Space Complexity: O(1) - only removes data
  • Index Stability: ⚠️ MAY BREAK STABILITY - edge indices may be invalidated

Implementation Details

  • Directed graphs: Removes only u→v edge
  • Undirected graphs: Removes both u→v and v→u internal representations
  • Search cost: Linear search in neighbor vectors to find edge
  • Array operations: Uses deleteat! which may shift subsequent elements

Edge Index Invalidation

g = build_adj_graph([(1,2), (2,3), (1,3)]; directed=false)
# Edge indices: (1,2)→1, (2,3)→2, (1,3)→3

# External edge data
edge_weights = [1.0, 2.0, 1.5]  # Indexed by edge indices

remove_edge!(g, 2, 3)  # Remove edge with index 2
# Now: remaining edges (1,2)→1, (1,3)→?
# ⚠️ Edge index for (1,3) may have changed!
# edge_weights[2] might now refer to wrong edge

Safe Usage Patterns

# ✅ SAFE: Use PropertyGraph for automatic edge property management
pg = PropertyGraph(g, vertex_props, edge_props)
remove_edge!(pg, u, v)  # Edge properties automatically maintained

# ✅ SAFE: Use edge-based operations instead of index-based
for (u, v) in edges(g)
    weight = compute_weight_from_vertices(u, v)  # No index dependency
end

# ❌ UNSAFE: Assume edge indices remain stable across removals
edge_data = Vector{Float64}(undef, num_edges(g))
remove_edge!(g, u, v)
# edge_data indices now potentially inconsistent!

Performance Considerations

For graphs with frequent edge removals, consider:

  1. Batch operations: Remove many edges at once, then rebuild external arrays
  2. Alternative storage: Use Dict{Tuple{Int,Int}, T} for edge properties
  3. Conversion workflow: AdjGraph for building → CoreGraph for analysis
source
GraphCore.remove_edge!Method
remove_edge!(g::PropertyGraph, u::Integer, v::Integer) -> Bool

Remove the edge from u to v from the property graph. Returns true if successful, false if edge doesn't exist.

Only available when the base graph type supports remove_edge!. Property arrays are automatically maintained.

⚠️ Index Invalidation Warning: Removing edges may invalidate edge indices and external arrays indexed by edge numbers.

source
GraphCore.remove_edge!Method
remove_edge!(g::WeightedAdjGraph, u::Integer, v::Integer) -> Bool

Remove the weighted edge from u to v from the graph. Returns true if successful, false if edge doesn't exist.

Performance

  • Time Complexity: O(degree(u)) + O(degree(v)) for undirected
  • Space Complexity: O(1) - only removes data
  • Index Stability: ⚠️ MAY BREAK STABILITY - edge indices may be invalidated

Implementation Details

  • Directed graphs: Removes only u→v edge
  • Undirected graphs: Removes both u→v and v→u internal representations
  • Search cost: Linear search in neighbor vectors to find edge
  • Array operations: Uses deleteat! which may shift subsequent elements

Edge Index Invalidation

g = build_weighted_adj_graph([(1,2), (2,3), (1,3)]; directed=false)
# Edge indices: (1,2)→1, (2,3)→2, (1,3)→3

# External edge data
edge_weights = [1.0, 2.0, 1.5]  # Indexed by edge indices

remove_edge!(g, 2, 3)  # Remove edge with index 2
# Now: remaining edges (1,2)→1, (1,3)→?
# ⚠️ Edge index for (1,3) may have changed!
# edge_weights[2] might now refer to wrong edge

Safe Usage Patterns

# ✅ SAFE: Use PropertyGraph for automatic edge property management
pg = PropertyGraph(g, vertex_props, edge_props)
remove_edge!(pg, u, v)  # Edge properties automatically maintained

# ✅ SAFE: Use edge-based operations instead of index-based
for (u, v) in edges(g)
    weight = compute_weight_from_vertices(u, v)  # No index dependency
end

# ❌ UNSAFE: Assume edge indices remain stable across removals
edge_data = Vector{Float64}(undef, num_edges(g))
remove_edge!(g, u, v)
# edge_data indices now potentially inconsistent!

Performance Considerations

For graphs with frequent edge removals, consider:

  1. Batch operations: Remove many edges at once, then rebuild external arrays
  2. Alternative storage: Use Dict{Tuple{Int,Int}, T} for edge properties
  3. Conversion workflow: AdjGraph for building → CoreGraph for analysis
source
GraphCore.remove_edge!Method
remove_edge!(g::CoreGraph, u::Integer, v::Integer) -> Bool

Remove the edge from u to v from the graph. Returns true if successful, false if edge doesn't exist.

Efficient Implementation: O(degree) operation that removes entries from CSR arrays and updates offsets.

For frequent mutations, consider using AdjGraph instead.

Example

g = build_core_graph([(1,2), (2,3), (1,3)]; directed=false)
success = remove_edge!(g, 1, 2)  # Returns true
@assert !has_edge(g, 1, 2) && !has_edge(g, 2, 1)  # Both directions removed for undirected
source
GraphCore.remove_edge!Method
remove_edge!(g::WeightedGraph, u::Integer, v::Integer) -> Bool

Remove the edge from u to v from the weighted graph. Returns true if successful, false if edge doesn't exist.

Efficient Implementation: O(degree) operation that removes entries from CSR arrays and updates offsets.

source
GraphCore.remove_vertex!Function
remove_vertex!(g::GraphInterface, v::Integer) -> Bool

Remove vertex v and all its incident edges. Returns true if successful, false if vertex doesn't exist. Only available for mutable graph types.

source
GraphCore.remove_vertex!Method
remove_vertex!(g::AdjGraph, v::Integer) -> Bool

Remove vertex v and all its incident edges from the graph. Returns true if successful, false if vertex doesn't exist.

Performance

  • Time Complexity: O(V + incident_edges) - must update all vertex references
  • Space Complexity: O(1) - only removes data
  • Index Stability: ⚠️ BREAKS STABILITY - vertex indices > v are decremented

Implementation Details

  1. Edge Removal: All incident edges are removed first (affects edge count)
  2. Vertex Deletion: Vertex v is removed from adjacency structures
  3. Index Update: All references to vertices > v are decremented by 1
  4. Property Cleanup: For PropertyGraph, properties are also removed

Index Invalidation Warning

g = build_adj_graph([(1,2), (2,3), (3,4)]; directed=false)
# Before: vertices [1,2,3,4], vertex 3 has neighbors [2,4]

success = remove_vertex!(g, 2)  # Remove vertex 2
# After: vertices [1,2,3], old vertex 3→new vertex 2, old vertex 4→new vertex 3
# ⚠️ External arrays indexed by old vertex numbers are now INVALID!

# External vertex properties become inconsistent:
vertex_labels = ["A", "B", "C", "D"]  # Indexed by old vertex numbers
# After removal: vertex_labels[3] no longer corresponds to current vertex 3!

Safe Usage Patterns

# ✅ SAFE: Use PropertyGraph for automatic property management
pg = PropertyGraph(g, vertex_labels, edge_labels)
remove_vertex!(pg, 2)  # Properties automatically updated

# ✅ SAFE: Rebuild external arrays after removal
external_data = rebuild_after_removal(external_data, removed_vertex)

# ❌ UNSAFE: Assume external arrays remain valid after removal
remove_vertex!(g, v)
old_label = vertex_labels[some_vertex]  # May be wrong!
source
GraphCore.remove_vertex!Method
remove_vertex!(g::PropertyGraph, v::Integer) -> Bool

Remove vertex v and all its incident edges from the property graph. Returns true if successful, false if vertex doesn't exist.

Only available when the base graph type supports remove_vertex!. Property arrays are automatically maintained and indices updated.

⚠️ Index Invalidation Warning: Removing vertices renumbers remaining vertices and invalidates external arrays indexed by vertex numbers.

source
GraphCore.remove_vertex!Method
remove_vertex!(g::WeightedAdjGraph, v::Integer) -> Bool

Remove vertex v and all its incident edges from the weighted graph. Returns true if successful, false if vertex doesn't exist.

Performance

  • Time Complexity: O(V + incident_edges) - must update all vertex references
  • Space Complexity: O(1) - only removes data
  • Index Stability: ⚠️ BREAKS STABILITY - vertex indices > v are decremented

Implementation Details

  1. Edge Removal: All incident edges are removed first (affects edge count)
  2. Vertex Deletion: Vertex v is removed from adjacency structures
  3. Index Update: All references to vertices > v are decremented by 1
  4. Property Cleanup: For PropertyGraph, properties are also removed

Index Invalidation Warning

g = build_weighted_adj_graph([(1,2), (2,3), (3,4)]; directed=false)
# Before: vertices [1,2,3,4], vertex 3 has neighbors [2,4]

success = remove_vertex!(g, 2)  # Remove vertex 2
# After: vertices [1,2,3], old vertex 3→new vertex 2, old vertex 4→new vertex 3
# ⚠️ External arrays indexed by old vertex numbers are now INVALID!

# External vertex properties become inconsistent:
vertex_labels = ["A", "B", "C", "D"]  # Indexed by old vertex numbers
# After removal: vertex_labels[3] no longer corresponds to current vertex 3!

Safe Usage Patterns

# ✅ SAFE: Use PropertyGraph for automatic property management
pg = PropertyGraph(g, vertex_labels, edge_labels)
remove_vertex!(pg, 2)  # Properties automatically updated

# ✅ SAFE: Rebuild external arrays after removal
external_data = rebuild_after_removal(external_data, removed_vertex)

# ❌ UNSAFE: Assume external arrays remain valid after removal
remove_vertex!(g, v)
old_label = vertex_labels[some_vertex]  # May be wrong!
source
GraphCore.remove_vertex!Method
remove_vertex!(g::CoreGraph, v::Integer) -> Bool

Remove vertex v and all its incident edges from the graph. Returns true if successful, false if vertex doesn't exist.

⚠️ Performance Note: O(V + E) operation due to vertex renumbering requirement. ⚠️ Index Invalidation: Removes vertex v and renumbers vertices v+1, v+2, ... to v, v+1, ... This invalidates any external arrays indexed by vertex numbers.

Implementation: More efficient than full reconstruction but still requires renumbering.

Example

g = build_core_graph([(1,2), (2,3), (1,3)]; directed=false)
success = remove_vertex!(g, 2)  # Returns true
@assert num_vertices(g) == 2
@assert has_edge(g, 1, 2)  # What was vertex 3 is now vertex 2
source
GraphCore.remove_vertex!Method
remove_vertex!(g::WeightedGraph, v::Integer) -> Bool

Remove vertex v and all its incident edges from the weighted graph. Returns true if successful, false if vertex doesn't exist.

⚠️ Performance Note: O(V + E) operation due to vertex renumbering requirement. ⚠️ Index Invalidation: Removes vertex v and renumbers vertices v+1, v+2, ... to v, v+1, ... This invalidates any external arrays indexed by vertex numbers.

Implementation: More efficient than full reconstruction but still requires renumbering.

Example

g = build_weighted_graph([(1,2,1.0), (2,3,2.0), (1,3,3.0)]; directed=false)
success = remove_vertex!(g, 2)  # Returns true
@assert num_vertices(g) == 2
@assert has_edge(g, 1, 2)  # What was vertex 3 is now vertex 2
source
GraphCore.set_edge_property!Function
set_edge_property!(g::PropertyGraphInterface{V,E,W}, edge_idx::Integer, prop::E) -> prop

Set the property of edge at edge_idx to prop. Only available for mutable graph types.

source
GraphCore.set_vertex_property!Function
set_vertex_property!(g::PropertyGraphInterface{V,E,W}, v::Integer, prop::V) -> prop

Set the property of vertex v to prop. Only available for mutable graph types.

source
GraphCore.symmetrize_edgesMethod
symmetrize_edges(edges) -> Vector{Tuple{Int,Int}}

Convert canonical format to symmetric format (both directions).

Arguments

  • edges: Vector of (u,v) tuples in canonical format

Returns

  • Vector of edges with both directions included

Format Conversion

  • Input: [(1,2), (2,3)] (canonical)
  • Output: [(1,2), (2,1), (2,3), (3,2)] (both directions)

Use when you need to create a directed graph from undirected edges, or when working with algorithms that expect symmetric adjacency representations.

Example

canonical = [(1,2), (2,3), (1,3)]
symmetric = GraphCore.symmetrize_edges(canonical)
# Result: [(1,2), (2,1), (2,3), (3,2), (1,3), (3,1)]

Note

Self-loops (u,u) are not duplicated to avoid redundancy.

source
GraphCore.symmetrize_edgesMethod
symmetrize_edges(edges, weights::AbstractVector{W}) -> (symmetric_edges, symmetric_weights)

Convert canonical format to symmetric, duplicating weights for both directions.

Arguments

  • edges: Vector of (u,v) tuples in canonical format
  • weights: Vector of weights corresponding to edges

Returns

  • Tuple of (symmetricedges, symmetricweights)

Behavior

Each weight is duplicated for both directions of the edge. This creates a symmetric weight matrix suitable for undirected graph algorithms.

Example

edges = [(1,2), (2,3)]
weights = [1.5, 2.0]
symmetric_edges, symmetric_weights = GraphCore.symmetrize_edges(edges, weights)
# Result:
# edges = [(1,2), (2,1), (2,3), (3,2)]
# weights = [1.5, 1.5, 2.0, 2.0]
source
GraphCore.to_adj_graphMethod
to_adj_graph(g::GraphInterface) -> AdjGraph

Convert any GraphInterface graph to an AdjGraph. Preserves the directedness of the original graph.

source
GraphCore.to_core_graphMethod
to_core_graph(g::GraphInterface) -> CoreGraph

Convert any GraphInterface implementation to a CoreGraph. Preserves the directedness of the original graph.

source
GraphCore.to_weighted_graphMethod
to_weighted_graph(g::WeightedGraphInterface{W}) -> WeightedGraph{W}

Convert any WeightedGraphInterface to a WeightedGraph. Preserves the directedness and all weights of the original graph.

source
GraphCore.vertex_propertiesFunction
vertex_properties(g::PropertyGraphInterface) -> iterator

Return an iterator over all vertex properties in order.

Example

g = build_property_graph(edges, ["A", "B", "C"], edge_props, 3)
for (i, prop) in enumerate(vertex_properties(g))
    println("Vertex ", i, " has property: ", prop)
end
source

Graph Construction

GraphCore.Builders.build_from_functionMethod
build_from_function(vertex_fn::Function, edge_fn::Function, nv::Int; directed=true)

Build a graph by calling vertexfn(i) for each vertex and edgefn(u,v) for potential edges.

source
GraphCore.add_edge!Method
add_edge!(builder::GraphBuilder{Nothing,Nothing,Nothing}, u::Integer, v::Integer) -> Int32

Convenience method for basic (unweighted, no properties) graph builders.

source
GraphCore.add_edge!Method
add_edge!(builder::GraphBuilder, u::Integer, v::Integer;
          edge_property=nothing, weight=nothing) -> Int32

Add an edge with optional properties and weights using keyword arguments. Returns the edge index (1-based).

Examples

# Basic edge
add_edge!(builder, 1, 2)

# Weighted edge
add_edge!(builder, 1, 2; weight=1.5)

# Edge with property
add_edge!(builder, 1, 2; edge_property="connection")

# Both weight and property
add_edge!(builder, 1, 2; edge_property="highway", weight=2.5)
source
GraphCore.add_vertex!Method
add_vertex!(builder::GraphBuilder [, prop]) -> Int32

Add a vertex with optional property. Returns the vertex index. For non-property builders, prop should be omitted.

source
GraphCore.build_graphMethod
build_graph(builder::GraphBuilder{V,E,W}) -> GraphInterface

Convert the builder to an optimized graph representation. Automatically chooses the most appropriate graph type among: CoreGraph, WeightedGraph{W}, PropertyGraph{G,V,E}.

source
GraphCore.build_graphMethod
build_graph(builder::GraphBuilder, ::Type{G}) -> G

Convert builder to a specific graph type G, where G can be one of: CoreGraph, WeightedGraph{W}, PropertyGraph, AdjGraph, WeightedAdjGraph{W}, PropertyAdjGraph. Note that the builder must be compatible with the target graph type. Also note that the order of the arguments, builder, graph type, is opposite to the usual order.

source

Conversions

GraphCore.Conversions.from_adjacency_matrixMethod
from_adjacency_matrix(::Type{G}, adj_matrix::AbstractMatrix{W}) where {G<:GraphInterface,W} -> G

Construct a graph of appropriate type from an adjacency matrix.

  • Non-zero entries in adj_matrix become edges with those weights
  • If directed is not specified, it is inferred from the symmetry of adj_matrix

For undirected graphs, adj_matrix should be symmetric.

source
GraphCore.Conversions.from_weighted_graphs_jlMethod
from_weighted_graphs_jl(g::Graphs.AbstractGraph, weights::AbstractVector{W};
                       directed::Bool = Graphs.is_directed(g)) -> WeightedGraph{W}

Convert a weighted graph from the Graphs.jl ecosystem to a WeightedGraph.

source
GraphCore.Conversions.to_adjacency_matrixMethod
to_adjacency_matrix(g::GraphInterface) -> SparseMatrixCSC{W} where {W}

Convert a graph to its adjacency matrix representation.

  • For directed graphs, the matrix is not required to be symmetric.
  • For undirected graphs, the matrix will be symmetric if the weights are.
  • For unweighted graphs, entries are 1 where edges exist.
  • For weighted graphs, entries are the edge weights (which are not necessarily symmetric even for undirected graphs).
source
GraphCore.Conversions.to_graphs_jlMethod
to_graphs_jl(g::GraphInterface) -> Graphs.SimpleGraph or Graphs.SimpleDiGraph

Convert a property graph to a Graphs.jl graph (losing properties and weights). Returns SimpleGraph for undirected graphs, SimpleDiGraph for directed graphs.

source
GraphCore.Conversions.to_weighted_graphs_jlMethod
to_weighted_graphs_jl(g::GraphInterface{V,E,W}) where {V,E,W} ->
    SimpleWeightedGraphs.SimpleWeightedGraph or SimpleWeightedGraphs.SimpleWeightedDiGraph

Convert a WeightedGraphInterface graph to a weighted SimpleWeightedGraphs.jl graph (preserving weights, losing other properties). Requires SimpleWeightedGraphs.jl package.

source

Lattices

GraphCore.Lattices.HypercubicLatticeType
HypercubicLattice{D,T} <: GraphInterface

A D-dimensional hypercubic lattice graph with side length of type T.

Type Parameters

  • D::Int: Dimension of the lattice (1D=line, 2D=grid, 3D=cube, etc.)
  • T<:Integer: Type for lattice size/coordinates

Storage

Uses mathematical coordinate mapping instead of explicit edge storage. Memory usage: O(1) regardless of lattice size!

Coordinate System

  • Vertices are numbered 1 to prod(sizes)
  • Coordinates are 0-indexed: (0,0,...,0) to (size₁-1, size₂-1, ..., sizeD-1)
  • Periodic boundary conditions optional

Examples

# 2D grid: 10×10
lattice_2d = HypercubicLattice{2,Int}((10, 10))

# 3D cube: 5×5×5
lattice_3d = HypercubicLattice{3,Int}((5, 5, 5))

# 1D chain: 100 vertices
lattice_1d = HypercubicLattice{1,Int}((100,))
source
GraphCore.Lattices.coord_to_vertexMethod
coord_to_vertex(g::HypercubicLattice{D,T}, coord::NTuple{D,T}) -> Int32

Convert coordinates to vertex index using optimized arithmetic. Specialized for common dimensions with loop unrolling.

source
GraphCore.Lattices.lattice_distanceMethod
lattice_distance(g::HypercubicLattice, u::Integer, v::Integer) -> Float64

Compute the Manhattan distance between two vertices on the lattice. Accounts for periodic boundary conditions.

source
GraphCore.Lattices.vertex_to_coordMethod
vertex_to_coord(g::HypercubicLattice{D,T}, v::Integer) -> NTuple{D,T}

Convert vertex index to coordinates using optimized integer arithmetic. Fully inlined and branch-free for maximum performance.

source
GraphCore.PowerOfTwoLattices.PowerOfTwoLatticeType
PowerOfTwoLattice{D} <: GraphInterface

Ultra-fast D-dimensional hypercubic lattice where all sizes are powers of 2. Uses bit operations for coordinate conversion and neighbor lookup.

Restrictions

  • D ≤ 5 (keeps neighbor tuples reasonable)
  • All sizes must be powers of 2: 2, 4, 8, 16, 32, 64, 128, ...
  • Periodic boundary conditions (makes bit operations clean)

Type Parameters

  • D::Int: Dimension (1 ≤ D ≤ 5)

Examples

# 2D: 16×32 grid (2^4 × 2^5)
g2d = P2Grid2D(4, 5)  # log₂ sizes

# 3D: 8×8×16 cube (2^3 × 2^3 × 2^4)
g3d = P2Grid3D(3, 3, 4)

# 1D: 64-element chain (2^6)
g1d = P2Chain1D(6)
source