def testKL(self): v = gum.LabelizedVariable("v", "v", 2) w = gum.LabelizedVariable("w", "w", 2) p = gum.Potential().add(v).fillWith([0.0, 1.0]) q = gum.Potential().add(v).fillWith([0.5, 0.5]) r = gum.Potential().add(v).fillWith([0.7, 0.3]) s = gum.Potential().add(v).add(w).fillWith([0.0, 1.0, 0.2, .08]) self.assertEqual(p.KL(p), 0.0) with self.assertRaises(gum.InvalidArgument): res = p.KL(s) with self.assertRaises(gum.InvalidArgument): res = s.KL(p) res = p.KL(q) self.assertAlmostEqual(res, 0.0 + 1.0 * math.log(1.0 / 0.5, 2)) with self.assertRaises(gum.FatalError): res = q.KL(p) res = p.KL(r) self.assertAlmostEqual(res, 0.0 + 1.0 * math.log(1.0 / 0.3, 2)) with self.assertRaises(gum.FatalError): res = r.KL(p) self.assertAlmostEqual( q.KL(r), 0.5 * math.log(0.5 / 0.7, 2) + 0.5 * math.log(0.5 / 0.3, 2)) self.assertAlmostEqual( r.KL(q), 0.7 * math.log(0.7 / 0.5, 2) + 0.3 * math.log(0.3 / 0.5, 2))
def testEqualities(self): u = gum.LabelizedVariable("u", "u", 4) v = gum.LabelizedVariable("v", "v", 2) w = gum.LabelizedVariable("w", "w", 3) p = gum.Potential().add(u).add(v).add(w) p.random() q = gum.Potential(p) self.assertEqual(p, q) i = gum.Instantiation(q) i.setLast() q[i] = 0 self.assertNotEqual(p, q) q.fillWith(p) self.assertEqual(p, q) q.fillWith(1) self.assertNotEqual(p, q) q.fillWith(p) self.assertEqual(p, q) x = gum.LabelizedVariable("x", "Unknown", 5) q.add(x) self.assertNotEqual(p, q) q = gum.Potential().add(v).add(w) self.assertNotEqual(p, q)
def test_basic(): v = gum.DiscretizedVariable("v", "v") for i in [0, 4, 10, 15, 30, 40]: v.addTick(i) w = gum.DiscretizedVariable("w", "w") for i in [-1, 4, 10, 30, 40]: w.addTick(i) print("\n** From OT::Distribution to gum::Potential:") unifDistribution = ot.Uniform(0, 40) pv = gum.Potential(otagrum.Utils.Discretize(unifDistribution, v)) pw = gum.Potential(otagrum.Utils.Discretize(unifDistribution, w)) print(pv) print(pw) print("\nCatching InvalidArgumentException for bad support") try: otagrum.Utils.Discretize(ot.Uniform(1, 100), w) print("Fail") except: print("OK") print("\n** Back to OT::Distribution") print(otagrum.Utils.FromMarginal(pv)) print(otagrum.Utils.FromMarginal(pw))
def testGetPosterior(self): self.assertEqual(gum.getPosterior(self.bn, {}, "A"), self.joint.margSumIn(["A"])) self.assertEqual(gum.getPosterior(self.bn, {}, 2), self.joint.margSumIn(["C"])) self.assertEqual(gum.getPosterior(self.bn, {}, 'D'), self.joint.margSumIn(["D"])) self.ie.eraseAllTargets() self.ie.addTarget("A") self.ie.addTarget("F") self.ie.addEvidence("B", 2) self.ie.addEvidence("D", [0.2, 0.6, 0.6]) self.ie.makeInference() posterior_joint = self.joint * \ gum.Potential().add(self.bn.variable("B")).fillWith([0, 0, 1]) * \ gum.Potential().add(self.bn.variable("D")).fillWith([0.2, 0.6, 0.6]) self.assertEqual( gum.getPosterior(self.bn, { 1: 2, "D": [0.2, 0.6, 0.6] }, "A"), posterior_joint.margSumIn(["A"]).normalize()) self.assertEqual( gum.getPosterior(self.bn, { "B": 2, 3: [0.2, 0.6, 0.6] }, "F"), posterior_joint.margSumIn(["F"]).normalize())
def testReorganizePotentialWithAccents(self): if sys.version_info >= (3, 0): a, b, c, d = [gum.LabelizedVariable(s, s, 3) for s in "éèàû"] p = gum.Potential() p.add(a).add(b) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) q = gum.Potential() q.add(c).add(d) q.fillWith([4, 5, 6, 3, 2, 1, 4, 3, 2]) self.assertNotEqual(str(p * q), str(q * p)) self.assertEqual( str(p * q), str((q * p).reorganize(['à', 'û', 'é', 'è']))) self.assertNotEqual( str(p * q), str((q * p).reorganize(['à', 'é', 'û', 'è']))) try: q.reorganize(['é']) self.assertTrue(False) except gum.InvalidArgument: self.assertTrue(True) try: q.reorganize(['û']) self.assertTrue(False) except gum.InvalidArgument: self.assertTrue(True)
def testInsertion(self): mn = gum.MarkovNet() self._fill(mn) with self.assertRaises(gum.InvalidArgument): mn.addFactor(gum.Potential()) # no empty factor with self.assertRaises(gum.InvalidArgument): mn.addFactor({"11", "31"}) # already exist mn1 = gum.MarkovNet() self._fill(mn1) pot = gum.Potential().add(mn1.variable("11")).add(mn1.variable("21")) pot.randomDistribution() mn1.addFactor(pot) self.assertEqual(pot.__str__(), mn1.factor({"11", "21"}).__str__()) mn1 = gum.MarkovNet() self._fill(mn1) pot = gum.Potential().add(mn1.variable("21")).add(mn1.variable("11")) pot.randomDistribution() mn1.addFactor(pot) # should be equal : does not depend of the order of vars in the MarkonNet self.assertEqual(pot.__str__(), mn1.factor({"11", "21"}).__str__()) # but the data should be the same I = gum.Instantiation(pot) factor = mn1.factor({"21", "11"}) I.setFirst() while not I.end(): self.assertAlmostEqual(pot.get(I), factor.get(I), places=7) I.inc()
def testReorganizePotential(self): a, b, c, d = [gum.LabelizedVariable(s, s, 3) for s in "abcd"] p = gum.Potential() p.add(a).add(b) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) q = gum.Potential() q.add(c).add(d) q.fillWith([4, 5, 6, 3, 2, 1, 4, 3, 2]) self.assertNotEqual(str(p * q), str(q * p)) self.assertEqual(str(p * q), str((q * p).reorganize(['c', 'd', 'a', 'b']))) self.assertNotEqual( str(p * q), str((q * p).reorganize(['c', 'a', 'd', 'b']))) try: q.reorganize(['a']) self.assertTrue(False) except gum.InvalidArgument: self.assertTrue(True) try: q.reorganize(['d']) self.assertTrue(False) except gum.InvalidArgument: self.assertTrue(True)
def testMargOutOperators(self): a, b, c, d = [gum.LabelizedVariable(s, s, 3) for s in "abcd"] p = gum.Potential() p.add(a).add(b) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) p.normalize() q = gum.Potential() q.add(c).add(d) q.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) q.normalize() joint = p * q margAB = joint.margSumOut(["c", "d"]) self.assertEqual(margAB.names, p.names) self.assertEqual(margAB.tolist(), p.tolist()) margCD = joint.margSumOut( ["b", "a", "x"]) # note the vars in a different order and with one not present in the potential self.assertEqual(margCD.names, q.names) self.assertEqual(margCD.tolist(), q.tolist()) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) self.assertEqual(p.margProdOut(["a"]).tolist(), [6, 120, 504]) self.assertEqual(p.margProdOut(["b"]).tolist(), [28, 80, 162]) self.assertEqual(p.margMaxOut(["a"]).tolist(), [3, 6, 9]) self.assertEqual(p.margMaxOut(["b"]).tolist(), [7, 8, 9]) self.assertEqual(p.margMinOut(["a"]).tolist(), [1, 4, 7]) self.assertEqual(p.margMinOut(["b"]).tolist(), [1, 2, 3])
def testBugInferenceWithEvidenceWithSemiFastSyntax(self): tst_id = gum.InfluenceDiagram() tst_id.addVariables(["c1","c","$u","*d"]) tst_id.addArcs([("c","c1"), ("c","u"), ("d","u")]) tst_id.cpt("c").fillWith([0.5, 0.5]) tst_id.cpt("c1")[{'c': 0}] = [1, 0] tst_id.cpt("c1")[{'c': 1}] = [0, 1] tst_id.utility("u")[{'c': 0, 'd': 0}] = [10] tst_id.utility("u")[{'c': 0, 'd': 1}] = [21] tst_id.utility("u")[{'c': 1, 'd': 0}] = [100] tst_id.utility("u")[{'c': 1, 'd': 1}] = [200] ie = gum.ShaferShenoyLIMIDInference(tst_id) ie.setEvidence({'c': 0}) ie.makeInference() self.assertEqual(ie.optimalDecision("d"), gum.Potential().add(tst_id.variableFromName("d")).fillWith([0, 1])) self.assertEqual(ie.MEU()['mean'], 21) ie = gum.ShaferShenoyLIMIDInference(tst_id) ie.setEvidence({'c': 1}) ie.makeInference() self.assertEqual(ie.optimalDecision("d"), gum.Potential().add(tst_id.variableFromName("d")).fillWith([0, 1])) self.assertEqual(ie.MEU()['mean'], 200)
def testSimpleInPLaceOperators(self): a, b, c = [gum.LabelizedVariable(s, s, 3) for s in "abc"] q = gum.Potential() q.add(b).add(c) q.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) p = gum.Potential() p.add(a).add(b) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) z = p + q p += q self.assertEqual(z.tolist(), p.tolist()) p = gum.Potential() p.add(a).add(b) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) z = p - q p -= q self.assertEqual(z.tolist(), p.tolist()) p = gum.Potential() p.add(a).add(b) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) z = p * q p *= q self.assertEqual(z.tolist(), p.tolist()) p = gum.Potential() p.add(a).add(b) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) z = p / q p /= q self.assertEqual(z.tolist(), p.tolist())
def testEquality(self): a, b, c = [gum.LabelizedVariable(s, s, 3) for s in "abc"] q = gum.Potential() q.add(b).add(c) q.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) p = gum.Potential() # same data, difference dims p.add(a).add(b) p.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) r = gum.Potential() # same data, same dims r.add(a).add(b) r.fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) t = gum.Potential() # same dims, different data t.add(a).add(b) t.fillWith([1, 2, 3, 0, 5, 6, 7, 8, 9]) u = gum.Potential() # same dims, same data, different order u.add(b).add(a) u.fillWith([1, 4, 7, 2, 5, 8, 3, 6, 9]) self.assertTrue(p == p) self.assertFalse(p == q) self.assertTrue(p == r) self.assertFalse(p == t) self.assertTrue(p == u) self.assertFalse(p != p) self.assertTrue(p != q) self.assertFalse(p != r) self.assertTrue(p != t) self.assertFalse(p != u)
def testVariableInsertion(self): pot = gum.Potential() self.assertTrue(pot.empty()) pot.add(self.var['c']) self.assertFalse(pot.empty()) self.assertEqual(pot.nbrDim(), 1) pot.add(self.var['s']).add(self.var['r']) self.assertEqual(pot.nbrDim(), 3) for id, var in enumerate([self.var['c'], self.var['s'], self.var['r']]): self.assertTrue(pot.contains(var)) self.assertEqual(pot.variable(id), var) self.assertFalse(pot.contains(gum.LabelizedVariable("a", "", 5))) a = gum.LabelizedVariable("a", "a", 2) other_a = gum.LabelizedVariable("a", "a", 2) p = gum.Potential() p.add(a) with self.assertRaises(gum.DuplicateElement): p.add(a) # once again with self.assertRaises(gum.DuplicateElement): p.add(other_a) # with the same name
def __init__(self, v): """ create a particule for the variable V """ self._val = gum.Potential().add(v).fillWith(0) self._val2 = gum.Potential().add(v).fillWith(0) self._nbr = 0 self._name = [v.name()]
def testLog2Potential(self): a, b = [gum.LabelizedVariable(s, s, 2) for s in "ab"] p = gum.Potential().add(a).add(b) p.random() pp = gum.Potential(p) pp[:] = np.log2(pp[:]) self.assertTrue((p.log2() - pp).abs().max() < 1e-8)
def testIsNonZeroMap(self): a, b = [gum.LabelizedVariable(s, s, 3) for s in "ab"] p = gum.Potential() p.add(a).add(b).fillWith([1, 9, 3, 0, 5, 0, 7, 8, 9]).normalizeAsCPT() q = gum.Potential() q.add(a).add(b).fillWith([1, 1, 1, 0, 1, 0, 1, 1, 1]) self.assertTrue(p.isNonZeroMap() == q)
def testOperationWithDifferentVariablesFromMadsLindskou(self): px = gum.Potential() py = gum.Potential() for s in "ab": px.add(gum.LabelizedVariable(s, s, 2)) for s in "bc": py.add(gum.LabelizedVariable(s, s, 2))
def testInstallCPTs(self): bn = self.fill() frag = gum.BayesNetFragment(bn) frag.installAscendants("v6") self.assertEqual(frag.size(), 3) self.assertEqual(frag.sizeArcs(), 2) for nod in frag.nodes(): self.assertTrue(frag.checkConsistency(nod)) self.assertTrue(frag.checkConsistency()) frag.installNode("v5") # 1->3->6 et 3->5 but 5 does not have all this parents (2,3 et 4) with self.assertRaises(gum.NotFound): v = frag.variable("v4").name() with self.assertRaises(gum.NotFound): v = frag.variable(bn.idFromName("v2")).name() self.assertEqual(frag.size(), 4) self.assertEqual(frag.sizeArcs(), 3) self.assertTrue(not frag.checkConsistency()) self.assertTrue(not frag.checkConsistency("v5")) for nod in frag.nodes(): if frag.variable(nod).name() != "v5": self.assertTrue(frag.checkConsistency(nod)) newV5 = gum.Potential().add(frag.variable("v5")) newV5.fillWith([0, 0, 1]) frag.installMarginal("v5", newV5) for nod in frag.nodes(): self.assertTrue(frag.checkConsistency(nod)) self.assertTrue(frag.checkConsistency()) self.assertEqual(frag.size(), 4) self.assertEqual(frag.sizeArcs(), 2) frag.installAscendants("v4") self.assertTrue(not frag.checkConsistency()) self.assertEqual(frag.size(), 6) self.assertEqual(frag.sizeArcs(), 6) frag.uninstallCPT("v5") for nod in frag.nodes(): self.assertTrue(frag.checkConsistency(nod)) self.assertTrue(frag.checkConsistency()) self.assertEqual(frag.size(), 6) self.assertEqual(frag.sizeArcs(), 7) frag.uninstallNode("v4") self.assertTrue(not frag.checkConsistency()) self.assertEqual(frag.size(), 5) self.assertEqual(frag.sizeArcs(), 4) newV5bis = gum.Potential().add(frag.variable("v5")).add( frag.variable("v2")).add(frag.variable("v3")) frag.installCPT("v5", newV5bis) self.assertTrue(frag.checkConsistency()) self.assertEqual(frag.size(), 5) self.assertEqual(frag.sizeArcs(), 4)
def _computeProdLambda(self, nodeX, nodeExcept=None): varX = self._bn.variable(nodeX) if (-1, nodeX) in self._messages: lamX = gum.Potential(self._messages[-1, nodeX]) else: lamX = gum.Potential().add(varX).fillWith(1.0) for child in self._bn.children(nodeX): if child != nodeExcept: lamX = lamX * self._messages[child, nodeX] return lamX
def testSqPotential(self): a, b = [gum.LabelizedVariable(s, s, 2) for s in "ab"] p = gum.Potential().add(a).add(b).fillWith([0, 1, 2, 3]) q = gum.Potential().add(a).add(b).fillWith([0, 3, 0, 3]) self.assertEqual((p - q).sq().tolist(), [[0, 4], [4, 0]]) self.assertEqual((q - p).sq().tolist(), [[0, 4], [4, 0]]) self.assertEqual((q - p).sq().max(), 4) self.assertEqual((q - p).sq().min(), 0)
def confidence(self, pval=1.96): if self._nbr == 0: return 100 v = gum.Potential(self._val) v.scale(1.0 / self._nbr) v2 = gum.Potential(self._val2) v2.scale(1.0 / self._nbr) return pval * math.sqrt((v2 - v * v).max() / self._nbr)
def testScaleAndTranslate(self): a = gum.LabelizedVariable("a", "a", 3) p = gum.Potential().add(a) q = gum.Potential().add(a).fillWith([3, 6, 9]) r = gum.Potential().add(a).fillWith([2, 3, 4]) s = gum.Potential().add(a).fillWith([4, 7, 10]) self.assertEqual(p.fillWith([1, 2, 3]).scale(3), q) self.assertEqual(p.fillWith([1, 2, 3]).translate(1), r) self.assertEqual(p.fillWith([1, 2, 3]).scale(3).translate(1), s)
def testInverse(self): u = gum.LabelizedVariable("u", "u", 4) v = gum.LabelizedVariable("v", "v", 2) w = gum.LabelizedVariable("w", "w", 3) p = gum.Potential().add(u).add(v).add(w) p.random() q = gum.Potential(p).inverse() self.assertAlmostEqual((q * p).max(), 1.0, delta=1e-7) self.assertAlmostEqual((q * p).min(), 1.0, delta=1e-7)
def oneRound(): self._nbr += 1 currentPotentials = {} proba = {} # simple sampling w.r.t. the BN inst = {} for i in self._bn.topologicalOrder(): name = self._bn.variable(i).name() q = gum.Potential(self._bn.cpt(i)) for j in self._bn.parents(i): q *= currentPotentials[j] q = q.margSumIn([name]) inst[name], currentPotentials[i] = utils.draw(q) if name not in self._evs: proba[i] = q # forcing the value of evidence and compute the probability of this forces instance globalProba = 1.0 for i in self._bn.topologicalOrder(): name = self._bn.variable(i).name() if name in self._evs: if inst[name] != self._evs[name]: inst[name] = self._evs[name] localp = self._bn.cpt(i)[inst] if localp == 0: return False globalProba *= localp for i in proba.keys(): estimators[i].add(currentPotentials[i], globalProba) return True
def testDrawSamples(self): bn = gum.fastBN("A->B[4]->C;A->D->C;D->E[3];") dbgen = gum.BNDatabaseGenerator(bn) nbsample = 100 nbsamples = [nbsample * i for i in [1, 100, 1000]] ns1, ns2, ns3 = nbsamples isOK = False for i in range(self.nbLoopForApproximatedTest): try: ll1, ll2, ll3 = [dbgen.drawSamples(n) for n in nbsamples] self.assertAlmostEqual(ns1 / ns2, ll1 / ll2, delta=0.1) self.assertAlmostEqual(ns3 / ns2, ll3 / ll2, delta=0.1) self.assertAlmostEqual(ns1 / ns3, ll1 / ll3, delta=0.1) isOK = True break except AssertionError: pass self.assertEqual(isOK, True, " Error in loop for Approximated tests") jointe = gum.Potential().fillWith(1) for i in bn.nodes(): jointe *= bn.cpt(i) entropy = jointe.entropy() self.assertAlmostEqual(entropy, -ll1 / ns1, delta=0.5) self.assertAlmostEqual(entropy, -ll2 / ns2, delta=0.2) self.assertAlmostEqual(entropy, -ll3 / ns3, delta=0.1)
def testEntropyPotential(self): a = gum.LabelizedVariable("a", "a", 2) p = gum.Potential().add(a) self.assertEqual(p.fillWith([0, 1]).entropy(), 0.0) self.assertEqual(p.fillWith([1, 0]).entropy(), 0.0) self.assertEqual(p.fillWith([0.5, 0.5]).entropy(), 1.0)
def testExtraction(self): a, b, c = [gum.LabelizedVariable(s, s, 3) for s in "abc"] p = gum.Potential().add(a).add(b).fillWith([1, 2, 3, 4, 5, 6, 7, 8, 9]) q = gum.Potential().add(c).fillWith([1, 2, 3]) pot = q * p I = gum.Instantiation() I.add(c) I.chgVal(c, 0) self.assertEqual(pot.extract(I), p) I.chgVal(c, 2) r = gum.Potential().add(a).add(b).fillWith( [3, 6, 9, 12, 15, 18, 21, 24, 27]) self.assertEqual(pot.reorganize(['b', 'c', 'a']).extract(I), r)
def draw(p): """ Draw a sample using p :param p: the distribution :return: (v,q) where v is the value and q is the deterministic distribution for v """ q = gum.Potential(p) r = random.random() i = gum.Instantiation(p) val = 0 while not i.end(): if r < 0: q.set(i, 0) else: if r <= p.get(i): val = i.val(0) q.set(i, 1) else: q.set(i, 0) r -= p.get(i) i.inc() if q.sum() != 1: print("ACHTUNG : {} {}".format(p.sum(), p)) print("AND THEN : {}".format(q)) return val,q
def oneRound(): self._nbr += 1 currentPotentials = {} proba = {} # simple sampling w.r.t. the samplerBN inst = dict(self._originalEvs) probaQ = 1.0 probaP = 1.0 for i in self._samplerBN.topologicalOrder(): name = self._samplerBN.variable(i).name() q = gum.Potential(self._samplerBN.cpt(i)) for j in self._samplerBN.parents(i): q *= currentPotentials[j] q = q.margSumIn([name]) inst[name], currentPotentials[i] = utils.draw(q) if name not in self._evs: proba[i] = q probaQ *= self._samplerBN.cpt(name)[inst] probaP *= self._bn.cpt(name)[inst] for name in self._bn.names(): if name not in self._samplerBN.names( ): # variable that have disappeared in sampler_bn probaP *= self._bn.cpt(name)[inst] if probaP == 0: return False # rejet for i in proba.keys(): estimators[i].add(currentPotentials[i], probaP / probaQ) return True
def testInferenceWithLocalsCPT(self): bn = self.fill() bn2 = self.fill2(bn) frag = gum.BayesNetFragment(bn) for i in bn.nodes(): frag.installNode(i) self.assertTrue(frag.checkConsistency()) self.assertEqual(frag.size(), 6) self.assertEqual(frag.sizeArcs(), 7) newV5 = gum.Potential().add(frag.variable("v5")).add( frag.variable("v2")).add(frag.variable("v3")) newV5.fillWith(bn2.cpt("v5")) frag.installCPT("v5", newV5) self.assertTrue(frag.checkConsistency()) self.assertEqual(frag.size(), 6) self.assertEqual(frag.sizeArcs(), 6) ie2 = gum.LazyPropagation(bn2) ie2.makeInference() ie = gum.LazyPropagation(frag) ie.makeInference() for n in frag.names(): for x1, x2 in zip( ie2.posterior(n).tolist(), ie.posterior(n).tolist()): self.assertAlmostEqual(x1, x2, delta=1e-5, msg="For variable '{}'".format(n))
def read_file(filename): """ Renvoie les variables aléatoires et la probabilité contenues dans le fichier dont le nom est passé en argument. """ Pjointe = gum.Potential() variables = [] fic = open(filename, 'r') # on rajoute les variables dans le potentiel nb_vars = int(fic.readline()) for i in range(nb_vars): name, domsize = fic.readline().split() variable = gum.LabelizedVariable(name, name, int(domsize)) variables.append(variable) Pjointe.add(variable) # on rajoute les valeurs de proba dans le potentiel cpt = [] for line in fic: cpt.append(float(line)) Pjointe.fillWith(np.array(cpt)) fic.close() return np.array(variables), Pjointe