Пример #1
0
    def test_loadsave(self):
        _, tmpfile = tempfile.mkstemp()

        g = gtn.Graph()
        gtn.save(tmpfile, g)
        g2 = gtn.load(tmpfile)
        self.assertTrue(gtn.equal(g, g2))

        g = gtn.Graph()
        g.add_node(True)
        g.add_node(True)
        g.add_node()
        g.add_node()
        g.add_node(False, True)
        g.add_node(False, True)

        g.add_arc(0, 1, 0, 1, 1.1)
        g.add_arc(1, 2, 1, 2, 2.1)
        g.add_arc(2, 3, 2, 3, 3.1)
        g.add_arc(3, 4, 3, 4, 4.1)
        g.add_arc(4, 5, 4, gtn.epsilon, 5.1)
        gtn.save(tmpfile, g)
        g2 = gtn.load(tmpfile)
        self.assertTrue(gtn.equal(g, g2))
        self.assertTrue(gtn.isomorphic(g, g2))
Пример #2
0
    def test_sum(self):

        # Empty graph
        self.assertTrue(gtn.equal(gtn.union([]), gtn.Graph()))

        # Check single graph is a no-op
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1)
        self.assertTrue(gtn.equal(gtn.union([g1]), g1))

        # Simple union
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_node(False, True)
        expected.add_arc(0, 2, 1)
        expected.add_arc(1, 3, 0)
        self.assertTrue(gtn.isomorphic(gtn.union([g1, g2]), expected))

        # Check adding with an empty graph works
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1)

        g2 = gtn.Graph()

        g3 = gtn.Graph()
        g3.add_node(True, True)
        g3.add_arc(0, 0, 2)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_node(True, True)
        expected.add_arc(0, 1, 1)
        expected.add_arc(2, 2, 2)
        self.assertTrue(gtn.isomorphic(gtn.union([g1, g2, g3]), expected))
Пример #3
0
    def test_project_clone(self):

        g_str = [
            "0 1",
            "3 4",
            "0 1 0 0 2",
            "0 2 1 1 1",
            "1 2 0 0 2",
            "2 3 0 0 1",
            "2 3 1 1 1",
            "1 4 0 0 2",
            "2 4 1 1 3",
            "3 4 0 0 2",
        ]
        graph = create_graph_from_text(g_str)

        # Test clone
        cloned = gtn.clone(graph)
        self.assertTrue(gtn.equal(graph, cloned))

        # Test projecting input
        g_str = [
            "0 1",
            "3 4",
            "0 1 0 0 2",
            "0 2 1 1 1",
            "1 2 0 0 2",
            "2 3 0 0 1",
            "2 3 1 1 1",
            "1 4 0 0 2",
            "2 4 1 1 3",
            "3 4 0 0 2",
        ]
        inputExpected = create_graph_from_text(g_str)
        self.assertTrue(gtn.equal(gtn.project_input(graph), inputExpected))

        # Test projecting output
        g_str = [
            "0 1",
            "3 4",
            "0 1 0 0 2",
            "0 2 1 1 1",
            "1 2 0 0 2",
            "2 3 0 0 1",
            "2 3 1 1 1",
            "1 4 0 0 2",
            "2 4 1 1 3",
            "3 4 0 0 2",
        ]
        outputExpected = create_graph_from_text(g_str)
        self.assertTrue(gtn.equal(gtn.project_output(graph), outputExpected))
Пример #4
0
 def test_backward_calls_once(self):
     g1 = gtn.scalar_graph(1)
     g2 = gtn.scalar_graph(1)
     gout = gtn.add(g1, g2)
     gtn.backward([gout])
     pmap_grad = gout.grad()
     gout = gtn.add(g1, g2)
     gtn.backward(gout)
     grad = gout.grad()
     self.assertTrue(gtn.equal(pmap_grad, grad))
Пример #5
0
    def test_parallel_one_arg(self):
        inputs = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        outputs = gtn.negate(inputs)

        expected = []
        for g in inputs:
            expected.append(gtn.negate(g))

        self.assertEqual(len(outputs), len(inputs))
        for i in range(0, len(expected)):
            self.assertTrue(gtn.equal(outputs[i], expected[i]))
