Repository: pgmpy/pgmpy
Pull request #894 (2017-09-12 20:37:46)

MarkovModel.py: Added node as an optional argument in get_cardinality method
As per the discussion now get_cardinality of MarkovModel accepts node as an optional argument and return the cardinality of the node. If node is not specified returns a dictionary with the given factors as keys and their respective cardinality as values.


coveralls: 
[![Coverage Status](https://coveralls.io/builds/13241761/badge)](https://coveralls.io/builds/13241761)

Coverage increased (+0.02%) to 94.89% when pulling **707e5f44fe6cb97c5a6de035d05c27f73a0d164d on lohani2280:branch7** into **b102d8822240abd4e013417bfc900e6cec78e473 on pgmpy:dev**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/13241876/badge)](https://coveralls.io/builds/13241876)

Coverage increased (+0.009%) to 94.881% when pulling **93820b2ed2f25096324906124a40585dfaeb640a on lohani2280:branch7** into **b102d8822240abd4e013417bfc900e6cec78e473 on pgmpy:dev**.


Patch:
diff --git a/pgmpy/models/MarkovModel.py b/pgmpy/models/MarkovModel.py
index 5049d321..ce63e848 100644
--- a/pgmpy/models/MarkovModel.py
+++ b/pgmpy/models/MarkovModel.py
@@ -177,10 +177,18 @@ class MarkovModel(UndirectedGraph):
         for factor in factors:
             self.factors.remove(factor)
 
-    def get_cardinality(self):
+    def get_cardinality(self, node=None):
         """
-        Returns a dictionary with the given factors as keys and their respective
-        cardinality as values.
+        Returns the cardinality of the node. If node is not specified returns
+        a dictionary with the given variable as keys and their respective cardinality
+        as values.
+
+        Parameters
+        ----------
+        node: any hashable python object (optional)
+            The node whose cardinality we want. If node is not specified returns a
+            dictionary with the given variable as keys and their respective cardinality
+            as values.
 
         Examples
         --------
@@ -190,14 +198,22 @@ class MarkovModel(UndirectedGraph):
         >>> factor = DiscreteFactor(['Alice', 'Bob'], cardinality=[2, 2],
         ...                 values=np.random.rand(4))
         >>> student.add_factors(factor)
+        >>> student.get_cardinality(node='Alice')
+        2
         >>> student.get_cardinality()
         defaultdict(<class 'int'>, {'Bob': 2, 'Alice': 2})
         """
-        cardinalities = defaultdict(int)
-        for factor in self.factors:
-            for variable, cardinality in zip(factor.scope(), factor.cardinality):
-                cardinalities[variable] = cardinality
-        return cardinalities
+        if node:
+            for factor in self.factors:
+                for variable, cardinality in zip(factor.scope(), factor.cardinality):
+                    if node == variable:
+                       return cardinality
+        else:
+            cardinalities = defaultdict(int)
+            for factor in self.factors:
+                    for variable, cardinality in zip(factor.scope(), factor.cardinality):
+                        cardinalities[variable] = cardinality
+            return cardinalities
 
     def check_model(self):
         """


Test patch:
diff --git a/pgmpy/tests/test_models/test_MarkovModel.py b/pgmpy/tests/test_models/test_MarkovModel.py
index 4eaa181e..77cc229f 100644
--- a/pgmpy/tests/test_models/test_MarkovModel.py
+++ b/pgmpy/tests/test_models/test_MarkovModel.py
@@ -115,6 +115,19 @@ class TestMarkovModelMethods(unittest.TestCase):
         self.graph.remove_factors(phi1, phi2, phi3)
         self.assertDictEqual(self.graph.get_cardinality(), {})
 
+    def test_get_cardinality_with_node(self):
+
+        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
+                                   ('d', 'a')])
+
+        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
+        phi2 = DiscreteFactor(['c', 'd'], [1, 2], np.random.rand(2))
+        self.graph.add_factors(phi1, phi2)
+        self.assertEqual(self.graph.get_cardinality('a'), 2)
+        self.assertEqual(self.graph.get_cardinality('b'), 2)
+        self.assertEqual(self.graph.get_cardinality('c'), 1)
+        self.assertEqual(self.graph.get_cardinality('d'), 2)
+
     def test_check_model(self):
         self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                    ('d', 'a')])