[pyAgrum] new methods Instantiation.fromdict and Instantiation.todict

parent 043933dd
......@@ -95,10 +95,7 @@ namespace gum {
template < typename GUM_SCALAR >
void GibbsKL< GUM_SCALAR >::_computeKL() {
gum::Instantiation Iq;
_q.completeInstantiation(Iq);
auto Iq = _q.completeInstantiation();
gum::Instantiation I = this->monteCarloSample();
initApproximationScheme();
......@@ -175,9 +172,13 @@ namespace gum {
_bhattacharya = -std::log(_bhattacharya);
}
template<typename GUM_SCALAR>
void GibbsKL<GUM_SCALAR>::setBurnIn(Size b) { this->_burn_in = b; }
template < typename GUM_SCALAR >
void GibbsKL< GUM_SCALAR >::setBurnIn(Size b) {
this->_burn_in = b;
}
template<typename GUM_SCALAR>
Size GibbsKL<GUM_SCALAR>::burnIn() const { return this->_burn_in; }
template < typename GUM_SCALAR >
Size GibbsKL< GUM_SCALAR >::burnIn() const {
return this->_burn_in;
}
}
......@@ -54,10 +54,8 @@ namespace gum {
_klPQ = _klQP = _hellinger = _bhattacharya = (GUM_SCALAR)0.0;
_errorPQ = _errorQP = 0;
gum::Instantiation Ip;
_p.completeInstantiation(Ip);
gum::Instantiation Iq;
_q.completeInstantiation(Iq);
auto Ip = _p.completeInstantiation();
auto Iq = _q.completeInstantiation();
// map between _p variables and _q variables (using name of vars)
HashTable< const DiscreteVariable*, const DiscreteVariable* > map;
......
......@@ -138,7 +138,7 @@ namespace gum {
variableFromName(const std::string& name) const = 0;
/// Get an instantiation over all the variables of the model
virtual void completeInstantiation(Instantiation& I) const;
virtual Instantiation completeInstantiation() const final;
/// @}
/// @name Arc manipulation methods.
......
......@@ -85,11 +85,13 @@ namespace gum {
}
INLINE
void DAGmodel::completeInstantiation(Instantiation& I) const {
I.clear();
Instantiation DAGmodel::completeInstantiation() const {
Instantiation I;
for (const auto node : dag())
I << variable(node);
return I;
}
INLINE
......
......@@ -229,6 +229,7 @@ namespace gum {
* @param v The new variable added to this Instantiation.
*
* @throw DuplicateElement Raised if v is already in this Instantiation.
* @throw InvalidArgument Raised if the name of v is already used in this Instantiation.
* @throw OperationNotAllowed Raised if this is a slave Instantiation.
*/
void add(const DiscreteVariable& v) override;
......
......@@ -137,7 +137,16 @@ namespace gum {
// check if the variable already belongs to the tuple of variables
// of the Instantiation
if (__vars.exists(&v)) {
GUM_ERROR(DuplicateElement, "Var already exists in this instantiation");
GUM_ERROR(DuplicateElement,
"Var <" << v.name() << "> already exists in this instantiation");
}
for (const auto& vv : __vars) {
if (vv->name() == v.name()) {
GUM_ERROR(InvalidArgument,
"Var with name <" << v.name()
<< "> already exists in this instantiation");
}
}
// actually add the new dimension
......
......@@ -230,8 +230,7 @@ namespace gum_tests {
gum::Size((2 * (3 - 1)) + (2 * (2 - 1)) + (2 - 1)));
TS_ASSERT_DELTA(pow(10, frag.log10DomainSize()), 2 * 2 * 3, 1e-5);
gum::Instantiation I;
frag.completeInstantiation(I);
auto I = frag.completeInstantiation();
I.setFirst();
TS_ASSERT_EQUALS(I.toString(), "<v1:0|v3:0|v6:0>");
......
......@@ -137,7 +137,7 @@ namespace gum_tests {
delete var5;
}
void /*test*/Constructor() {
void /*test*/ Constructor() {
gum::BayesNet< float >* topology = nullptr;
TS_GUM_ASSERT_THROWS_NOTHING(topology = new gum::BayesNet< float >());
TS_ASSERT_EQUALS(topology->size(), (gum::Idx)0);
......@@ -160,7 +160,7 @@ namespace gum_tests {
TS_GUM_ASSERT_THROWS_NOTHING(delete topology);
}
void /*test*/CopyConstructor() {
void /*test*/ CopyConstructor() {
gum::BayesNet< float > source;
gum::List< gum::NodeId > idList;
TS_GUM_ASSERT_THROWS_NOTHING(fill(source, idList));
......@@ -214,7 +214,7 @@ namespace gum_tests {
}
}
void /*test*/CopyOperator() {
void /*test*/ CopyOperator() {
gum::BayesNet< float > source;
gum::BayesNet< float > copy;
gum::List< gum::NodeId > idList;
......@@ -278,7 +278,7 @@ namespace gum_tests {
}
}
void /*test*/Insertion_1() {
void /*test*/ Insertion_1() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -317,7 +317,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(*((gum::LabelizedVariable*)&bn.variable(idList[4])), *var5);
}
void /*test*/Insertion_2() {
void /*test*/ Insertion_2() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -342,7 +342,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(*((gum::LabelizedVariable*)&bn.variable(idList[4])), *var5);
}
void /*test*/Iterations() {
void /*test*/ Iterations() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
TS_GUM_ASSERT_THROWS_NOTHING(fill(bn, idList));
......@@ -365,7 +365,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(cpt, bn.sizeArcs());
}
void /*test*/ArcInsertion() {
void /*test*/ ArcInsertion() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -385,7 +385,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(bn.dag().sizeArcs(), (gum::Size)6);
}
void /*test*/EraseVar() {
void /*test*/ EraseVar() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -426,7 +426,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(bn.dag().sizeArcs(), (gum::Size)6);
}
void /*test*/EraseArc() {
void /*test*/ EraseArc() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -453,7 +453,7 @@ namespace gum_tests {
TS_ASSERT(bn.dag().emptyArcs());
}
void /*test*/StringAccessors() {
void /*test*/ StringAccessors() {
gum::BayesNet< float > bn;
for (const auto& x : {"A", "B", "C"}) {
bn.add(gum::LabelizedVariable(x, x, 2));
......@@ -499,7 +499,7 @@ namespace gum_tests {
}
void /*test*/Iterator() {
void /*test*/ Iterator() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -508,7 +508,7 @@ namespace gum_tests {
}
}
void /*test*/RandomlyFilled() {
void /*test*/ RandomlyFilled() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -524,7 +524,7 @@ namespace gum_tests {
}
}
void /*test*/MoralGraph() {
void /*test*/ MoralGraph() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -535,7 +535,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(graph, getRealMoralGraph(bn, idList));
}
void /*test*/TopologicalOrder() {
void /*test*/ TopologicalOrder() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -547,7 +547,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(topoOrder.size(), (gum::Size)5);
}
void /*test*/cpt() {
void /*test*/ cpt() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -559,7 +559,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(bn.cpt(idList[4]).domainSize(), (gum::Size)24);
}
void /*test*/CPTCoherencyVarRemoval() {
void /*test*/ CPTCoherencyVarRemoval() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -594,7 +594,7 @@ namespace gum_tests {
TS_ASSERT(bn.cpt(idList[3]).contains(bn.variable(idList[3])));
}
void /*test*/CPTCoherencyArcRemoval() {
void /*test*/ CPTCoherencyArcRemoval() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -628,7 +628,7 @@ namespace gum_tests {
TS_ASSERT(bn.cpt(idList[3]).contains(bn.variable(idList[3])));
}
void /*test*/StreamOperator() {
void /*test*/ StreamOperator() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -637,7 +637,7 @@ namespace gum_tests {
TS_GUM_ASSERT_THROWS_NOTHING(sBuff << bn);
}
void /*test*/AccessorByName() {
void /*test*/ AccessorByName() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
......@@ -658,7 +658,7 @@ namespace gum_tests {
TS_ASSERT_THROWS(bn.idFromName("var1"), gum::NotFound);
}
void /*test*/CopyAndEqualityOperators() {
void /*test*/ CopyAndEqualityOperators() {
gum::BayesNet< float >* bn_1 = new gum::BayesNet< float >();
gum::SimpleBayesNetGenerator< float > generator(20, 30, 4);
generator.generateBN(*bn_1);
......@@ -711,7 +711,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(s1, s2);
}
void /*test*/AggregatorNodes() {
void /*test*/ AggregatorNodes() {
{
gum::BayesNet< float > bn;
gum::Idx i1 = 0;
......@@ -736,14 +736,13 @@ namespace gum_tests {
}
}
void /*test*/JointProbability() {
void /*test*/ JointProbability() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
fill(bn, idList);
gum::Instantiation i;
bn.completeInstantiation(i);
auto i = bn.completeInstantiation();
TS_ASSERT_EQUALS(i.nbrDim(), bn.size());
TS_ASSERT_EQUALS(i.domainSize(), (gum::Size)(2 * 2 * 2 * 2 * 3));
......@@ -764,15 +763,14 @@ namespace gum_tests {
TS_ASSERT_EQUALS(a, b);
}
void /*test*/ArcReversal() {
void /*test*/ ArcReversal() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
fill(bn, idList);
std::vector< float > joint;
joint.reserve(2 * bn.dim());
gum::Instantiation i;
bn.completeInstantiation(i);
auto i = bn.completeInstantiation();
for (i.setFirst(); !i.end(); i.inc()) {
joint.push_back(bn.jointProbability(i));
......@@ -792,7 +790,7 @@ namespace gum_tests {
}
}
void /*test*/ChangeLabelOfVariable() {
void /*test*/ ChangeLabelOfVariable() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
fill(bn, idList);
......@@ -804,7 +802,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(bn.variable(0).toString(), "var1<x,1>");
}
void /*test*/ShortCutAddLabelized() {
void /*test*/ ShortCutAddLabelized() {
gum::BayesNet< float > bn;
gum::NodeId i1, i2, i3;
......@@ -822,7 +820,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(bn.log10DomainSize(), std::log10(2.0 * 3.0));
}
void /*test*/SomeFunctions() {
void /*test*/ SomeFunctions() {
gum::BayesNet< float > bn;
gum::List< gum::NodeId > idList;
TS_GUM_ASSERT_THROWS_NOTHING(fill(bn, idList));
......@@ -834,7 +832,7 @@ namespace gum_tests {
TS_ASSERT_EQUALS(bn.maxNonOneParam(), 0.9f);
}
void /*test*/MinimalCondSet() {
void /*test*/ MinimalCondSet() {
/*
A B 0 1
\ / \ \ / \
......@@ -884,7 +882,7 @@ namespace gum_tests {
gum::NodeSet({b, c, f, h}));
}
void /*test*/MinimalCondSet2() {
void /*test*/ MinimalCondSet2() {
/*
F A
\ / \
......
......@@ -15,10 +15,10 @@ double
"
Get an instantiation over all the variables of the model.
Parameters
Returns
----------
i : pyAgrum.instantiation
the instantiation to complete
pyAgrum.instantiation
the complete instantiation
"
%feature("docstring") gum::DAGmodel::dag
......@@ -47,7 +47,7 @@ pyAgrum.DAGmodel
Returns
-------
bool
True if all the named node are the same and all the named arcs are the same
True if all the named node are the same and all the named arcs are the same
"
%feature("docstring") gum::DAGmodel::size
......@@ -122,7 +122,7 @@ list
Returns
-------
str
a friendly display of the graph in DOT format
a friendly display of the graph in DOT format
"
%feature("docstring") gum::DAGmodel::idFromName
......@@ -137,7 +137,7 @@ name : str
Returns
-------
int :
The variable's node id.
The variable's node id.
Warnings
--------
......
......@@ -33,7 +33,7 @@ Instantiation is subscriptable therefore values can be easily accessed/modified.
Examples
--------
>>> ## Access the value of A in an instantiation aI
>>> ## Access the value of A in an instantiation aI
>>> valueOfA = aI['A']
>>> ## Modify the value
>>> aI['A'] = newValueOfA
......@@ -454,3 +454,29 @@ Returns
List
the sequence of DiscreteVariable of this instantiation.
"
%feature("docstring") gum::Instantiation::todict
"
Create a dict (variable_name:value) from an instantiation
Parameters
----------
withLabels : boolean
The value will be a label (string) if True. It will be a position (int) if False.
Returns
-------
Dict
The dictionary
"
%feature("docstring") gum::Instantiation::fromdict
"
Change the values in an instantiation from a dict (variable_name:value) where value can be a position (int) or a label (string).
If a variable_name does not occur in the instantiation, nothing is done.
Warnings
--------
OutOfBounds raised if a value cannot be found.
"
......@@ -129,13 +129,14 @@ namespace PyAgrumHelper {
void fillInstantiationFromPyObject(const gum::Potential< double >* pot,
gum::Instantiation& inst,
PyObject* dict) {
if (!PyDict_Check(dict)) {
GUM_ERROR(gum::InvalidArgument, "Argument is not a dictionary");
}
gum::HashTable< std::string, const gum::DiscreteVariable* > namesToVars;
for (gum::Idx i = 0; i < pot->nbrDim(); i++)
namesToVars.insert(pot->variable(i).name(), &(pot->variable(i)));
if (!PyDict_Check(dict)) {
GUM_ERROR(gum::InvalidArgument, "Argument is not a dictionnary");
}
PyObject * key, *value;
Py_ssize_t pos = 0;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -6267,7 +6267,7 @@ class Instantiation(_object):
Examples
--------
>>> ## Access the value of A in an instantiation aI
>>> ## Access the value of A in an instantiation aI
>>> valueOfA = aI['A']
>>> ## Modify the value
>>> aI['A'] = newValueOfA
......@@ -6987,6 +6987,45 @@ class Instantiation(_object):
return _pyAgrum.Instantiation___str__(self)
def todict(self, withLabels: 'bool'=False) -> "PyObject *":
"""
todict(self, withLabels=False) -> PyObject
todict(self) -> PyObject *
Create a dict (variable_name:value) from an instantiation
Parameters
----------
withLabels : boolean
The value will be a label (string) if True. It will be a position (int) if False.
Returns
-------
Dict
The dictionary
"""
return _pyAgrum.Instantiation_todict(self, withLabels)
def fromdict(self, dict: 'PyObject *') -> "void":
"""
fromdict(self, dict)
Change the values in an instantiation from a dict (variable_name:value) where value can be a position (int) or a label (string).
If a variable_name does not occur in the instantiation, nothing is done.
Warnings
--------
OutOfBounds raised if a value cannot be found.
"""
return _pyAgrum.Instantiation_fromdict(self, dict)
def __setitem__(self,key,item):
self.chgVal(key,item)
......@@ -7193,7 +7232,7 @@ class DAGmodel(_object):
Returns
-------
int :
The variable's node id.
The variable's node id.
Warnings
--------
......@@ -7226,20 +7265,20 @@ class DAGmodel(_object):
return _pyAgrum.DAGmodel_variableFromName(self, name)
def completeInstantiation(self, I: 'Instantiation') -> "void":
def completeInstantiation(self) -> "gum::Instantiation":
"""
completeInstantiation(self, I)
completeInstantiation(self) -> Instantiation
Get an instantiation over all the variables of the model.
Parameters
Returns
----------
i : pyAgrum.instantiation
the instantiation to complete
pyAgrum.instantiation
the complete instantiation
"""
return _pyAgrum.DAGmodel_completeInstantiation(self, I)
return _pyAgrum.DAGmodel_completeInstantiation(self)
def arcs(self) -> "gum::ArcSet const &":
......@@ -7335,7 +7374,7 @@ class DAGmodel(_object):
Returns
-------
bool
True if all the named node are the same and all the named arcs are the same
True if all the named node are the same and all the named arcs are the same
"""
return _pyAgrum.DAGmodel_hasSameStructure(self, other)
......@@ -10018,7 +10057,7 @@ class IBayesNet_double(DAGmodel):
Returns
-------
int :
The variable's node id.
The variable's node id.
Warnings
--------
......@@ -10657,7 +10696,7 @@ class BayesNet_double(IBayesNet_double):
Returns
-------
int :
The variable's node id.
The variable's node id.
Warnings
--------
......
%extend gum::Instantiation {
PyObject* todict(bool withLabels=false) const {
auto res=PyDict_New();
for(gum::Idx i=0;i<self->nbrDim();i++) {
auto key=PyString_FromString(self->variable(i).name().c_str());
PyObject* val;
if (withLabels) {
val=PyString_FromString(self->variable(i).label(self->val(i)).c_str());
} else {
val=PyLong_FromUnsignedLong(self->val(i));
}
PyDict_SetItem(res,key,val);
}
return res;
}
void fromdict(PyObject* dict) {
if (!PyDict_Check(dict)) {
GUM_ERROR(gum::InvalidArgument, "Argument is not a dictionary");
}
gum::HashTable< std::string, const gum::DiscreteVariable* > namesToVars;
for (gum::Idx i = 0; i < self->nbrDim(); i++)
namesToVars.insert(self->variable(i).name(), &(self->variable(i)));
PyObject *key, *value;
Py_ssize_t pos = 0;
while (PyDict_Next(dict, &pos, &key, &value)) {
std::string name = PyAgrumHelper::stringFromPyObject(key);
gum::Idx v;
if (name == "") {
GUM_ERROR(gum::InvalidArgument, "A key is not a string");
}
if (namesToVars.exists(name)) {
if (!PyInt_Check(value)) {
std::string label = PyAgrumHelper::stringFromPyObject(value);
if (label == "") {
GUM_ERROR(gum::InvalidArgument,
"A value is neither an int or a string");
}
v = namesToVars[name]->index(label); // may throw gum::OutOfBounds
} else {
v = gum::Idx(PyInt_AsLong(value));
}
if (v >= namesToVars[name]->domainSize()) {
GUM_ERROR(gum::InvalidArgument,
"The value " << v << " is not in the domain of " << name);
}
self->chgVal(namesToVars[name], v);
}
}
}
%pythoncode {
def __setitem__(self,key,item):
self.chgVal(key,item)
......
......@@ -88,8 +88,7 @@ def computeScores(bn_name, csv_name, visible=False, transforme_label=None):
if positions is None:
sys.exit(1)
inst = gum.Instantiation()
bn.completeInstantiation(inst)
inst = bn.completeInstantiation()
if visible:
prog = ProgressBar(csv_name + ' : ', 0, nbr_lines, 77, mode='static', char='#')
......
......@@ -17,7 +17,7 @@ for cde in sys.argv:
testNotebooks = (cde == "all")
print("+ Mode detected : " + mod)
print("+ Testing notebooks : "+str(testNotebooks))
print("+ Testing notebooks : " + str(testNotebooks))
if mod != "standalone":
if mod == "debug":
......
......@@ -80,9 +80,9 @@ class IncrementalLazyPropagationTestCase(pyAgrumTestCase):
raise (NotImplementedError("This class is a generic class for Incremental Inference"))
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.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")
......@@ -97,8 +97,10 @@ class IncrementalLazyPropagationTestCase(pyAgrumTestCase):
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())
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 testPrior(self):
self.assertEqual(self.ie.posterior("A"), self.joint.margSumIn(["A"]))
......
......@@ -91,7 +91,7 @@ class BNLearnerCSVTestCase(pyAgrumTestCase):
bn2 = learner.learnParameters(bn)
for i in range(bn.size()):
#self.assertEquals(str(bn2.variable(i)), str(bn.variable(bn.idFromName(bn2.variable(i).name()))))
# self.assertEquals(str(bn2.variable(i)), str(bn.variable(bn.idFromName(bn2.variable(i).name()))))
self.assertEquals(set(bn2.variable(i).labels()), set(
bn.variable(bn.idFromName(bn2.variable(i).name())).labels()))
......@@ -105,16 +105,16 @@ class BNLearnerCSVTestCase(pyAgrumTestCase):
def testDBNTonda(self):
dbn = gum.BayesNet()
l = [dbn.add(gum.LabelizedVariable(name, name, nbr)) for (name, nbr) in [
("bf_0", 4),
("bf_t", 4),
("c_0", 5),
("c_t", 5),
("h_0", 5),
("h_t", 5),
("tf_0", 5),
("tf_t", 5),