Пример #6
0
    def test_default_args(self):
        g1 = gtn.scalar_graph(0)
        g1.add_arc(0, 1, 0)

        g2 = gtn.scalar_graph(0)
        g2.add_arc(0, 1, 0)

        g_expected = gtn.remove(g1)
        g_removed = gtn.remove([g1, g2])[0]

        self.assertTrue(gtn.equal(g_expected, g_removed))
Пример #7
0
    def test_comparisons(self):
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)

        self.assertTrue(gtn.equal(g1, g2))
        self.assertTrue(gtn.isomorphic(g1, g2))

        g2 = gtn.Graph()
        g2.add_node(False, True)
        g2.add_node(True)
        g2.add_arc(1, 0, 0)

        self.assertFalse(gtn.equal(g1, g2))
        self.assertTrue(gtn.isomorphic(g1, g2))
Пример #8
0
    def test_parallel_two_arg(self):
        inputs1 = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        inputs2 = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        outputs = gtn.add(inputs1, inputs2)

        expected = []
        for g1, g2 in zip(inputs1, inputs2):
            expected.append(gtn.add(g1, g2))

        self.assertEqual(len(outputs), len(inputs1), len(inputs2))
        for i in range(0, len(expected)):
            self.assertTrue(gtn.equal(outputs[i], expected[i]))
    def test_kernel_graph(self):
        def get_graph(l1, l2, add_skip=False):
            g = gtn.Graph()
            g.add_node(True)
            g.add_node(True)
            g.add_node()
            g.add_node(False, True)
            g.add_node(False, True)
            g.add_arc(0, 0, 2)
            g.add_arc(0, 1, l1)
            g.add_arc(1, 1, l1)
            g.add_arc(1, 2, 2)
            g.add_arc(2, 2, 2)
            g.add_arc(2, 3, l2)
            g.add_arc(3, 3, l2)
            g.add_arc(3, 4, 2)
            g.add_arc(4, 4, 2)
            if add_skip:
                g.add_arc(1, 3, l2)
            return g

        # Repeats with optional blank
        graph = transducer.make_kernel_graph([0, 0], 2, True)
        gtn.equal(graph, get_graph(0, 0, False))

        # No repeats without optional blank
        graph = transducer.make_kernel_graph([0, 1], 2, False)
        gtn.equal(graph, get_graph(0, 1, False))

        # No repeats with optional blank
        graph = transducer.make_kernel_graph([0, 1], 2, True)
        gtn.equal(graph, get_graph(0, 1, True))
Пример #10
0
    def test_parallel_backward(self):
        inputs1 = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        inputs2 = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]

        outputs = gtn.add(inputs1, inputs2)
        gtn.backward(outputs)
        # Test gradients
        inputs1 = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        inputs2 = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        outputs = gtn.add(inputs1, inputs2)
        gradIn = gtn.scalar_graph(5.0)
        gtn.backward(outputs, [gradIn], [False])

        inputs1Dup = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        inputs2Dup = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        expected = []
        for g1, g2 in zip(inputs1Dup, inputs2Dup):
            expected.append(gtn.add(g1, g2))
        for g in expected:
            gtn.backward(g, gtn.scalar_graph(5.0))

        for i in range(0, len(expected)):
            self.assertTrue(gtn.equal(inputs1[i].grad(), inputs1Dup[i].grad()))
            self.assertTrue(gtn.equal(inputs2[i].grad(), inputs2Dup[i].grad()))
Пример #11
0
    def test_parallel_vector_arg(self):
        inputList = [
            gtn.scalar_graph(1.0),
            gtn.scalar_graph(2.0),
            gtn.scalar_graph(3.0),
        ]
        inputs = [inputList, inputList, inputList]
        outputs = gtn.concat(inputs)

        expected = []
        for gList in inputs:
            expected.append(gtn.concat(gList))

        self.assertEqual(len(outputs), len(inputs))
        for i in range(0, len(expected)):
            self.assertTrue(gtn.equal(outputs[i], expected[i]))
