Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Rewrite test_metis.py to test exposed functions
Browse files Browse the repository at this point in the history
  • Loading branch information
OrkoHunter committed Jul 22, 2015
1 parent 39602a7 commit 5dea0b6
Showing 1 changed file with 72 additions and 53 deletions.
125 changes: 72 additions & 53 deletions nxmetis/tests/test_metis.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import itertools
import nose.tools

import networkx as nx

import nxmetis
from nxmetis import exceptions
from nxmetis import _metis
from nxmetis import types
Expand All @@ -17,59 +20,75 @@ def make_cycle(n):

class TestMetis(object):

def test_node_nd(self):
n = 16
xadj, adjncy = make_cycle(n)
perm, iperm = _metis.node_nd(xadj, adjncy)
nose.tools.assert_equal(set(perm), set(range(n)))
nose.tools.assert_equal(abs(perm[-1] - perm[-2]), n // 2)
nose.tools.ok_(set(range(min(perm[-2:]) + 1, max(perm[-2:]))) in
(set(perm[0:n // 2 - 1]), set(perm[n // 2 - 1:-2])))
nose.tools.ok_(all(i == perm[iperm[i]] for i in range(n)))

def test_selfloops(self):
n = 16
xadj = list(range(0, 3 * n + 1, 3))
adjncy = list(
itertools.chain.from_iterable(
zip(itertools.chain([n - 1], range(n - 1)),
range(n),
itertools.chain(range(1, n), [0]))))
perm, iperm = _metis.node_nd(xadj, adjncy)
nose.tools.assert_equal(set(perm), set(range(n)))
nose.tools.assert_equal(abs(perm[-1] - perm[-2]), n // 2)
nose.tools.ok_(set(range(min(perm[-2:]) + 1, max(perm[-2:]))) in
(set(perm[0:n // 2 - 1]), set(perm[n // 2 - 1:-2])))
nose.tools.ok_(all(i == perm[iperm[i]] for i in range(n)))

def test_part_graph(self):
n = 16
xadj, adjncy = make_cycle(n)
for recursive in (False, True):
objval, part = _metis.part_graph(
xadj, adjncy, 2, recursive=recursive)
nose.tools.assert_equal(objval, 2)
nose.tools.assert_equal(set(part), set(range(2)))
it = itertools.dropwhile(lambda x: x == 0, itertools.cycle(part))
nose.tools.assert_equal(
list(itertools.takewhile(lambda x: x == 1, it)), [1] * (n // 2))

def test_compute_vertex_separator(self):
n = 16
xadj, adjncy = make_cycle(n)
sepsize, part = _metis.compute_vertex_separator(xadj, adjncy)
nose.tools.assert_equal(sepsize, 2)
nose.tools.assert_equal(len(part), n)
part1, part2, sep = (list(filter(lambda i: part[i] == k, range(n)))
for k in range(3))
nose.tools.assert_equal(sorted(part1 + part2 + sep), list(range(n)))
nose.tools.assert_equal(len(sep), 2)
nose.tools.assert_equal(abs(sep[1] - sep[0]), n // 2)
nose.tools.assert_equal(
sorted(map(sorted, [part1, part2])),
sorted(map(sorted,
[[(sep[0] + i) % n for i in range(1, n // 2)],
[(sep[1] + i) % n for i in range(1, n // 2)]])))
def setUp(self):
self.node_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
1, 2, 3, 4, 5, 6]
self.G = nx.Graph()
self.G.add_path(self.node_list)
self.G.add_edge(self.node_list[-1], self.node_list[0])

def test_node_nested_dissection_unweighted(self):
node_ordering = nxmetis.node_nested_dissection(self.G)
nose.tools.assert_equal(len(self.G), len(node_ordering))
nose.tools.assert_equal(set(self.G), set(node_ordering))

# Tests for exercising package's ability to handle self-loops
# METIS crashes on self loops. networkx-metis should not
self.G.add_edge(1, 1)
self.G.add_edge('a', 'a')
node_ordering = nxmetis.node_nested_dissection(self.G)
nose.tools.assert_equal(len(self.G), len(node_ordering))
nose.tools.assert_equal(set(self.G), set(node_ordering))


def test_partition(self):
partition = nxmetis.partition(self.G, 4)
# When we choose one node from one part of the partitioned Graph,
# It must be adjacent to one or more of the nodes in the same part.
# This is to verify the continuity of the chain of nodes.
parts = partition[1] # List containing partitioned node lists

nose.tools.assert_equal(list(partition)[0], 4)

for part in parts:
nose.tools.assert_not_equal(0, len(part)) # Non-empty set
nose.tools.assert_equal(len(part), len(set(part))) # Duplicate-free
nose.tools.ok_(nx.is_connected(self.G.subgraph(part))) # Connected

# Disjoint sets
nose.tools.ok_(set(parts[0]) & set(parts[1]) == set())
nose.tools.ok_(set(parts[0]) & set(parts[2]) == set())
nose.tools.ok_(set(parts[0]) & set(parts[3]) == set())
nose.tools.ok_(set(parts[1]) & set(parts[2]) == set())
nose.tools.ok_(set(parts[1]) & set(parts[3]) == set())
nose.tools.ok_(set(parts[2]) & set(parts[3]) == set())

def test_vertex_separator(self):
bisection = nxmetis.vertex_separator(self.G)

# The two separator nodes must not be present in the
# two bisected chains
nose.tools.ok_(list(bisection)[0][0] not in list(bisection)[1])
nose.tools.ok_(list(bisection)[0][0] not in list(bisection)[2])
nose.tools.ok_(list(bisection)[0][1] not in list(bisection)[1])
nose.tools.ok_(list(bisection)[0][1] not in list(bisection)[2])

# The lists should be exhaustive with the node list of the Graph
nose.tools.ok_(set(list(bisection)[0]) | set(list(bisection)[1]) |
set(list(bisection)[2]) == set(self.G))

# Continuity check
part1 = list(bisection)[1] # One of the two bisected lists
part2 = list(bisection)[2] # One of the two bisected lists

nose.tools.ok_(set(part1)!={0}) # Non-empty set
nose.tools.ok_(set(part2)!={0})

nose.tools.ok_(len(part1)==len(set(part1))) # Duplicate-free
nose.tools.ok_(len(part2)==len(set(part2)))

nose.tools.ok_(nx.is_connected(self.G.subgraph(part1))) # Connected
nose.tools.ok_(nx.is_connected(self.G.subgraph(part2)))

def test_MetisOptions(self):
n = 16
Expand Down

0 comments on commit 5dea0b6

Please sign in to comment.