add_vertex Module Subroutine

module subroutine add_vertex(this, vertex, feature, id, update_adjacency)

Add a vertex to the graph.

Arguments

Type IntentOptional Attributes Name
class(graph_type), intent(inout) :: this

Parent. Instance of the graph structure.

type(vertex_type), intent(in), optional :: vertex

Vertex to be added.

real(kind=real32), intent(in), optional, dimension(:) :: feature

Feature vector of the vertex.

integer, intent(in), optional :: id

Identifier of the vertex.

logical, intent(in), optional :: update_adjacency

Boolean whether to update the adjacency matrix. Default is True.


Source Code

  module subroutine add_vertex(this, vertex, feature, id, update_adjacency)
    !! Add a vertex to the graph.
    implicit none

    ! Arguments
    class(graph_type), intent(inout) :: this
    !! Parent. Instance of the graph structure.
    type(vertex_type), intent(in), optional :: vertex
    !! Vertex to be added.
    real(real32), dimension(:), intent(in), optional :: feature
    !! Feature vector of the vertex.
    integer, intent(in), optional :: id
    !! Identifier of the vertex.
    logical, intent(in), optional :: update_adjacency
    !! Boolean whether to update the adjacency matrix. Default is True.

    ! Local variables
    type(vertex_type) :: vertex_
    !! Initialised vertex.
    real(real32), dimension(:,:), allocatable :: vertex_features
    !! Feature vectors of the vertices.
    logical :: update_adjacency_
    !! Boolean whether to update the adjacency matrix.


    ! Validate input arguments
    if(present(vertex) .and. present(feature))then
       call stop_program('Specify either vertex or feature, not both')
    elseif(.not. present(vertex) .and. .not. present(feature))then
       call stop_program('Must specify either vertex or feature')
    end if
    
    if(present(vertex)) vertex_ = vertex
    if(present(feature)) vertex_%feature = feature

    ! Handle feature allocation and validation
    if(.not. allocated(vertex_%feature))then
       allocate(vertex_%feature(this%num_vertex_features), source=0.0_real32)
    elseif(this%num_vertex_features .eq. 0)then
       this%num_vertex_features = size(vertex_%feature)
    elseif(size(vertex_%feature) .ne. this%num_vertex_features)then
       call stop_program('Vertex feature size does not match graph')
    end if

    if(present(id)) vertex_%id = id


    this%num_vertices = this%num_vertices + 1
    
    ! Add vertex to appropriate storage
    if(this%is_sparse)then
       allocate(vertex_features(this%num_vertex_features, this%num_vertices))
       vertex_features(:, 1:this%num_vertices-1) = this%vertex_features
       vertex_features(:, this%num_vertices) = vertex_%feature
       if(allocated(this%vertex_features)) deallocate(this%vertex_features)
       call move_alloc(vertex_features, this%vertex_features)
    else
       if(.not. allocated(this%vertex)) allocate(this%vertex(0))
       this%vertex = [this%vertex, vertex_]
    end if
    
    ! Update adjacency matrix if requested
    update_adjacency_ = .true.
    if(present(update_adjacency)) update_adjacency_ = update_adjacency
    if(update_adjacency_) call this%generate_adjacency()
  end subroutine add_vertex