Пример #12
0
    def test_clone_project_grad(self):
        g1 = gtn.scalar_graph(3.0)
        g2 = gtn.scalar_graph(4.0)

        cloned = gtn.clone(g1)

        result = gtn.add(g1, g2)
        gtn.backward(result)

        # Cloned wasn't used in the computation
        self.assertRaises(RuntimeError, cloned.grad)

        # Cloned was used in the computation
        g1.zero_grad()
        g2.zero_grad()
        result = gtn.add(cloned, g2)
        gtn.backward(result)
        self.assertTrue(gtn.equal(cloned.grad(), g1.grad()))
Пример #13
0
    def test_parallel_func(self):
        B = 3
        inputs1 = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]
        inputs2 = [gtn.scalar_graph(k) for k in [1.0, 2.0, 3.0]]

        out = [None] * B

        def process(b):
            out[b] = gtn.add(gtn.add(inputs1[b], inputs1[b]),
                             gtn.negate(inputs2[b]))

        gtn.parallel_for(process, range(B))

        expected = []
        for b in range(B):
            expected.append(
                gtn.add(gtn.add(inputs1[b], inputs1[b]),
                        gtn.negate(inputs2[b])))

        self.assertEqual(len(out), len(expected))
        for i in range(len(expected)):
            self.assertTrue(gtn.equal(out[i], expected[i]))
Пример #14
0
    def test_closure(self):

        # Empty graph
        expected = gtn.Graph()
        expected.add_node(True, True)
        self.assertTrue(gtn.equal(gtn.closure(gtn.Graph()), expected))

        # Multi-start, multi-accept
        g = gtn.Graph()
        g.add_node(True)
        g.add_node(True)
        g.add_node(False, True)
        g.add_node(False, True)
        g.add_arc(0, 2, 0, 0, 0.0)
        g.add_arc(0, 3, 1, 2, 2.1)
        g.add_arc(1, 2, 0, 1, 1.0)
        g.add_arc(1, 3, 1, 3, 3.1)

        expected = gtn.Graph()
        expected.add_node(True, True)
        expected.add_node()
        expected.add_node()
        expected.add_node(False, True)
        expected.add_node(False, True)
        expected.add_arc(0, 1, gtn.epsilon)
        expected.add_arc(0, 2, gtn.epsilon)
        expected.add_arc(1, 3, 0, 0, 0.0)
        expected.add_arc(1, 4, 1, 2, 2.1)
        expected.add_arc(2, 3, 0, 1, 1.0)
        expected.add_arc(2, 4, 1, 3, 3.1)
        expected.add_arc(3, 1, gtn.epsilon)
        expected.add_arc(3, 2, gtn.epsilon)
        expected.add_arc(4, 1, gtn.epsilon)
        expected.add_arc(4, 2, gtn.epsilon)

        self.assertTrue(gtn.rand_equivalent(gtn.closure(g), expected))
Пример #15
0
    def test_loadtxt(self):

        g1 = gtn.Graph()
        g1.add_node(True, True)
        g1.add_node(False, True)
        g1.add_node()
        g1.add_arc(0, 0, 1)
        g1.add_arc(0, 2, 1, 1, 1.1)
        g1.add_arc(2, 1, 2, 2, 2.1)

        g_str = ["0", "0 1", "0 0 1 1 0", "0 2 1 1 1.1", "2 1 2 2 2.1"]
        g2 = create_graph_from_text(g_str)
        self.assertTrue(gtn.equal(g1, g2))
        self.assertTrue(gtn.isomorphic(g1, g2))

        _, tmpfile = tempfile.mkstemp()

        # Write the test file
        gtn.savetxt(tmpfile, g2)
        g3 = gtn.loadtxt(tmpfile)
        self.assertTrue(gtn.equal(g1, g3))

        # Empty graph doesn't load

        g_str = [""]
        self.assertRaises(ValueError, create_graph_from_text, g_str)

        # Graph without accept nodes doesn't load

        g_str = ["1"]
        self.assertRaises(ValueError, create_graph_from_text, g_str)

        # Graph with repeat start nodes doesn't load

        g_str = ["1 0 0", "0 1"]
        self.assertRaises(ValueError, create_graph_from_text, g_str)

        # Graph loads if the start and accept nodes are specified

        g_str = ["0", "1"]
        g = gtn.Graph()
        g.add_node(True)
        g.add_node(False, True)
        self.assertTrue(gtn.equal(g, create_graph_from_text(g_str)))

        # Graph doesn't load if arc incorrect

        g_str = ["0", "1", "0 2"]
        self.assertRaises(ValueError, create_graph_from_text, g_str)
        g_str = ["0", "1", "0 1 2 3 4 5"]
        self.assertRaises(ValueError, create_graph_from_text, g_str)

        # Transducer loads

        g1 = gtn.Graph()
        g1.add_node(True, True)
        g1.add_node(False, True)
        g1.add_node()
        g1.add_arc(0, 0, 1, 1)
        g1.add_arc(0, 2, 1, 2, 1.1)
        g1.add_arc(2, 1, 2, 3, 2.1)

        g_str = ["0", "0 1", "0 0 1", "0 2 1 2 1.1", "2 1 2 3 2.1"]
        g2 = create_graph_from_text(g_str)
        self.assertTrue(gtn.equal(g1, g2))
        self.assertTrue(gtn.isomorphic(g1, g2))
