# Source code for higra.attribute.graph_attributes

############################################################################
# Copyright ESIEE Paris (2018)                                             #
#                                                                          #
# Contributor(s) : Benjamin Perret                                         #
#                                                                          #
#                                                                          #
# The full license is in the file LICENSE, distributed with this software. #
############################################################################

import numpy as np
import higra as hg

[docs]@hg.auto_cache
def attribute_vertex_area(graph):
"""
Vertex area of the given graph.

In general the area of a vertex if simply equal to 1. But, if the graph is a region adjacency graph then the area of
a region is equal to the sum of the area of the vertices inside the region (obtained with a recursive call to
attribute_vertex_area on the original graph).

:param graph: input graph
:return: a 1d array
"""
if hg.CptRegionAdjacencyGraph.validate(graph):  # this is a rag like graph
pre_graph_vertex_area = attribute_vertex_area(pre_graph)
return hg.rag_accumulate_on_vertices(graph, hg.Accumulators.sum, vertex_weights=pre_graph_vertex_area)
res = np.ones((graph.num_vertices(),), dtype=np.float64)
res = hg.delinearize_vertex_weights(res, graph)
return res

[docs]@hg.auto_cache
def attribute_edge_length(graph):
"""
Edge length of the given graph.

In general the length of an edge if simply equal to 1. But, if the graph is a region adjacency graph then the
length of an edge is equal to the sum of length of the corresponding edges in the original graph (obtained with a
recursive call to attribute_edge_length on the original graph).

:param graph: input graph
:return: a nd array
"""
if hg.CptRegionAdjacencyGraph.validate(graph):  # this is a rag like graph
pre_graph_edge_length = attribute_edge_length(pre_graph)
return hg.rag_accumulate_on_edges(graph, hg.Accumulators.sum, edge_weights=pre_graph_edge_length)
res = np.ones((graph.num_edges(),), dtype=np.float64)
return res

[docs]@hg.auto_cache
def attribute_vertex_perimeter(graph, edge_length=None):
"""
Vertex perimeter of the given graph.
The perimeter of a vertex is defined as the sum of the length of out-edges of the vertex.

If the input graph has an attribute value no_border_vertex_out_degree, then each vertex perimeter is assumed to be
equal to this attribute value. This is a convenient method to handle image type graphs where an outer border has to be
considered.

:param graph: input graph
:param edge_length: length of the edges of the input graph (provided by :func:~higra.attribute_edge_length on graph)
:return: a nd array
"""
if edge_length is None:
edge_length = hg.attribute_edge_length(graph)

special_case_border_graph = hg.get_attribute(graph, "no_border_vertex_out_degree")

if special_case_border_graph is not None:
res = np.full((graph.num_vertices(),), special_case_border_graph, dtype=np.float64)
res = hg.delinearize_vertex_weights(res, graph)
return res

res = hg.accumulate_graph_edges(graph, edge_length, hg.Accumulators.sum)
res = hg.delinearize_vertex_weights(res, graph)
return res

[docs]@hg.argument_helper(hg.CptGridGraph)
@hg.auto_cache
def attribute_vertex_coordinates(graph, shape):
"""
Coordinates of the vertices of the given grid graph.

Example
=======

>>> c = hg.attribute_vertex_coordinates(g)
(((0, 0), (0, 1), (0, 2)),
((1, 0), (1, 1), (1, 2)))

:param graph: Input graph (Concept :class:~higra.CptGridGraph)
:param shape: (deduced from :class:~higra.CptGridGraph)
:return: a nd array
"""
coords = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]))
coords = [c.reshape((-1,)) for c in coords]
attribute = np.stack(list(reversed(coords)), axis=1)
attribute = hg.delinearize_vertex_weights(attribute, graph)
return attribute