Skip to content

Commit

Permalink
Merge c24f37b into 8ce5bde
Browse files Browse the repository at this point in the history
  • Loading branch information
mdeff committed May 9, 2019
2 parents 8ce5bde + c24f37b commit 862ceda
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
11 changes: 11 additions & 0 deletions pygsp/graphs/__init__.py
Expand Up @@ -137,6 +137,16 @@
.. _NetworkX's documentation: https://networkx.github.io/documentation/stable/reference/generators.html
Graphs built from other graphs
------------------------------
.. autosummary::
LineGraph
Generated graphs
----------------
.. autosummary::
Airfoil
Expand Down Expand Up @@ -186,6 +196,7 @@
'ErdosRenyi',
'FullConnected',
'Grid2d',
'LineGraph',
'Logo',
'LowStretchTree',
'Minnesota',
Expand Down
47 changes: 47 additions & 0 deletions pygsp/graphs/linegraph.py
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-

import numpy as np
from scipy import sparse

from . import Graph # prevent circular import in Python < 3.5


class LineGraph(Graph):
r"""Build the line graph of a graph.
Each vertex of the line graph represents an edge in the original graph. Two
vertices are connected if the edges they represent share a vertex in the
original graph.
Parameters
----------
graph : :class:`Graph`
Examples
--------
>>> import matplotlib.pyplot as plt
>>> graph = graphs.Sensor(5, k=2, seed=10)
>>> line_graph = graphs.LineGraph(graph)
>>> fig, ax = plt.subplots()
>>> fig, ax = graph.plot('blue', edge_color='blue', indices=True, ax=ax)
>>> fig, ax = line_graph.plot('red', edge_color='red', indices=True, ax=ax)
>>> _ = ax.set_title('graph and its line graph')
"""

def __init__(self, graph, **kwargs):

graph.compute_differential_operator()
# incidence = np.abs(graph.D) # weighted?
incidence = (graph.D != 0)

adjacency = incidence.T.dot(incidence).astype(np.int)
adjacency -= sparse.identity(graph.n_edges, dtype=np.int)

try:
coords = incidence.T.dot(graph.coords) / 2
except AttributeError:
coords = None

super(LineGraph, self).__init__(adjacency, coords=coords,
plotting=graph.plotting, **kwargs)
32 changes: 32 additions & 0 deletions pygsp/tests/test_graphs.py
Expand Up @@ -448,6 +448,38 @@ def test_set_coordinates(self):
G.set_coordinates('community2D')
self.assertRaises(ValueError, G.set_coordinates, 'invalid')

def test_line_graph(self):
adjacency = [
[0, 1, 1, 3],
[1, 0, 1, 0],
[1, 1, 0, 1],
[3, 0, 1, 0],
]
coords = [
[0, 0],
[4, 0],
[4, 2],
[0, 2],
]
graph = graphs.Graph(adjacency, coords=coords)
graph = graphs.LineGraph(graph)
adjacency = [
[0, 1, 1, 1, 0],
[1, 0, 1, 1, 1],
[1, 1, 0, 0, 1],
[1, 1, 0, 0, 1],
[0, 1, 1, 1, 0],
]
coords = [
[2, 0],
[2, 1],
[0, 1],
[4, 1],
[2, 2],
]
np.testing.assert_equal(graph.W.toarray(), adjacency)
np.testing.assert_equal(graph.coords, coords)

def test_subgraph(self, n_vertices=100):
self._G.set_signal(self._G.coords, 'coords')
graph = self._G.subgraph(range(n_vertices))
Expand Down
2 changes: 2 additions & 0 deletions pygsp/tests/test_plotting.py
Expand Up @@ -54,6 +54,8 @@ def test_plot_graphs(self):
Gs.append(Graph(Xin))
elif classname in ['ImgPatches', 'Grid2dImgPatches']:
Gs.append(Graph(img=self._img, patch_shape=(3, 3)))
elif classname == 'LineGraph':
Gs.append(Graph(graphs.Sensor(20, seed=42)))
else:
Gs.append(Graph())

Expand Down

0 comments on commit 862ceda

Please sign in to comment.