Пример #16
0
    def test_epsilon_composition(self):

        # Simple test case for output epsilon on first graph
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 0, 0, gtn.epsilon, 1.0)
        g1.add_arc(0, 1, 1, 2)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 2, 3)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_arc(0, 0, 0, gtn.epsilon, 1.0)
        expected.add_arc(0, 1, 1, 3)

        self.assertTrue(gtn.equal(gtn.compose(g1, g2), expected))

        # Simple test case for input epsilon on second graph
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1, 2)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 2, 3)
        g2.add_arc(1, 1, gtn.epsilon, 0, 2.0)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_arc(0, 1, 1, 3)
        expected.add_arc(1, 1, gtn.epsilon, 0, 2.0)

        self.assertTrue(gtn.equal(gtn.compose(g1, g2), expected))

        # This test case is taken from "Weighted Automata Algorithms", Mehryar
        # Mohri, https://cs.nyu.edu/~mohri/pub/hwa.pdf Section 5.1, Figure 7
        symbols = {"a": 0, "b": 1, "c": 2, "d": 3, "e": 4}
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_node()
        g1.add_node()
        g1.add_node(False, True)
        g1.add_arc(0, 1, symbols["a"], symbols["a"])
        g1.add_arc(1, 2, symbols["b"], gtn.epsilon)
        g1.add_arc(2, 3, symbols["c"], gtn.epsilon)
        g1.add_arc(3, 4, symbols["d"], symbols["d"])

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_node()
        g2.add_node(False, True)
        g2.add_arc(0, 1, symbols["a"], symbols["d"])
        g2.add_arc(1, 2, gtn.epsilon, symbols["e"])
        g2.add_arc(2, 3, symbols["d"], symbols["a"])

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node()
        expected.add_node()
        expected.add_node()
        expected.add_node(False, True)
        expected.add_arc(0, 1, symbols["a"], symbols["d"])
        expected.add_arc(1, 2, symbols["b"], symbols["e"])
        expected.add_arc(2, 3, symbols["c"], gtn.epsilon)
        expected.add_arc(3, 4, symbols["d"], symbols["a"])

        self.assertTrue(gtn.rand_equivalent(gtn.compose(g1, g2), expected))

        # Test multiple input/output epsilon transitions per node
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 0, 1, gtn.epsilon, 1.1)
        g1.add_arc(0, 1, 2, gtn.epsilon, 2.1)
        g1.add_arc(0, 1, 3, gtn.epsilon, 3.1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, gtn.epsilon, 3, 2.1)
        g2.add_arc(0, 1, 1, 2)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_arc(0, 0, 1, gtn.epsilon, 1.1)
        expected.add_arc(0, 1, 2, 3, 4.2)
        expected.add_arc(0, 1, 3, 3, 5.2)

        self.assertTrue(gtn.rand_equivalent(gtn.compose(g1, g2), expected))
