78 template < GUM_Numeric GUM_SCALAR >
80 std::string_view node,
81 std::string_view default_domain) {
86 else res = bn.
add(*v);
90 template < GUM_Numeric GUM_SCALAR >
93 return fastPrototype(dotlike,
"[" + std::to_string(domainSize) +
"]");
96 template < GUM_Numeric GUM_SCALAR >
98 std::string_view domain) {
101 auto resolve = [&](
const std::string& node) {
return build_node(bn, node, domain); };
103 auto addEdge = [&](
NodeId,
NodeId,
const std::string& token) {
105 "fastPrototype: '" << token <<
"' is preceded by '-' but a BayesNet "
106 <<
"does not support edges")
111 fastGraphWalkTokens(fastGraphTokenize(chaine), dotlike, resolve,
addArc, addEdge);
118 template < GUM_Numeric GUM_SCALAR >
123 template < GUM_Numeric GUM_SCALAR >
128 template < GUM_Numeric GUM_SCALAR >
136 template < GUM_Numeric GUM_SCALAR >
142 template < GUM_Numeric GUM_SCALAR >
144 if (
this != &source) {
154 template < GUM_Numeric GUM_SCALAR >
156 if (
this != &source) {
165 template < GUM_Numeric GUM_SCALAR >
173 template < GUM_Numeric GUM_SCALAR >
178 template < GUM_Numeric GUM_SCALAR >
180 std::string_view old_label,
181 std::string_view new_label) {
186 if (var ==
nullptr)
GUM_ERROR(
TypeError,
"Variable " <<
id <<
" is not a LabelizedVariable.")
188 var->
changeLabel(var->posLabel(old_label), new_label);
191 template < GUM_Numeric GUM_SCALAR >
195 return add(var, ptr);
202 template < GUM_Numeric GUM_SCALAR >
204 unsigned int default_nbrmod) {
210 template < GUM_Numeric GUM_SCALAR >
215 return add(var, aContent, proposedId);
218 template < GUM_Numeric GUM_SCALAR >
223 return add(var, ptr,
id);
230 template < GUM_Numeric GUM_SCALAR >
235 this->
dag_.addNodeWithId(
id);
237 auto cpt =
new Tensor< GUM_SCALAR >(aContent);
243 template < GUM_Numeric GUM_SCALAR >
248 template < GUM_Numeric GUM_SCALAR >
253 template < GUM_Numeric GUM_SCALAR >
255 if (this->
varMap_.exists(varId)) {
265 this->
dag_.eraseNode(varId);
269 template < GUM_Numeric GUM_SCALAR >
271 if (!this->
empty()) {
272 auto l = this->
nodes();
273 for (
const auto no: l) {
279 template < GUM_Numeric GUM_SCALAR >
281 if (this->
dag_.existsArc(tail, head)) {
285 this->
dag_.addArc(tail, head);
290 template < GUM_Numeric GUM_SCALAR >
299 template < GUM_Numeric GUM_SCALAR >
301 if (this->
varMap_.exists(arc.
tail()) && this->varMap_.exists(arc.
head())) {
304 this->
dag_.eraseArc(arc);
310 template < GUM_Numeric GUM_SCALAR >
315 template < GUM_Numeric GUM_SCALAR >
318 if (!this->
varMap_.exists(arc.
tail()) || !this->varMap_.exists(arc.
head())
338 Tensor< GUM_SCALAR > prod{
cpt(tail) *
cpt(head)};
346 for (
const auto node: this->
parents(head))
352 for (
const auto p: new_parents) {
358 new_parents.erase(tail);
360 for (
const auto p: new_parents) {
364 endTopologyTransformation();
368 del_vars << &(variable(tail));
369 Tensor< GUM_SCALAR > new_cpt_head = prod.sumOut(del_vars).putFirst(&variable(head));
371 auto& cpt_head =
const_cast< Tensor< GUM_SCALAR >&
>(cpt(head));
372 cpt_head = std::move(new_cpt_head);
374 Tensor< GUM_SCALAR > new_cpt_tail{(prod / cpt_head).putFirst(&variable(tail))};
376 cpt_tail = std::move(new_cpt_tail);
379 template < GUM_Numeric GUM_SCALAR >
387 template < GUM_Numeric GUM_SCALAR >
392 template < GUM_Numeric GUM_SCALAR >
399 template < GUM_Numeric GUM_SCALAR >
404 template < GUM_Numeric GUM_SCALAR >
411 template < GUM_Numeric GUM_SCALAR >
418 template < GUM_Numeric GUM_SCALAR >
423 template < GUM_Numeric GUM_SCALAR >
428 template < GUM_Numeric GUM_SCALAR >
433 template < GUM_Numeric GUM_SCALAR >
440 template < GUM_Numeric GUM_SCALAR >
445 template < GUM_Numeric GUM_SCALAR >
449 const std::string type =
toLower(aggregatorType);
450 if (type ==
"and")
return addAND(var);
451 if (type ==
"or")
return addOR(var);
453 if (type ==
"count")
return addCOUNT(var, value);
454 if (type ==
"exists")
return addEXISTS(var, value);
455 if (type ==
"forall")
return addFORALL(var, value);
456 if (type ==
"max")
return addMAX(var);
457 if (type ==
"median")
return addMEDIAN(var);
458 if (type ==
"min")
return addMIN(var);
459 if (type ==
"sum")
return addSUM(var);
466 template < GUM_Numeric GUM_SCALAR >
468 GUM_SCALAR external_weight) {
472 template < GUM_Numeric GUM_SCALAR >
474 GUM_SCALAR external_weight) {
478 template < GUM_Numeric GUM_SCALAR >
480 GUM_SCALAR external_weight) {
484 template < GUM_Numeric GUM_SCALAR >
486 GUM_SCALAR external_weight) {
490 template < GUM_Numeric GUM_SCALAR >
495 template < GUM_Numeric GUM_SCALAR >
498 GUM_SCALAR externalWeight) {
499 if (iciType ==
"MultiDimNoisyORCompound")
return addNoisyORCompound(var, externalWeight);
500 if (iciType ==
"MultiDimNoisyORNet")
return addNoisyORNet(var, externalWeight);
501 if (iciType ==
"MultiDimNoisyAND")
return addNoisyAND(var, externalWeight);
502 if (iciType ==
"MultiDimLogit")
return addLogit(var, externalWeight);
506 template < GUM_Numeric GUM_SCALAR >
508 GUM_SCALAR external_weight,
513 template < GUM_Numeric GUM_SCALAR >
515 GUM_SCALAR external_weight,
520 template < GUM_Numeric GUM_SCALAR >
522 GUM_SCALAR external_weight,
527 template < GUM_Numeric GUM_SCALAR >
529 GUM_SCALAR external_weight,
534 template < GUM_Numeric GUM_SCALAR >
536 GUM_SCALAR external_weight,
541 template < GUM_Numeric GUM_SCALAR >
548 CImodel->causalWeight(
variable(tail), causalWeight);
551 "Head variable (" <<
variable(head).name() <<
") is not a CIModel variable !")
555 template < GUM_Numeric GUM_SCALAR >
556 std::ostream&
operator<<(std::ostream& output,
const BayesNet< GUM_SCALAR >& bn) {
557 output << bn.toString();
562 template < GUM_Numeric GUM_SCALAR >
564 for (
const auto node:
nodes())
569 template < GUM_Numeric GUM_SCALAR >
571 for (
const auto node:
nodes())
576 template < GUM_Numeric GUM_SCALAR >
587 template < GUM_Numeric GUM_SCALAR >
591 for (
const auto& src: source._probaMap_) {
593 auto copy_array =
new Tensor< GUM_SCALAR >();
594 copy_array->beginMultipleChanges();
595 for (
gum::Idx i = 0; i < src.second->nbrDim(); i++) {
598 copy_array->endMultipleChanges();
599 copy_array->copyFrom(*(src.second));
602 _probaMap_.insert(src.first, copy_array);
606 template < GUM_Numeric GUM_SCALAR >
608 for (
const auto node:
nodes())
612 template < GUM_Numeric GUM_SCALAR >
619 template < GUM_Numeric GUM_SCALAR >
621 if (
cpt(
id).nbrDim() != newPot->nbrDim()) {
623 "cannot exchange tensors with different "
624 "dimensions for variable with id "
628 for (
Idx i = 0; i < cpt(
id).nbrDim(); i++) {
629 if (&cpt(
id).variable(i) != &(newPot->variable(i))) {
631 "cannot exchange tensors because, for variable with id " <<
id <<
", dimension "
632 << i <<
" differs. ")
636 _unsafeChangeTensor_(
id, newPot);
639 template < GUM_Numeric GUM_SCALAR >
645 template < GUM_Numeric GUM_SCALAR >
650 template < GUM_Numeric GUM_SCALAR >
651 BayesNet< GUM_SCALAR >
658 "Cannot have both an observation and an intervention on the same variable")
672 bn.beginTopologyTransformation();
674 const std::string& nam = observations.
variable(i).
name();
677 bn.eraseArc(bn.idFromName(nam), bn.idFromName(this->variable(child).name()));
681 const std::string& nam = interventions.
variable(i).
name();
684 bn.eraseArc(bn.idFromName(nam), bn.idFromName(this->variable(child).name()));
687 const auto v1 = bn.idFromName(this->variable(par).name());
688 const auto v2 = bn.idFromName(nam);
689 if (bn.existsArc(v1, v2)) bn.eraseArc(v1, v2);
691 cpt_changed.
insert(bn.idFromName(nam));
692 bn.cpt(bn.idFromName(nam))
694 interventions.
val(i)));
696 bn.endTopologyTransformation();
702 cpt_changed.
insert(child);
703 bn.cpt(bn.idFromName(this->variable(child).name()))
704 .fillWith(this->cpt(child).extract(all));
712 template < GUM_Numeric GUM_SCALAR >
717 template < GUM_Numeric GUM_SCALAR >
722 template < GUM_Numeric GUM_SCALAR >
727 template < GUM_Numeric GUM_SCALAR >
729 std::string_view new_name) {
733 template < GUM_Numeric GUM_SCALAR >
735 std::string_view old_label,
736 std::string_view new_label) {
740 template < GUM_Numeric GUM_SCALAR >
745 template < GUM_Numeric GUM_SCALAR >
750 template < GUM_Numeric GUM_SCALAR >
752 std::string_view head,
753 GUM_SCALAR causalWeight) {
757 template < GUM_Numeric GUM_SCALAR >
Class representing Bayesian networks.
virtual void eraseArc(const Arc &arc)
removes an arc from the ArcGraphPart
The base class for all directed edges.
GUM_NODISCARD NodeId head() const
returns the head of the arc
GUM_NODISCARD NodeId tail() const
returns the tail of the arc
Exception base for argument error.
Class representing a Bayesian network.
NodeId idFromName(std::string_view name) const override
Returns the NodeId of a variable given its name.
NodeId addLogit(const DiscreteVariable &var, GUM_SCALAR external_weight, NodeId id)
Add a variable, its associate node and a Logit implementation.
void eraseArc(const Arc &arc)
Removes an arc in the BN, and update head's CTP.
void endTopologyTransformation()
terminates a sequence of insertions/deletions of arcs by adjusting all CPTs dimensions.
NodeId addCOUNT(const DiscreteVariable &var, Idx value=1)
Others aggregators.
NodeId addAMPLITUDE(const DiscreteVariable &var)
Others aggregators.
static BayesNet< GUM_SCALAR > fastPrototype(std::string_view dotlike, Size domainSize)
Create a Bayesian network with a dot-like syntax which specifies:
NodeId addAND(const DiscreteVariable &var)
Add a variable, it's associate node and an AND implementation.
void beginTopologyTransformation()
When inserting/removing arcs, node CPTs change their dimension with a cost in time.
const Tensor< GUM_SCALAR > & cpt(NodeId varId) const final
Returns the CPT of a variable.
void erase(NodeId varId)
Remove a variable from the gum::BayesNet.
NodeId addMAX(const DiscreteVariable &var)
Others aggregators.
void clear()
clear the whole Bayes net *
void changeVariableLabel(NodeId id, std::string_view old_label, std::string_view new_label)
Changes a variable's label in the gum::BayesNet.
const DiscreteVariable & variable(std::string_view name) const
Returns a gum::DiscreteVariable given its name in the gum::BayesNet.
void changeTensor(NodeId id, Tensor< GUM_SCALAR > *newPot)
change the CPT associated to nodeId to newPot delete the old CPT associated to nodeId.
NodeId addEXISTS(const DiscreteVariable &var, Idx value=1)
Others aggregators.
void addWeightedArc(NodeId tail, NodeId head, GUM_SCALAR causalWeight)
Add an arc in the BN, and update arc.head's CPT.
NodeId addSUM(const DiscreteVariable &var)
Others aggregators.
BayesNet< GUM_SCALAR > contextualize(const gum::Instantiation &observations, const gum::Instantiation &interventions) const
create a contextual BN from this and a set of hard observations and hard interventions.
NodeId _addAggregator_(std::string_view aggregatorType, const DiscreteVariable &var, Idx value=1)
Generic factory for aggregator nodes, dispatching on the aggregator's name.
NodeId addNoisyORNet(const DiscreteVariable &var, GUM_SCALAR external_weight)
Add a variable, it's associate node and a gum::noisyOR implementation.
const DiscreteVariable & variableFromName(std::string_view name) const override
void _copyTensors_(const BayesNet< GUM_SCALAR > &source)
copy of tensors from a BN to another, using names of vars as ref.
NodeId addNoisyAND(const DiscreteVariable &var, GUM_SCALAR external_weight, NodeId id)
Add a variable, its associate node and a noisyAND implementation.
void addArc(NodeId tail, NodeId head)
Add an arc in the BN, and update arc.head's CPT.
NodeId addFORALL(const DiscreteVariable &var, Idx value=1)
Others aggregators.
NodeId add(const DiscreteVariable &var)
Add a variable to the gum::BayesNet.
void reverseArc(NodeId tail, NodeId head)
Reverses an arc while preserving the same joint distribution.
NodeId addMIN(const DiscreteVariable &var)
Others aggregators.
NodeId addNoisyORCompound(const DiscreteVariable &var, GUM_SCALAR external_weight)
Add a variable, it's associate node and a gum::noisyOR implementation.
NodeId addNoisyOR(const DiscreteVariable &var, GUM_SCALAR external_weight)
Add a variable, it's associate node and a gum::noisyOR implementation.
void generateCPT(NodeId node) const
randomly generate CPT for a given node in a given structure
NodeProperty< Tensor< GUM_SCALAR > * > _probaMap_
Mapping between the variable's id and their CPT.
NodeId addMEDIAN(const DiscreteVariable &var)
Others aggregators.
void changeVariableName(NodeId id, std::string_view new_name)
Changes a variable's name in the gum::BayesNet.
void _clearTensors_()
clear all tensors
NodeId addOR(const DiscreteVariable &var)
Add a variable, it's associate node and an OR implementation.
void _unsafeChangeTensor_(NodeId id, Tensor< GUM_SCALAR > *newPot)
change the CPT associated to nodeId to newPot delete the old CPT associated to nodeId.
~BayesNet() override
Destructor.
void generateCPTs() const
randomly generates CPTs for a given structure
BayesNet()
Default constructor.
NodeId _addICIModel_(std::string_view iciType, const DiscreteVariable &var, GUM_SCALAR externalWeight)
Generic factory for ICI model nodes, dispatching on the implementation's name.
BayesNet< GUM_SCALAR > & operator=(const BayesNet< GUM_SCALAR > &source)
Copy operator.
const DiscreteVariable & variable(NodeId id) const override
void addArc(NodeId tail, NodeId head) final
insert a new arc into the directed graph
DAG dag_
The DAG of this Directed Graphical Model.
bool existsArc(const NodeId tail, const NodeId head) const
return true if the arc tail->head exists in the DAGmodel
DAG dag() const
Returns a named copy of the internal DAG: each node id is assigned the name of the corresponding vari...
const NodeSet & children(const NodeId id) const
returns the set of nodes with arc outgoing from a given node
bool exists(NodeId node) const final
Return true if this node exists in this graphical model.
const NodeSet & parents(const NodeId id) const
const NodeGraphPart & nodes() const final
Returns a named copy of the internal DAG: each node id is assigned the name of the corresponding vari...
Base class for discrete random variable.
virtual Size domainSize() const =0
Exception : a similar element already exists.
Base class for all aGrUM's exceptions.
void setProperty(std::string_view name, std::string_view value)
Add or change a property of this GraphicalModel.
virtual bool empty() const
Return true if this graphical model is empty.
IBayesNet()
Default constructor.
IBayesNet< GUM_SCALAR > & operator=(const IBayesNet< GUM_SCALAR > &source)
Copy operator.
Class for assigning/browsing values to tuples of discrete variables.
Instantiation & setVals(const Instantiation &i)
Assign the values from i in the Instantiation.
void add(const DiscreteVariable &v) final
Adds a new variable in the Instantiation.
bool contains(const DiscreteVariable &v) const final
Indicates whether a given variable belongs to the Instantiation.
Idx val(Idx i) const
Returns the current value of the variable at position i.
const DiscreteVariable & variable(Idx i) const final
Returns the variable at position i in the tuple.
Idx nbrDim() const final
Returns the number of variables in the Instantiation.
Exception : there is something wrong with an arc.
Exception : there is something wrong with an edge.
void changeLabel(Idx pos, std::string_view aLabel) const
change a label for this index
Multidimensional matrix stored as an array in memory.
Noisy AND representation.
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
void insert(const Key &k)
Inserts a new element into the set.
<agrum/BN/generator/simpleCPTGenerator.h>
Exception : problem with size.
aGrUM's Tensor is a multi-dimensional array with tensor operators.
static Tensor< GUM_SCALAR > deterministicTensor(const DiscreteVariable &var, Idx value)
Exception : wrong type for this operation.
const std::string & name() const
returns the name of the variable
#define GUM_ERROR(type, msg)
Builds a graph from a "fast" DOT-like textual description.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Size Idx
Type for indexes.
Size NodeId
Type for node ids.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
std::string remove_newline(std::string_view s)
remove all newlines in a string
std::string toLower(std::string_view str)
Returns the lowercase version of str.
std::vector< std::string > split(std::string_view str, std::string_view delim)
Split str using the delimiter.
class for LOGIT implementation as multiDim
class for NoisyAND-net implementation as multiDim
class for multiDimNoisyORCompound
class for NoisyOR-net implementation as multiDim
gum is the global namespace for all aGrUM entities
Set< const DiscreteVariable * > VariableSet
std::ostream & operator<<(std::ostream &stream, const AVLTree< Val, Cmp > &tree)
display the content of a tree
std::unique_ptr< DiscreteVariable > fastVariable(std::string var_description, Size default_domain_size)
Create a pointer on a Discrete Variable from a "fast" syntax.
NodeId build_node(gum::BayesNet< GUM_SCALAR > &bn, std::string_view node, std::string_view default_domain)
Abstract class for generating Conditional Probability Tables.
Utilities for manipulating strings.