Repository: pgmpy/pgmpy
Pull request #839 (2017-02-06 11:30:22)

FactorGraph: Added copy method
Fixes https://github.com/pgmpy/pgmpy/issues/489


Patch:
diff --git a/pgmpy/models/FactorGraph.py b/pgmpy/models/FactorGraph.py
index 26d5c669..403c7cbd 100644
--- a/pgmpy/models/FactorGraph.py
+++ b/pgmpy/models/FactorGraph.py
@@ -391,3 +391,39 @@ class FactorGraph(UndirectedGraph):
             raise ValueError('DiscreteFactor for all the random variables not defined.')
 
         return np.sum(factor.values)
+
+    def copy(self):
+        """
+        Returns a copy of the model.
+
+        Returns
+        -------
+        FactorGraph : Copy of FactorGraph
+
+        Examples
+        --------
+        >>> from pgmpy.models import FactorGraph
+        >>> from pgmpy.factors.discrete import DiscreteFactor
+        >>> import numpy as np
+        >>> G = FactorGraph()
+        >>> G.add_nodes_from([('a', 'b'), ('b', 'c')])
+        >>> phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
+        >>> phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
+        >>> G.add_factors(phi1, phi2)
+        >>> G.add_nodes_from([phi1, phi2])
+        >>> G.add_edges_from([('a', phi1), ('b', phi1),
+        ...                   ('b', phi2), ('c', phi2)])
+        >>> G_copy = G.copy()
+        >>> G_copy.nodes()
+        [<Factor representing phi(b:2, c:2) at 0xb4badd4c>, 'b', 'c',
+          'a', <Factor representing phi(a:2, b:2) at 0xb4badf2c>]
+
+        """
+        clone_FactorGraph = FactorGraph(self.edges())
+        clone_FactorGraph.add_nodes_from(self.nodes())
+
+        if self.factors:
+           factors_copy = [factor.copy() for factor in self.factors]
+           clone_FactorGraph.add_factors(*factors_copy)
+
+        return clone_FactorGraph	


Test patch:
diff --git a/pgmpy/tests/test_models/test_FactorGraph.py b/pgmpy/tests/test_models/test_FactorGraph.py
index 85e65052..f235135a 100644
--- a/pgmpy/tests/test_models/test_FactorGraph.py
+++ b/pgmpy/tests/test_models/test_FactorGraph.py
@@ -280,5 +280,25 @@ class TestFactorGraphMethods(unittest.TestCase):
         self.graph.add_edges_from([('a', phi3), ('c', phi3)])
         self.assertRaises(ValueError, self.graph.check_model)
 
+    def test_copy(self):
+        self.graph.add_nodes_from(['a', 'b', 'c'])
+        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
+        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
+        self.graph.add_factors(phi1, phi2)
+        self.graph.add_nodes_from([phi1, phi2])
+        self.graph.add_edges_from([('a', phi1), ('b', phi1), 
+                                   ('b', phi2), ('c', phi2)])
+        graph_copy = self.graph.copy()
+        self.assertIsInstance(graph_copy, FactorGraph)
+        self.assertTrue(graph_copy.check_model())
+        self.assertEqual(self.graph.get_factors(), graph_copy.get_factors())
+        self.graph.remove_factors(phi1, phi2)
+        self.assertTrue(phi1 not in self.graph.factors and phi2 not in self.graph.factors)
+        self.assertTrue(phi1 in graph_copy.factors and phi2 in graph_copy.factors)
+        self.graph.add_factors(phi1, phi2)
+        self.graph.factors[0] = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
+        self.assertNotEqual(self.graph.get_factors()[0], graph_copy.get_factors()[0])
+        self.assertNotEqual(self.graph.factors, graph_copy.factors)
+                  
     def tearDown(self):
         del self.graph