Пример #17
0
    def test_concat(self):

        # Empty string language
        g = gtn.Graph()
        g.add_node(True, True)

        self.assertTrue(gtn.equal(gtn.concat([]), g))
        self.assertTrue(gtn.rand_equivalent(gtn.concat([g, g]), g))
        self.assertTrue(gtn.rand_equivalent(gtn.concat([g, g, g]), g))

        # Singleton
        g = gtn.Graph()
        g.add_node(True)
        g.add_node(False, True)
        g.add_arc(0, 1, 1)
        self.assertTrue(gtn.equal(gtn.concat([g]), g))

        # Empty language
        g = gtn.Graph()
        g.add_node()
        self.assertTrue(gtn.rand_equivalent(gtn.concat([g, g]), gtn.Graph()))
        self.assertTrue(gtn.rand_equivalent(gtn.concat([g, g, g]), gtn.Graph()))

        # Concat 0 and 1 to get 01
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 1)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node()
        expected.add_node(False, True)
        expected.add_arc(0, 1, 0)
        expected.add_arc(1, 2, 1)

        self.assertTrue(gtn.rand_equivalent(gtn.concat([g1, g2]), expected))

        # Concat 0, 1 and 2, 3 to get 02, 03, 12, 13
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0)
        g1.add_arc(0, 2, 1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 2, 2)
        g2.add_arc(1, 2, 3)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node()
        expected.add_node(False, True)
        expected.add_arc(0, 1, 0)
        expected.add_arc(0, 1, 1)
        expected.add_arc(1, 2, 2)
        expected.add_arc(1, 2, 3)

        self.assertTrue(gtn.rand_equivalent(gtn.concat([g1, g2]), expected))
Пример #18
0
    def test_remove(self):
        g = gtn.Graph(False)
        g.add_node(True)
        g.add_node()
        g.add_node(False, True)
        g.add_arc(0, 1, gtn.epsilon)
        g.add_arc(1, 2, 0)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_arc(0, 1, 0)
        self.assertTrue(gtn.equal(gtn.remove(g, gtn.epsilon), expected))

        # Check gradient status propagates correctly
        self.assertFalse(gtn.remove(g, gtn.epsilon).calc_grad)

        # Removing other labels works
        g = gtn.Graph()
        g.add_node(True)
        g.add_node()
        g.add_node(False, True)
        g.add_arc(0, 1, 2, 1)
        g.add_arc(1, 2, 0, 1)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_arc(0, 1, 0, 1)
        self.assertTrue(gtn.equal(gtn.remove(g, 2, 1), expected))

        # No-op on graph without epsilons
        g = gtn.Graph()
        g.add_node(True)
        g.add_node(False, True)
        g.add_arc(0, 1, 0, 1)
        g.add_arc(0, 1, 1, 1)
        self.assertTrue(gtn.equal(gtn.remove(g), g))

        # Epsilon only transitions into accepting state
        g = gtn.Graph()
        g.add_node(True)
        g.add_node()
        g.add_node()
        g.add_node(False, True)
        g.add_arc(0, 1, 0)
        g.add_arc(0, 2, 1)
        g.add_arc(1, 3, gtn.epsilon)
        g.add_arc(2, 3, gtn.epsilon)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node(False, True)
        expected.add_node(False, True)
        expected.add_arc(0, 1, 0)
        expected.add_arc(0, 2, 1)
        self.assertTrue(gtn.equal(gtn.remove(g), expected))

        # Only remove an arc, no removed nodes
        g = gtn.Graph()
        g.add_node(True)
        g.add_node()
        g.add_node()
        g.add_node(False, True)
        g.add_arc(0, 1, gtn.epsilon)
        g.add_arc(0, 2, 1)
        g.add_arc(2, 1, 0)
        g.add_arc(1, 3, 1)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node()
        expected.add_node()
        expected.add_node(False, True)
        expected.add_arc(0, 2, 1)
        expected.add_arc(2, 1, 0)
        expected.add_arc(1, 3, 1)
        expected.add_arc(0, 3, 1)
        self.assertTrue(gtn.equal(gtn.remove(g), expected))

        # Successive epsilons
        g = gtn.Graph()
        g.add_node(True)
        g.add_node()
        g.add_node()
        g.add_node()
        g.add_node(False, True)
        g.add_arc(0, 1, 0)
        g.add_arc(1, 2, gtn.epsilon)
        g.add_arc(2, 3, gtn.epsilon)
        g.add_arc(2, 4, 1)
        g.add_arc(3, 4, 2)
        g.add_arc(1, 4, 0)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node()
        expected.add_node(False, True)
        expected.add_arc(0, 1, 0)
        expected.add_arc(1, 2, 0)
        expected.add_arc(1, 2, 1)
        expected.add_arc(1, 2, 2)
        self.assertTrue(gtn.equal(gtn.remove(g), expected))

        # Multiple interior removals

        g = gtn.Graph()
        g.add_node(True)
        g.add_node()
        g.add_node()
        g.add_node()
        g.add_node(False, True)
        g.add_arc(0, 1, gtn.epsilon)
        g.add_arc(1, 2, gtn.epsilon)
        g.add_arc(2, 3, 0)
        g.add_arc(3, 4, 0)

        expected = gtn.Graph()
        expected.add_node(True)
        expected.add_node()
        expected.add_node(False, True)
        expected.add_arc(0, 1, 0)
        expected.add_arc(1, 2, 0)
        self.assertTrue(gtn.equal(gtn.remove(g), expected))
