Edges¶
Edges (or links) connect vertices in a graph, representing relationships or connections between entities.
Edge Type¶
Each edge has the following properties:
type(edge_type) :: e
e%id ! Unique identifier (integer)
e%index(2) ! [source, target] vertex indices
e%weight ! Edge weight (real32, default: 1.0)
e%feature(:) ! Feature vector (real32, allocatable)
Adding Edges¶
Basic Edges¶
Connect two vertices:
! Simple undirected edge between vertices 1 and 2
call graph%add_edge(index=[1, 2])
Directed Edges¶
For directed graphs, use negative indices or the directed parameter:
graph%directed = .true.
! Method 1: Negative target index (from 1 to 2)
call graph%add_edge(index=[1, -2]) ! 1 → 2
! Method 2: Use directed parameter
call graph%add_edge(index=[1, 2], directed=.true.)
The negative index convention allows you to mix directed and undirected edges in the same graph.
Weighted Edges¶
Add edges with custom weights:
! Edge with weight 2.5
call graph%add_edge(index=[1, 2], weight=2.5)
! Default weight is 1.0
call graph%add_edge(index=[2, 3]) ! weight = 1.0
Edge Features¶
Edges can have feature vectors:
! Add edge with features
call graph%add_edge(index=[1, 2], weight=1.5, feature=[0.1, 0.2])
Important: Like vertices, the first edge sets the feature dimension for all subsequent edges.
Batch Operations¶
Connect one vertex to multiple vertices efficiently:
! Connect vertex 1 to vertices 2, 3, 4 (undirected)
call graph%set_edges(1, [2, 3, 4])
! Same but directed (1 → 2, 1 → 3, 1 → 4)
call graph%set_edges(1, [-2, -3, -4])
Accessing Edges¶
By Index¶
Access edge properties:
! Get edge endpoints
write(*,*) 'Source:', graph%edge(3)%index(1)
write(*,*) 'Target:', graph%edge(3)%index(2)
! Get weight and features
write(*,*) 'Weight:', graph%edge(3)%weight
write(*,*) 'Features:', graph%edge(3)%feature
Iterating All Edges¶
Loop through all edges:
do i = 1, graph%num_edges
write(*,'(A,I0,A,I0,A,I0,A,F6.2)') &
'Edge ', i, ': ', graph%edge(i)%index(1), &
' -> ', graph%edge(i)%index(2), &
' weight: ', graph%edge(i)%weight
end do
Modifying Edges¶
Updating Properties¶
Modify edge weights and features:
! Update weight
graph%edge(3)%weight = 5.0
! Update features
graph%edge(3)%feature = [0.5, 0.6]
! Update individual feature components
graph%edge(3)%feature(1) = 0.8
Removing Edges¶
Remove one or more edges:
! Remove single edge
call graph%remove_edges([3])
! Remove multiple edges
call graph%remove_edges([1, 4, 7])
Effects:
Updates vertex degrees
Updates adjacency matrix
Remaining edges are renumbered
Batch Removal¶
For efficiency when removing many edges, defer adjacency updates:
! Remove many edges without updating adjacency each time
do i = 1, n_to_remove
call graph%remove_edges([edge_list(i)], update_adjacency=.false.)
end do
! Update adjacency once at the end
call graph%generate_adjacency()
Self-Loops¶
A self-loop is an edge that connects a vertex to itself.
Adding Self-Loops¶
! Add to all vertices
call graph%add_self_loops()
! Add to specific vertices
call graph%add_self_loops(indices=[1, 3, 5])
! With custom weight
call graph%add_self_loops(indices=[1, 3, 5], weight=2.0)
Removing Self-Loops¶
! Remove from all vertices
call graph%remove_self_loops()
! Remove from specific vertices
call graph%remove_self_loops(indices=[2, 4])
Edge Features¶
Edge features can represent:
Relationship strength or type
Distance or cost
Capacity or flow
Temporal information
Any numerical property of the connection
The feature size is determined by the first edge added and applies to all edges in the graph.