Skip to content

Commit

Permalink
Merge pull request #50 from microsoft/din-dout-fix
Browse files Browse the repository at this point in the history
Use degree in and degree out instead of just degree out for Laplacian…
  • Loading branch information
nicaurvi committed Aug 4, 2020
2 parents a008194 + a845a50 commit bd8e514
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 9 deletions.
2 changes: 2 additions & 0 deletions docs/release_notes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Release Notes
## 0.1.4
- Fixed a bug during Laplacian matrix construction for directed graphs
## 0.1.3
- Added `modularity` and `modularity_components` functions, and deprecated `q_score`.
## 0.1.2
Expand Down
23 changes: 23 additions & 0 deletions tests/embedding/test_laplacian_spectral_embedding.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
class TestLaplacianSpectralEmbedding(unittest.TestCase):
def test_laplacian_embedding(self):
graph = nx.Graph([('a', 'b', {'weight': 1.0}), ('b', 'c', {'weight': 2.0})])

result = laplacian_embedding(
graph,
elbow_cut=1,
svd_seed=1234
)

self.assertIsNotNone(result)
(matrix, labels) = result
self.assertIsInstance(matrix, np.ndarray)
Expand All @@ -32,6 +34,27 @@ def test_laplacian_embedding(self):
np.testing.assert_allclose(expected_matrix, matrix, rtol=1e-5)
self.assertListEqual(expected_label, labels)

def test_laplacian_embedding_digraph(self):
graph = nx.DiGraph([('a', 'b', {'weight': 1.0}), ('b', 'c', {'weight': 2.0})])

result = laplacian_embedding(
graph,
elbow_cut=1,
svd_seed=1234
)

self.assertIsNotNone(result)
(matrix, labels) = result
self.assertIsInstance(matrix, np.ndarray)
self.assertIsInstance(labels, list)
self.assertEqual(2, matrix.ndim)
expected_matrix = np.array([[0.527046, 0.235702],
[0.781736, 0.62361 ],
[0.333333, 0.745356]])
expected_label = ['a', 'b', 'c']
np.testing.assert_allclose(expected_matrix, matrix, rtol=1e-5)
self.assertListEqual(expected_label, labels)

@unittest.skipIf(
sys.platform.startswith('darwin') and os.getenv("SKIP_TEST_35", "false") == "true",
"Test not supported on MacOS Github Actions, see: https://github.com/microsoft/topologic/issues/35"
Expand Down
14 changes: 10 additions & 4 deletions topologic/embedding/laplacian_spectral_embedding.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,16 @@ def laplacian_embedding(
minimum_matrix_dimension = min(graph_matrix.shape)

# make Laplacian matrix (DAD)
degree = graph_matrix.sum(axis=1).T.astype(float)
degree_array = np.squeeze(np.asarray(degree))
diagonal = sp.sparse.diags(degree_array ** (-0.5))
lse_matrix = diagonal.dot(graph_matrix).dot(diagonal)
in_degree = graph_matrix.sum(axis=0).astype(float)
out_degree = graph_matrix.sum(axis=1).T.astype(float)

in_degree_array = np.squeeze(np.asarray(in_degree))
out_degree_array = np.squeeze(np.asarray(out_degree))

in_diagonal = sp.sparse.diags(in_degree_array ** (-0.5))
out_diagonal = sp.sparse.diags(out_degree_array ** (-0.5))

lse_matrix = out_diagonal.dot(graph_matrix).dot(in_diagonal)

embedding = _generate_embedding(
elbow_cut,
Expand Down
13 changes: 9 additions & 4 deletions topologic/embedding/omnibus_embedding.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,16 @@ def _get_laplacian_matrices(graphs):


def _get_lse_matrix(adjacency_matrix: np.ndarray):
degree = adjacency_matrix.sum(axis=1).T.astype(float)
degree_array = np.squeeze(np.asarray(degree))
diagonal = sp.sparse.diags(degree_array ** -.5)
in_degree = adjacency_matrix.sum(axis=0).astype(float)
out_degree = adjacency_matrix.sum(axis=1).T.astype(float)

lse_matrix = diagonal.dot(adjacency_matrix).dot(diagonal)
in_degree_array = np.squeeze(np.asarray(in_degree))
out_degree_array = np.squeeze(np.asarray(out_degree))

in_diagonal = sp.sparse.diags(in_degree_array ** (-0.5))
out_diagonal = sp.sparse.diags(out_degree_array ** (-0.5))

lse_matrix = out_diagonal.dot(adjacency_matrix).dot(in_diagonal)

return lse_matrix

Expand Down
2 changes: 1 addition & 1 deletion topologic/version/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
name = "topologic"

# manually updated
__semver = "0.1.3"
__semver = "0.1.4"
# full version (may be same as __semver on release)
__version_file = "version.txt"

Expand Down
1 change: 1 addition & 0 deletions topologic/version/version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit bd8e514

Please sign in to comment.