Пример #19
0
    def test_viterbi_path(self):

        g = gtn.Graph()

        # Empty graph gives empty path
        self.assertTrue(gtn.equal(gtn.viterbi_path(g), g))

        # Accepting empty string
        g.add_node(True, True)
        self.assertTrue(gtn.equal(gtn.viterbi_path(g), g))

        # A simple test case
        g = gtn.Graph()
        g.add_node(True)
        g.add_node()
        g.add_node(False, True)
        g.add_arc(0, 1, 0, 0, 1)
        g.add_arc(0, 1, 1, 1, 2)
        g.add_arc(0, 1, 2, 2, 3)
        g.add_arc(1, 2, 0, 0, 1)
        g.add_arc(1, 2, 1, 1, 2)
        g.add_arc(1, 2, 2, 2, 3)

        best = gtn.Graph()
        best.add_node(True)
        best.add_node()
        best.add_node(False, True)
        best.add_arc(0, 1, 2, 2, 3)
        best.add_arc(1, 2, 2, 2, 3)

        path = gtn.viterbi_path(g)
        self.assertTrue(gtn.rand_equivalent(path, best))
        self.assertEqual(gtn.viterbi_score(path).item(), gtn.viterbi_score(g).item())

        # Handle a single node.
        g = gtn.Graph()
        g.add_node(True, True)

        best = gtn.Graph()
        best.add_node(True, True)
        path = gtn.viterbi_path(g)
        self.assertTrue(gtn.rand_equivalent(path, best))
        self.assertEqual(gtn.viterbi_score(path).item(), gtn.viterbi_score(g).item())

        # Handle two start nodes
        g = gtn.Graph()
        g.add_node(True)
        g.add_node(True)
        g.add_node(False, True)
        g.add_arc(0, 1, 0, 0, -5)
        g.add_arc(0, 2, 0, 0, 1)
        g.add_arc(1, 2, 0, 0, 2)

        best = gtn.Graph()
        best.add_node(True)
        best.add_node(False, True)
        best.add_arc(0, 1, 0, 0, 2)

        path = gtn.viterbi_path(g)
        self.assertTrue(gtn.rand_equivalent(path, best))
        self.assertEqual(gtn.viterbi_score(path).item(), gtn.viterbi_score(g).item())

        # Handle two accept nodes
        g = gtn.Graph()
        g.add_node(True)
        g.add_node(False, True)
        g.add_node(False, True)
        g.add_arc(0, 1, 0, 0, 3)
        g.add_arc(0, 2, 0, 0, 2)
        g.add_arc(1, 2, 0, 0, 2)

        best = gtn.Graph()
        best.add_node(True)
        best.add_node()
        best.add_node(False, True)
        best.add_arc(0, 1, 0, 0, 3)
        best.add_arc(1, 2, 0, 0, 2)

        path = gtn.viterbi_path(g)
        self.assertTrue(gtn.rand_equivalent(path, best))
        self.assertEqual(gtn.viterbi_score(path).item(), gtn.viterbi_score(g).item())

        # A more complex test case
        g_str = [
            "0 1",
            "3 4",
            "0 1 0 0 2",
            "0 2 1 1 1",
            "1 2 0 0 2",
            "2 3 0 0 1",
            "2 3 1 1 1",
            "1 4 0 0 2",
            "2 4 1 1 3",
            "3 4 0 0 2",
        ]
        g = create_graph_from_text(g_str)

        # There are three options for the best path, the
        # viterbiPath may return any of them.
        best1 = gtn.Graph()
        best1.add_node(True)
        best1.add_node()
        best1.add_node()
        best1.add_node()
        best1.add_node(False, True)
        best1.add_arc(0, 1, 0, 0, 2)
        best1.add_arc(1, 2, 0, 0, 2)
        best1.add_arc(2, 3, 0, 0, 1)
        best1.add_arc(3, 4, 0, 0, 2)

        best2 = gtn.Graph()
        best2.add_node(True)
        best2.add_node()
        best2.add_node()
        best2.add_node()
        best2.add_node(False, True)
        best2.add_arc(0, 1, 0, 0, 2)
        best2.add_arc(1, 2, 0, 0, 2)
        best2.add_arc(2, 3, 1, 1, 1)
        best2.add_arc(3, 4, 0, 0, 2)

        best3 = gtn.Graph()
        best3.add_node(True)
        best3.add_node()
        best3.add_node()
        best3.add_node(False, True)
        best3.add_arc(0, 1, 0, 0, 2)
        best3.add_arc(1, 2, 0, 0, 2)
        best3.add_arc(2, 3, 1, 1, 3)

        path = gtn.viterbi_path(g)
        self.assertTrue(
            (
                gtn.rand_equivalent(path, best1)
                or gtn.rand_equivalent(path, best2)
                or gtn.rand_equivalent(path, best3)
            )
        )

        self.assertEqual(gtn.viterbi_score(path).item(), gtn.viterbi_score(g).item())
Пример #20
0
    def test_equality(self):
        # Empty graph is equal to itself
        g1 = gtn.Graph()
        g2 = gtn.Graph()
        self.assertTrue(gtn.equal(g1, g2))

        # Different start node
        g1 = gtn.Graph()
        g1.add_node(True)

        g2 = gtn.Graph()
        g2.add_node(False)
        self.assertFalse(gtn.equal(g1, g2))

        # Simple equality
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        self.assertTrue(gtn.equal(g1, g2))

        # Different arc label
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_arc(0, 1, 0)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_arc(0, 1, 1)
        self.assertFalse(gtn.equal(g1, g2))

        # Different arc weight
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_arc(0, 1, 0, 0, 1.2)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_arc(0, 1, 0, 0, 2.2)
        self.assertFalse(gtn.equal(g1, g2))

        # Self loop in g1
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0)
        g1.add_arc(0, 1, 1)
        g1.add_arc(1, 1, 1)
        g1.add_arc(1, 2, 2)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)
        g2.add_arc(0, 1, 1)
        g2.add_arc(1, 2, 2)
        self.assertFalse(gtn.equal(g1, g2))

        # Equals
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0, 0, 2.1)
        g1.add_arc(0, 1, 1, 1, 3.1)
        g1.add_arc(1, 1, 1, 1, 4.1)
        g1.add_arc(1, 2, 2, 2, 5.1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0, 0, 2.1)
        g2.add_arc(0, 1, 1, 1, 3.1)
        g2.add_arc(1, 1, 1, 1, 4.1)
        g2.add_arc(1, 2, 2, 2, 5.1)
        self.assertTrue(gtn.equal(g1, g2))

        # Different arc order
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1, 1, 3.1)
        g1.add_arc(0, 1, 0, 0, 2.1)
        g1.add_arc(1, 1, 1, 1, 4.1)
        g1.add_arc(1, 2, 2, 2, 5.1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0, 0, 2.1)
        g2.add_arc(0, 1, 1, 1, 3.1)
        g2.add_arc(1, 2, 2, 2, 5.1)
        g2.add_arc(1, 1, 1, 1, 4.1)
        self.assertTrue(gtn.equal(g1, g2))

        # Repeat arcs
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 1, 1, 3.1)
        g1.add_arc(0, 1, 1, 1, 3.1)
        g1.add_arc(0, 1, 1, 1, 4.1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 1, 1, 3.1)
        g2.add_arc(0, 1, 1, 1, 4.1)
        g2.add_arc(0, 1, 1, 1, 4.1)
        self.assertFalse(gtn.equal(g1, g2))

        # Transducer with different outputs
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0, 1, 2.1)
        g1.add_arc(1, 1, 1, 3, 4.1)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0, 1, 2.1)
        g2.add_arc(1, 1, 1, 4, 4.1)
        self.assertFalse(gtn.equal(g1, g2))
Пример #21
0
    def test_composition(self):
        # Compos,ing with an empty graph gives an empty graph
        g1 = gtn.Graph()
        g2 = gtn.Graph()
        self.assertTrue(gtn.equal(gtn.compose(g1, g2), gtn.Graph()))

        g1.add_node(True)
        g1.add_node()
        g1.add_arc(0, 1, 0)

        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)
        g2.add_arc(0, 1, 0)

        self.assertTrue(gtn.equal(gtn.compose(g1, g2), gtn.Graph()))
        self.assertTrue(gtn.equal(gtn.compose(g2, g1), gtn.Graph()))
        self.assertTrue(gtn.equal(gtn.intersect(g2, g1), gtn.Graph()))

        # Check singly sorted version
        g1.arc_sort(True)
        self.assertTrue(gtn.equal(gtn.compose(g1, g2), gtn.Graph()))

        # Check doubly sorted version
        g2.arc_sort()
        self.assertTrue(gtn.equal(gtn.compose(g1, g2), gtn.Graph()))

        # Self-loop in the composed graph
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 0, 0)
        g1.add_arc(0, 1, 1)
        g1.add_arc(1, 1, 2)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0)
        g2.add_arc(1, 1, 0)
        g2.add_arc(1, 2, 1)

        g_str = ["0", "2", "0 1 0", "1 1 0", "1 2 1"]
        expected = create_graph_from_text(g_str)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))
        self.assertTrue(gtn.isomorphic(gtn.intersect(g1, g2), expected))

        # Check singly sorted version
        g1.arc_sort(True)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        # Check doubly sorted version
        g2.arc_sort()
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        # Loop in the composed graph
        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node(False, True)
        g1.add_arc(0, 1, 0)
        g1.add_arc(1, 1, 1)
        g1.add_arc(1, 0, 0)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node(False, True)
        g2.add_arc(0, 0, 0)
        g2.add_arc(0, 1, 1)
        g2.add_arc(1, 0, 1)

        g_str = ["0", "2", "0 1 0", "1 0 0", "1 2 1", "2 1 1"]
        expected = create_graph_from_text(g_str)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))
        self.assertTrue(gtn.isomorphic(gtn.intersect(g1, g2), expected))

        # Check singly sorted version
        g1.arc_sort(True)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        # Check doubly sorted version
        g2.arc_sort()
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        g1 = gtn.Graph()
        g1.add_node(True)
        g1.add_node()
        g1.add_node()
        g1.add_node()
        g1.add_node(False, True)
        for i in range(g1.num_nodes() - 1):
            for j in range(3):
                g1.add_arc(i, i + 1, j, j, j)

        g2 = gtn.Graph()
        g2.add_node(True)
        g2.add_node()
        g2.add_node(False, True)
        g2.add_arc(0, 1, 0, 0, 3.5)
        g2.add_arc(1, 1, 0, 0, 2.5)
        g2.add_arc(1, 2, 1, 1, 1.5)
        g2.add_arc(2, 2, 1, 1, 4.5)
        g_str = [
            "0",
            "6",
            "0 1 0 0 3.5",
            "1 2 0 0 2.5",
            "1 4 1 1 2.5",
            "2 3 0 0 2.5",
            "2 5 1 1 2.5",
            "4 5 1 1 5.5",
            "3 6 1 1 2.5",
            "5 6 1 1 5.5",
        ]
        expected = create_graph_from_text(g_str)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))
        self.assertTrue(gtn.isomorphic(gtn.intersect(g1, g2), expected))

        # Check singly sorted version
        g1.arc_sort(True)
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))

        # Check doubly sorted version
        g2.arc_sort()
        self.assertTrue(gtn.isomorphic(gtn.compose(g1, g2), expected))