aGrUM  0.21.0
a C++ library for (probabilistic) graphical models
gum::learning::Miic Class Reference

The miic learning algorithm. More...

#include <Miic.h>

+ Inheritance diagram for gum::learning::Miic:
+ Collaboration diagram for gum::learning::Miic:

Public Attributes

Signaler3< Size, double, doubleonProgress
 Progression, error and time. More...
 
Signaler1< std::string > onStop
 Criteria messageApproximationScheme. More...
 

Public Member Functions

Miicoperator= (const Miic &from)
 copy operator More...
 
Miicoperator= (Miic &&from)
 move operator More...
 
Constructors / Destructors
 Miic ()
 default constructor More...
 
 Miic (int maxLog)
 default constructor with maxLog More...
 
 Miic (const Miic &from)
 copy constructor More...
 
 Miic (Miic &&from)
 move constructor More...
 
 ~Miic () override
 destructor More...
 
Accessors / Modifiers
MixedGraph learnMixedStructure (CorrectedMutualInformation<> &mutualInformation, MixedGraph graph)
 learns the structure of an Essential Graph More...
 
DAG learnStructure (CorrectedMutualInformation<> &I, MixedGraph graph)
 learns the structure of a Bayesian network, i.e. a DAG, by first learning an Essential graph and then directing the remaining edges. More...
 
template<typename GUM_SCALAR = double, typename GRAPH_CHANGES_SELECTOR , typename PARAM_ESTIMATOR >
BayesNet< GUM_SCALAR > learnBN (GRAPH_CHANGES_SELECTOR &selector, PARAM_ESTIMATOR &estimator, DAG initial_dag=DAG())
 learns the structure and the parameters of a BN More...
 
const std::vector< ArclatentVariables () const
 get the list of arcs hiding latent variables More...
 
void setMiicBehaviour ()
 Sets the orientation phase to follow the one of the MIIC algorithm. More...
 
void set3of2Behaviour ()
 Sets the orientation phase to follow the one of the 3off2 algorithm. More...
 
void addConstraints (HashTable< std::pair< NodeId, NodeId >, char > constraints)
 Set a ensemble of constraints for the orientation phase. More...
 
Getters and setters
void setEpsilon (double eps)
 Given that we approximate f(t), stopping criterion on |f(t+1)-f(t)|. More...
 
double epsilon () const
 Returns the value of epsilon. More...
 
void disableEpsilon ()
 Disable stopping criterion on epsilon. More...
 
void enableEpsilon ()
 Enable stopping criterion on epsilon. More...
 
bool isEnabledEpsilon () const
 Returns true if stopping criterion on epsilon is enabled, false otherwise. More...
 
void setMinEpsilonRate (double rate)
 Given that we approximate f(t), stopping criterion on d/dt(|f(t+1)-f(t)|). More...
 
double minEpsilonRate () const
 Returns the value of the minimal epsilon rate. More...
 
void disableMinEpsilonRate ()
 Disable stopping criterion on epsilon rate. More...
 
void enableMinEpsilonRate ()
 Enable stopping criterion on epsilon rate. More...
 
bool isEnabledMinEpsilonRate () const
 Returns true if stopping criterion on epsilon rate is enabled, false otherwise. More...
 
void setMaxIter (Size max)
 Stopping criterion on number of iterations. More...
 
Size maxIter () const
 Returns the criterion on number of iterations. More...
 
void disableMaxIter ()
 Disable stopping criterion on max iterations. More...
 
void enableMaxIter ()
 Enable stopping criterion on max iterations. More...
 
bool isEnabledMaxIter () const
 Returns true if stopping criterion on max iterations is enabled, false otherwise. More...
 
void setMaxTime (double timeout)
 Stopping criterion on timeout. More...
 
double maxTime () const
 Returns the timeout (in seconds). More...
 
double currentTime () const
 Returns the current running time in second. More...
 
void disableMaxTime ()
 Disable stopping criterion on timeout. More...
 
void enableMaxTime ()
 Enable stopping criterion on timeout. More...
 
bool isEnabledMaxTime () const
 Returns true if stopping criterion on timeout is enabled, false otherwise. More...
 
void setPeriodSize (Size p)
 How many samples between two stopping is enable. More...
 
Size periodSize () const
 Returns the period size. More...
 
void setVerbosity (bool v)
 Set the verbosity on (true) or off (false). More...
 
bool verbosity () const
 Returns true if verbosity is enabled. More...
 
ApproximationSchemeSTATE stateApproximationScheme () const
 Returns the approximation scheme state. More...
 
Size nbrIterations () const
 Returns the number of iterations. More...
 
const std::vector< double > & history () const
 Returns the scheme history. More...
 
void initApproximationScheme ()
 Initialise the scheme. More...
 
bool startOfPeriod ()
 Returns true if we are at the beginning of a period (compute error is mandatory). More...
 
void updateApproximationScheme (unsigned int incr=1)
 Update the scheme w.r.t the new error and increment steps. More...
 
Size remainingBurnIn ()
 Returns the remaining burn in. More...
 
void stopApproximationScheme ()
 Stop the approximation scheme. More...
 
bool continueApproximationScheme (double error)
 Update the scheme w.r.t the new error. More...
 
Getters and setters
std::string messageApproximationScheme () const
 Returns the approximation scheme message. More...
 

Public Types

enum  ApproximationSchemeSTATE : char {
  ApproximationSchemeSTATE::Undefined, ApproximationSchemeSTATE::Continue, ApproximationSchemeSTATE::Epsilon, ApproximationSchemeSTATE::Rate,
  ApproximationSchemeSTATE::Limit, ApproximationSchemeSTATE::TimeLimit, ApproximationSchemeSTATE::Stopped
}
 The different state of an approximation scheme. More...
 

Protected Attributes

double current_epsilon_
 Current epsilon. More...
 
double last_epsilon_
 Last epsilon value. More...
 
double current_rate_
 Current rate. More...
 
Size current_step_
 The current step. More...
 
Timer timer_
 The timer. More...
 
ApproximationSchemeSTATE current_state_
 The current state. More...
 
std::vector< doublehistory_
 The scheme history, used only if verbosity == true. More...
 
double eps_
 Threshold for convergence. More...
 
bool enabled_eps_
 If true, the threshold convergence is enabled. More...
 
double min_rate_eps_
 Threshold for the epsilon rate. More...
 
bool enabled_min_rate_eps_
 If true, the minimal threshold for epsilon rate is enabled. More...
 
double max_time_
 The timeout. More...
 
bool enabled_max_time_
 If true, the timeout is enabled. More...
 
Size max_iter_
 The maximum iterations. More...
 
bool enabled_max_iter_
 If true, the maximum iterations stopping criterion is enabled. More...
 
Size burn_in_
 Number of iterations before checking stopping criteria. More...
 
Size period_size_
 Checking criteria frequency. More...
 
bool verbosity_
 If true, verbosity is enabled. More...
 

Protected Member Functions

void findBestContributor_ (NodeId x, NodeId y, const std::vector< NodeId > &ui, const MixedGraph &graph, CorrectedMutualInformation<> &mutualInformation, Heap< CondRanking, GreaterPairOn2nd > &rank)
 finds the best contributor node for a pair given a conditioning set More...
 
std::vector< RankingunshieldedTriples_ (const MixedGraph &graph, CorrectedMutualInformation<> &mutualInformation, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet)
 gets the list of unshielded triples in the graph in decreasing value of |I'(x, y, z|{ui})| More...
 
std::vector< ProbabilisticRankingunshieldedTriplesMiic_ (const MixedGraph &graph, CorrectedMutualInformation<> &mutualInformation, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet, HashTable< std::pair< NodeId, NodeId >, char > &marks)
 gets the list of unshielded triples in the graph in decreasing value of |I'(x, y, z|{ui})|, prepares the orientation matrix for MIIC More...
 
std::vector< ProbabilisticRankingupdateProbaTriples_ (const MixedGraph &graph, std::vector< ProbabilisticRanking > probaTriples)
 Gets the orientation probabilities like MIIC for the orientation phase. More...
 
bool propagatesRemainingOrientableEdges_ (MixedGraph &graph, NodeId xj)
 Propagates the orientation from a node to its neighbours. More...
 
void propagatesOrientationInChainOfRemainingEdges_ (MixedGraph &graph)
 heuristic for remaining edges when everything else has been tried More...
 
bool isForbidenArc_ (NodeId x, NodeId y) const
 
bool isOrientable_ (const MixedGraph &graph, NodeId xi, NodeId xj) const
 
Main phases
void initiation_ (CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet, Heap< CondRanking, GreaterPairOn2nd > &rank)
 Initiation phase. More...
 
void iteration_ (CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet, Heap< CondRanking, GreaterPairOn2nd > &rank)
 Iteration phase. More...
 
void orientation3off2_ (CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet)
 Orientation phase from the 3off2 algorithm, returns a CPDAG. More...
 
void orientationLatents_ (CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet)
 Modified version of the orientation phase that tries to propagate orientations from both orientations in case of a bidirected arc, not used. More...
 
void orientationMiic_ (CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet)
 Orientation phase from the MIIC algorithm, returns a mixed graph that may contain circles. More...
 

Detailed Description

The miic learning algorithm.

The miic class implements the miic algorithm based on https://doi.org/10.1371/journal.pcbi.1005662. It starts by eliminating edges that correspond to independent variables to build the skeleton of the graph, and then directs the remaining edges to get an essential graph. Latent variables can be detected using bi-directed arcs.

The variant 3off2 is also implemented as proposed by Affeldt and al. in https://doi.org/10.1186/s12859-015-0856-x. Only the orientation phase differs from miic, with a different ranking method and different propagation rules.

Definition at line 98 of file Miic.h.

Member Enumeration Documentation

◆ ApproximationSchemeSTATE

The different state of an approximation scheme.

Enumerator
Undefined 
Continue 
Epsilon 
Rate 
Limit 
TimeLimit 
Stopped 

Definition at line 64 of file IApproximationSchemeConfiguration.h.

64  : char
65  {
66  Undefined,
67  Continue,
68  Epsilon,
69  Rate,
70  Limit,
71  TimeLimit,
72  Stopped
73  };

Constructor & Destructor Documentation

◆ Miic() [1/4]

gum::learning::Miic::Miic ( )

default constructor

Definition at line 44 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

44 : _maxLog_(100), _size_(0) { GUM_CONSTRUCTOR(Miic); }
int _maxLog_
Fixes the maximum log that we accept in exponential computations.
Definition: Miic.h:323
Size _size_
size of the database
Definition: Miic.h:330
Miic()
default constructor
Definition: Miic.cpp:44
+ Here is the call graph for this function:

◆ Miic() [2/4]

gum::learning::Miic::Miic ( int  maxLog)
explicit

default constructor with maxLog

Definition at line 47 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

47 : _maxLog_(maxLog), _size_(0) { GUM_CONSTRUCTOR(Miic); }
int _maxLog_
Fixes the maximum log that we accept in exponential computations.
Definition: Miic.h:323
Size _size_
size of the database
Definition: Miic.h:330
Miic()
default constructor
Definition: Miic.cpp:44
+ Here is the call graph for this function:

◆ Miic() [3/4]

gum::learning::Miic::Miic ( const Miic from)

copy constructor

Definition at line 50 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

50  : ApproximationScheme(from), _size_(from._size_) {
51  GUM_CONS_CPY(Miic);
52  }
ApproximationScheme(bool verbosity=false)
Size _size_
size of the database
Definition: Miic.h:330
Miic()
default constructor
Definition: Miic.cpp:44
+ Here is the call graph for this function:

◆ Miic() [4/4]

gum::learning::Miic::Miic ( Miic &&  from)

move constructor

Definition at line 55 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

55  : ApproximationScheme(std::move(from)), _size_(from._size_) {
56  GUM_CONS_MOV(Miic);
57  }
ApproximationScheme(bool verbosity=false)
Size _size_
size of the database
Definition: Miic.h:330
Miic()
default constructor
Definition: Miic.cpp:44
+ Here is the call graph for this function:

◆ ~Miic()

gum::learning::Miic::~Miic ( )
override

destructor

Definition at line 60 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

60 { GUM_DESTRUCTOR(Miic); }
Miic()
default constructor
Definition: Miic.cpp:44
+ Here is the call graph for this function:

Member Function Documentation

◆ _existsDirectedPath_()

bool gum::learning::Miic::_existsDirectedPath_ ( const MixedGraph graph,
NodeId  n1,
NodeId  n2 
)
staticprivate

checks for directed paths in a graph, consider double arcs like edges

Parameters
graphMixedGraph in which to search the path
n1tail of the path
n2head of the path

Definition at line 962 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

962  {
963  // not recursive version => use a FIFO for simulating the recursion
964  List< NodeId > nodeFIFO;
965  // mark[node] = successor if visited, else mark[node] does not exist
966  Set< NodeId > mark;
967 
968  mark.insert(n2);
969  nodeFIFO.pushBack(n2);
970 
971  NodeId current;
972 
973  while (!nodeFIFO.empty()) {
974  current = nodeFIFO.front();
975  nodeFIFO.popFront();
976 
977  // check the parents
978  for (const auto new_one: graph.parents(current)) {
979  if (graph.existsArc(current,
980  new_one)) // if there is a double arc, pass
981  continue;
982 
983  if (new_one == n1) { return true; }
984 
985  if (mark.exists(new_one)) // if this node is already marked, do not
986  continue; // check it again
987 
988  mark.insert(new_one);
989  nodeFIFO.pushBack(new_one);
990  }
991  }
992 
993  return false;
994  }
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:600
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:606
+ Here is the call graph for this function:

◆ _existsNonTrivialDirectedPath_()

bool gum::learning::Miic::_existsNonTrivialDirectedPath_ ( const MixedGraph graph,
NodeId  n1,
NodeId  n2 
)
staticprivate

checks for directed paths in a graph, considering double arcs like edges, not considering arc as a directed path.

Parameters
graphMixedGraph in which to search the path
n1tail of the path
n2head of the path
countArcbool to know if we

Definition at line 948 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

950  {
951  for (const auto parent: graph.parents(n2)) {
952  if (graph.existsArc(parent,
953  n2)) // if there is a double arc, pass
954  continue;
955  if (parent == n1) // trivial directed path => not recognized
956  continue;
957  if (_existsDirectedPath_(graph, n1, parent)) return true;
958  }
959  return false;
960  }
static bool _existsDirectedPath_(const MixedGraph &graph, NodeId n1, NodeId n2)
checks for directed paths in a graph, consider double arcs like edges
Definition: Miic.cpp:962
+ Here is the call graph for this function:

◆ _isNotLatentCouple_()

bool gum::learning::Miic::_isNotLatentCouple_ ( NodeId  x,
NodeId  y 
)
private

Definition at line 1161 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

1161  {
1162  const auto& lbeg = _latentCouples_.begin();
1163  const auto& lend = _latentCouples_.end();
1164 
1165  return (std::find(lbeg, lend, Arc(x, y)) == lend)
1166  && (std::find(lbeg, lend, Arc(y, x)) == lend);
1167  }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
+ Here is the call graph for this function:

◆ _orientingVstructureMiic_()

void gum::learning::Miic::_orientingVstructureMiic_ ( MixedGraph graph,
HashTable< std::pair< NodeId, NodeId >, char > &  marks,
NodeId  x,
NodeId  y,
NodeId  z,
double  p1,
double  p2 
)
private

Definition at line 996 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

1002  {
1003  // v-structure discovery
1004  if (marks[{x, z}] == 'o' && marks[{y, z}] == 'o') { // If x-z-y
1005  if (!_existsNonTrivialDirectedPath_(graph, z, x)) {
1006  graph.eraseEdge(Edge(x, z));
1007  graph.addArc(x, z);
1008  GUM_TRACE("1.a Removing edge (" << x << "," << z << ")")
1009  GUM_TRACE("1.a Adding arc (" << x << "," << z << ")")
1010  marks[{x, z}] = '>';
1011  if (graph.existsArc(z, x) && _isNotLatentCouple_(z, x)) {
1012  GUM_TRACE("Adding latent couple (" << z << "," << x << ")")
1013  _latentCouples_.emplace_back(z, x);
1014  }
1015  if (!_arcProbas_.exists(Arc(x, z))) _arcProbas_.insert(Arc(x, z), p1);
1016  } else {
1017  graph.eraseEdge(Edge(x, z));
1018  GUM_TRACE("1.b Adding arc (" << x << "," << z << ")")
1019  if (!_existsNonTrivialDirectedPath_(graph, x, z)) {
1020  graph.addArc(z, x);
1021  GUM_TRACE("1.b Removing edge (" << x << "," << z << ")")
1022  marks[{z, x}] = '>';
1023  }
1024  }
1025 
1026  if (!_existsNonTrivialDirectedPath_(graph, z, y)) {
1027  graph.eraseEdge(Edge(y, z));
1028  graph.addArc(y, z);
1029  GUM_TRACE("1.c Removing edge (" << y << "," << z << ")")
1030  GUM_TRACE("1.c Adding arc (" << y << "," << z << ")")
1031  marks[{y, z}] = '>';
1032  if (graph.existsArc(z, y) && _isNotLatentCouple_(z, y)) {
1033  _latentCouples_.emplace_back(z, y);
1034  }
1035  if (!_arcProbas_.exists(Arc(y, z))) _arcProbas_.insert(Arc(y, z), p2);
1036  } else {
1037  graph.eraseEdge(Edge(y, z));
1038  GUM_TRACE("1.d Removing edge (" << y << "," << z << ")")
1039  if (!_existsNonTrivialDirectedPath_(graph, y, z)) {
1040  graph.addArc(z, y);
1041  GUM_TRACE("1.d Adding arc (" << z << "," << y << ")")
1042  marks[{z, y}] = '>';
1043  }
1044  }
1045  } else if (marks[{x, z}] == '>' && marks[{y, z}] == 'o') { // If x->z-y
1046  if (!_existsNonTrivialDirectedPath_(graph, z, y)) {
1047  graph.eraseEdge(Edge(y, z));
1048  graph.addArc(y, z);
1049  GUM_TRACE("2.a Removing edge (" << y << "," << z << ")")
1050  GUM_TRACE("2.a Adding arc (" << y << "," << z << ")")
1051  marks[{y, z}] = '>';
1052  if (graph.existsArc(z, y) && _isNotLatentCouple_(z, y)) {
1053  _latentCouples_.emplace_back(z, y);
1054  }
1055  if (!_arcProbas_.exists(Arc(y, z))) _arcProbas_.insert(Arc(y, z), p2);
1056  } else {
1057  graph.eraseEdge(Edge(y, z));
1058  GUM_TRACE("2.b Removing edge (" << y << "," << z << ")")
1059  if (!_existsNonTrivialDirectedPath_(graph, y, z)) {
1060  graph.addArc(z, y);
1061  GUM_TRACE("2.b Adding arc (" << y << "," << z << ")")
1062  marks[{z, y}] = '>';
1063  }
1064  }
1065  } else if (marks[{y, z}] == '>' && marks[{x, z}] == 'o') {
1066  if (!_existsNonTrivialDirectedPath_(graph, z, x)) {
1067  graph.eraseEdge(Edge(x, z));
1068  graph.addArc(x, z);
1069  GUM_TRACE("3.a Removing edge (" << x << "," << z << ")")
1070  GUM_TRACE("3.a Adding arc (" << x << "," << z << ")")
1071  marks[{x, z}] = '>';
1072  if (graph.existsArc(z, x) && _isNotLatentCouple_(z, x)) {
1073  _latentCouples_.emplace_back(z, x);
1074  }
1075  if (!_arcProbas_.exists(Arc(x, z))) _arcProbas_.insert(Arc(x, z), p1);
1076  } else {
1077  graph.eraseEdge(Edge(x, z));
1078  GUM_TRACE("3.b Removing edge (" << x << "," << z << ")")
1079  if (!_existsNonTrivialDirectedPath_(graph, x, z)) {
1080  graph.addArc(z, x);
1081  GUM_TRACE("3.b Adding arc (" << x << "," << z << ")")
1082  marks[{z, x}] = '>';
1083  }
1084  }
1085  }
1086  }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
ArcProperty< double > _arcProbas_
Storing the propabilities for each arc set in the graph.
Definition: Miic.h:335
bool _isNotLatentCouple_(NodeId x, NodeId y)
Definition: Miic.cpp:1161
static bool _existsNonTrivialDirectedPath_(const MixedGraph &graph, NodeId n1, NodeId n2)
checks for directed paths in a graph, considering double arcs like edges, not considering arc as a di...
Definition: Miic.cpp:948
+ Here is the call graph for this function:

◆ _propagatingOrientationMiic_()

void gum::learning::Miic::_propagatingOrientationMiic_ ( MixedGraph graph,
HashTable< std::pair< NodeId, NodeId >, char > &  marks,
NodeId  x,
NodeId  y,
NodeId  z,
double  p1,
double  p2 
)
private

Definition at line 1089 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

1095  {
1096  // orientation propagation
1097  if (marks[{x, z}] == '>' && marks[{y, z}] == 'o' && marks[{z, y}] != '-') {
1098  graph.eraseEdge(Edge(z, y));
1099  // std::cout << "4. Removing edge (" << z << "," << y << ")" <<
1100  // std::endl;
1101  if (!_existsDirectedPath_(graph, y, z) && graph.parents(y).empty()) {
1102  graph.addArc(z, y);
1103  GUM_TRACE("4.a Adding arc (" << z << "," << y << ")")
1104  marks[{z, y}] = '>';
1105  marks[{y, z}] = '-';
1106  if (!_arcProbas_.exists(Arc(z, y))) _arcProbas_.insert(Arc(z, y), p2);
1107  } else if (!_existsDirectedPath_(graph, z, y) && graph.parents(z).empty()) {
1108  graph.addArc(y, z);
1109  GUM_TRACE("4.b Adding arc (" << y << "," << z << ")")
1110  marks[{z, y}] = '-';
1111  marks[{y, z}] = '>';
1112  _latentCouples_.emplace_back(y, z);
1113  if (!_arcProbas_.exists(Arc(y, z))) _arcProbas_.insert(Arc(y, z), p2);
1114  } else if (!_existsDirectedPath_(graph, y, z)) {
1115  graph.addArc(z, y);
1116  GUM_TRACE("4.c Adding arc (" << z << "," << y << ")")
1117  marks[{z, y}] = '>';
1118  marks[{y, z}] = '-';
1119  if (!_arcProbas_.exists(Arc(z, y))) _arcProbas_.insert(Arc(z, y), p2);
1120  } else if (!_existsDirectedPath_(graph, z, y)) {
1121  graph.addArc(y, z);
1122  GUM_TRACE("4.d Adding arc (" << y << "," << z << ")")
1123  _latentCouples_.emplace_back(y, z);
1124  marks[{z, y}] = '-';
1125  marks[{y, z}] = '>';
1126  if (!_arcProbas_.exists(Arc(y, z))) _arcProbas_.insert(Arc(y, z), p2);
1127  }
1128  } else if (marks[{y, z}] == '>' && marks[{x, z}] == 'o' && marks[{z, x}] != '-') {
1129  graph.eraseEdge(Edge(z, x));
1130  GUM_TRACE("5. Removing edge (" << z << "," << x << ")")
1131  if (!_existsDirectedPath_(graph, x, z) && graph.parents(x).empty()) {
1132  graph.addArc(z, x);
1133  GUM_TRACE("5.a Adding arc (" << z << "," << x << ")")
1134  marks[{z, x}] = '>';
1135  marks[{x, z}] = '-';
1136  if (!_arcProbas_.exists(Arc(z, x))) _arcProbas_.insert(Arc(z, x), p1);
1137  } else if (!_existsDirectedPath_(graph, z, x) && graph.parents(z).empty()) {
1138  graph.addArc(x, z);
1139  GUM_TRACE("5.b Adding arc (" << x << "," << z << ")")
1140  marks[{z, x}] = '-';
1141  marks[{x, z}] = '>';
1142  _latentCouples_.emplace_back(x, z);
1143  if (!_arcProbas_.exists(Arc(x, z))) _arcProbas_.insert(Arc(x, z), p1);
1144  } else if (!_existsDirectedPath_(graph, x, z)) {
1145  graph.addArc(z, x);
1146  GUM_TRACE("5.c Adding arc (" << z << "," << x << ")")
1147  marks[{z, x}] = '>';
1148  marks[{x, z}] = '-';
1149  if (!_arcProbas_.exists(Arc(z, x))) _arcProbas_.insert(Arc(z, x), p1);
1150  } else if (!_existsDirectedPath_(graph, z, x)) {
1151  graph.addArc(x, z);
1152  GUM_TRACE("5.d Adding arc (" << x << "," << z << ")")
1153  marks[{z, x}] = '-';
1154  marks[{x, z}] = '>';
1155  _latentCouples_.emplace_back(x, z);
1156  if (!_arcProbas_.exists(Arc(x, z))) _arcProbas_.insert(Arc(x, z), p1);
1157  }
1158  }
1159  }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
ArcProperty< double > _arcProbas_
Storing the propabilities for each arc set in the graph.
Definition: Miic.h:335
static bool _existsDirectedPath_(const MixedGraph &graph, NodeId n1, NodeId n2)
checks for directed paths in a graph, consider double arcs like edges
Definition: Miic.cpp:962
+ Here is the call graph for this function:

◆ addConstraints()

void gum::learning::Miic::addConstraints ( HashTable< std::pair< NodeId, NodeId >, char >  constraints)

Set a ensemble of constraints for the orientation phase.

Definition at line 944 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

944  {
945  this->_initialMarks_ = constraints;
946  }
HashTable< std::pair< NodeId, NodeId >, char > _initialMarks_
Initial marks for the orientation phase, used to convey constraints.
Definition: Miic.h:338
+ Here is the call graph for this function:

◆ continueApproximationScheme()

INLINE bool gum::ApproximationScheme::continueApproximationScheme ( double  error)
inherited

Update the scheme w.r.t the new error.

Test the stopping criterion that are enabled.

Parameters
errorThe new error value.
Returns
false if state become != ApproximationSchemeSTATE::Continue
Exceptions
OperationNotAllowedRaised if state != ApproximationSchemeSTATE::Continue.

Definition at line 208 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

208  {
209  // For coherence, we fix the time used in the method
210 
211  double timer_step = timer_.step();
212 
213  if (enabled_max_time_) {
214  if (timer_step > max_time_) {
216  return false;
217  }
218  }
219 
220  if (!startOfPeriod()) { return true; }
221 
223  GUM_ERROR(OperationNotAllowed,
224  "state of the approximation scheme is not correct : "
226  }
227 
228  if (verbosity()) { history_.push_back(error); }
229 
230  if (enabled_max_iter_) {
231  if (current_step_ > max_iter_) {
233  return false;
234  }
235  }
236 
238  current_epsilon_ = error; // eps rate isEnabled needs it so affectation was
239  // moved from eps isEnabled below
240 
241  if (enabled_eps_) {
242  if (current_epsilon_ <= eps_) {
244  return false;
245  }
246  }
247 
248  if (last_epsilon_ >= 0.) {
249  if (current_epsilon_ > .0) {
250  // ! current_epsilon_ can be 0. AND epsilon
251  // isEnabled can be disabled !
253  }
254  // limit with current eps ---> 0 is | 1 - ( last_eps / 0 ) | --->
255  // infinity the else means a return false if we isEnabled the rate below,
256  // as we would have returned false if epsilon isEnabled was enabled
257  else {
259  }
260 
261  if (enabled_min_rate_eps_) {
262  if (current_rate_ <= min_rate_eps_) {
264  return false;
265  }
266  }
267  }
268 
270  if (onProgress.hasListener()) {
272  }
273 
274  return true;
275  } else {
276  return false;
277  }
278  }
double max_time_
The timeout.
double step() const
Returns the delta time between now and the last reset() call (or the constructor).
Definition: timer_inl.h:41
Signaler3< Size, double, double > onProgress
Progression, error and time.
ApproximationSchemeSTATE current_state_
The current state.
void stopScheme_(ApproximationSchemeSTATE new_state)
Stop the scheme given a new state.
bool startOfPeriod()
Returns true if we are at the beginning of a period (compute error is mandatory). ...
bool enabled_max_iter_
If true, the maximum iterations stopping criterion is enabled.
double last_epsilon_
Last epsilon value.
double eps_
Threshold for convergence.
double min_rate_eps_
Threshold for the epsilon rate.
bool enabled_max_time_
If true, the timeout is enabled.
double current_rate_
Current rate.
Size max_iter_
The maximum iterations.
double current_epsilon_
Current epsilon.
bool enabled_eps_
If true, the threshold convergence is enabled.
ApproximationSchemeSTATE stateApproximationScheme() const
Returns the approximation scheme state.
std::vector< double > history_
The scheme history, used only if verbosity == true.
bool verbosity() const
Returns true if verbosity is enabled.
std::string messageApproximationScheme() const
Returns the approximation scheme message.
bool enabled_min_rate_eps_
If true, the minimal threshold for epsilon rate is enabled.
Size current_step_
The current step.
#define GUM_EMIT3(signal, arg1, arg2, arg3)
Definition: signaler3.h:41
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ currentTime()

INLINE double gum::ApproximationScheme::currentTime ( ) const
virtualinherited

Returns the current running time in second.

Returns
Returns the current running time in second.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 115 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

115 { return timer_.step(); }
double step() const
Returns the delta time between now and the last reset() call (or the constructor).
Definition: timer_inl.h:41
+ Here is the call graph for this function:

◆ disableEpsilon()

INLINE void gum::ApproximationScheme::disableEpsilon ( )
virtualinherited

Disable stopping criterion on epsilon.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 53 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

53 { enabled_eps_ = false; }
bool enabled_eps_
If true, the threshold convergence is enabled.
+ Here is the call graph for this function:

◆ disableMaxIter()

INLINE void gum::ApproximationScheme::disableMaxIter ( )
virtualinherited

Disable stopping criterion on max iterations.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 94 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

94 { enabled_max_iter_ = false; }
bool enabled_max_iter_
If true, the maximum iterations stopping criterion is enabled.
+ Here is the call graph for this function:

◆ disableMaxTime()

INLINE void gum::ApproximationScheme::disableMaxTime ( )
virtualinherited

Disable stopping criterion on timeout.

Returns
Disable stopping criterion on timeout.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 118 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

118 { enabled_max_time_ = false; }
bool enabled_max_time_
If true, the timeout is enabled.
+ Here is the call graph for this function:

◆ disableMinEpsilonRate()

INLINE void gum::ApproximationScheme::disableMinEpsilonRate ( )
virtualinherited

Disable stopping criterion on epsilon rate.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 74 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

74 { enabled_min_rate_eps_ = false; }
bool enabled_min_rate_eps_
If true, the minimal threshold for epsilon rate is enabled.
+ Here is the call graph for this function:

◆ enableEpsilon()

INLINE void gum::ApproximationScheme::enableEpsilon ( )
virtualinherited

Enable stopping criterion on epsilon.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 56 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

56 { enabled_eps_ = true; }
bool enabled_eps_
If true, the threshold convergence is enabled.
+ Here is the call graph for this function:

◆ enableMaxIter()

INLINE void gum::ApproximationScheme::enableMaxIter ( )
virtualinherited

Enable stopping criterion on max iterations.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 97 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

97 { enabled_max_iter_ = true; }
bool enabled_max_iter_
If true, the maximum iterations stopping criterion is enabled.
+ Here is the call graph for this function:

◆ enableMaxTime()

INLINE void gum::ApproximationScheme::enableMaxTime ( )
virtualinherited

Enable stopping criterion on timeout.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 121 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

121 { enabled_max_time_ = true; }
bool enabled_max_time_
If true, the timeout is enabled.
+ Here is the call graph for this function:

◆ enableMinEpsilonRate()

INLINE void gum::ApproximationScheme::enableMinEpsilonRate ( )
virtualinherited

Enable stopping criterion on epsilon rate.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 77 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

77 { enabled_min_rate_eps_ = true; }
bool enabled_min_rate_eps_
If true, the minimal threshold for epsilon rate is enabled.
+ Here is the call graph for this function:

◆ epsilon()

INLINE double gum::ApproximationScheme::epsilon ( ) const
virtualinherited

Returns the value of epsilon.

Returns
Returns the value of epsilon.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 50 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

50 { return eps_; }
double eps_
Threshold for convergence.
+ Here is the call graph for this function:

◆ findBestContributor_()

void gum::learning::Miic::findBestContributor_ ( NodeId  x,
NodeId  y,
const std::vector< NodeId > &  ui,
const MixedGraph graph,
CorrectedMutualInformation<> &  mutualInformation,
Heap< CondRanking, GreaterPairOn2nd > &  rank 
)
protected

finds the best contributor node for a pair given a conditioning set

Parameters
xfirst node
ysecond node
uiconditioning set
mutualInformationA mutual information instance that will do the computations and has loaded the database.
graphcontaining the assessed nodes
rankthe heap of ranks of the algorithm

Definition at line 570 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

575  {
576  double maxP = -1.0;
577  NodeId maxZ = 0;
578 
579  // compute N
580  // __N = I.N();
581  const double Ixy_ui = mutualInformation.score(x, y, ui);
582 
583  for (const NodeId z: graph) {
584  // if z!=x and z!=y and z not in ui
585  if (z != x && z != y && std::find(ui.begin(), ui.end(), z) == ui.end()) {
586  double Pnv;
587  double Pb;
588 
589  // Computing Pnv
590  const double Ixyz_ui = mutualInformation.score(x, y, z, ui);
591  double calc_expo1 = -Ixyz_ui * M_LN2;
592  // if exponential are too high or to low, crop them at _maxLog_
593  if (calc_expo1 > _maxLog_) {
594  Pnv = 0.0;
595  } else if (calc_expo1 < -_maxLog_) {
596  Pnv = 1.0;
597  } else {
598  Pnv = 1 / (1 + std::exp(calc_expo1));
599  }
600 
601  // Computing Pb
602  const double Ixz_ui = mutualInformation.score(x, z, ui);
603  const double Iyz_ui = mutualInformation.score(y, z, ui);
604 
605  calc_expo1 = -(Ixz_ui - Ixy_ui) * M_LN2;
606  double calc_expo2 = -(Iyz_ui - Ixy_ui) * M_LN2;
607 
608  // if exponential are too high or to low, crop them at _maxLog_
609  if (calc_expo1 > _maxLog_ || calc_expo2 > _maxLog_) {
610  Pb = 0.0;
611  } else if (calc_expo1 < -_maxLog_ && calc_expo2 < -_maxLog_) {
612  Pb = 1.0;
613  } else {
614  double expo1, expo2;
615  if (calc_expo1 < -_maxLog_) {
616  expo1 = 0.0;
617  } else {
618  expo1 = std::exp(calc_expo1);
619  }
620  if (calc_expo2 < -_maxLog_) {
621  expo2 = 0.0;
622  } else {
623  expo2 = std::exp(calc_expo2);
624  }
625  Pb = 1 / (1 + expo1 + expo2);
626  }
627 
628  // Getting max(min(Pnv, pb))
629  const double min_pnv_pb = std::min(Pnv, Pb);
630  if (min_pnv_pb > maxP) {
631  maxP = min_pnv_pb;
632  maxZ = z;
633  }
634  } // if z not in (x, y)
635  } // for z in graph.nodes
636  // storing best z in rank_
637  CondRanking final;
638  auto tup = new CondThreePoints{x, y, maxZ, ui};
639  final.first = tup;
640  final.second = maxP;
641  rank.insert(final);
642  }
int _maxLog_
Fixes the maximum log that we accept in exponential computations.
Definition: Miic.h:323
#define M_LN2
Definition: math_utils.h:43
std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > CondThreePoints
Definition: Miic.h:57
std::pair< CondThreePoints *, double > CondRanking
Definition: Miic.h:58
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ history()

INLINE const std::vector< double > & gum::ApproximationScheme::history ( ) const
virtualinherited

Returns the scheme history.

Returns
Returns the scheme history.
Exceptions
OperationNotAllowedRaised if the scheme did not performed or if verbosity is set to false.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 157 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

157  {
159  GUM_ERROR(OperationNotAllowed, "state of the approximation scheme is udefined")
160  }
161 
162  if (verbosity() == false) { GUM_ERROR(OperationNotAllowed, "No history when verbosity=false") }
163 
164  return history_;
165  }
ApproximationSchemeSTATE stateApproximationScheme() const
Returns the approximation scheme state.
std::vector< double > history_
The scheme history, used only if verbosity == true.
bool verbosity() const
Returns true if verbosity is enabled.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ initApproximationScheme()

INLINE void gum::ApproximationScheme::initApproximationScheme ( )
inherited

Initialise the scheme.

Definition at line 168 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

168  {
170  current_step_ = 0;
172  history_.clear();
173  timer_.reset();
174  }
ApproximationSchemeSTATE current_state_
The current state.
void reset()
Reset the timer.
Definition: timer_inl.h:31
double current_rate_
Current rate.
double current_epsilon_
Current epsilon.
std::vector< double > history_
The scheme history, used only if verbosity == true.
Size current_step_
The current step.
+ Here is the call graph for this function:

◆ initiation_()

void gum::learning::Miic::initiation_ ( CorrectedMutualInformation<> &  mutualInformation,
MixedGraph graph,
HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sepSet,
Heap< CondRanking, GreaterPairOn2nd > &  rank 
)
protected

Initiation phase.

We go over all edges and test if the variables are marginally independent. If they are, the edge is deleted. If not, the best contributor is found.

Parameters
mutualInformationA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph we start from for the learning
sepSetthe separation set for independent couples, here set to {}
rankthe heap of ranks of the algorithm

Definition at line 140 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

143  {
144  NodeId x, y;
145  EdgeSet edges = graph.edges();
146  Size steps_init = edges.size();
147 
148  for (const Edge& edge: edges) {
149  x = edge.first();
150  y = edge.second();
151  double Ixy = mutualInformation.score(x, y);
152 
153  if (Ixy <= 0) { //< K
154  graph.eraseEdge(edge);
155  sepSet.insert(std::make_pair(x, y), _emptySet_);
156  } else {
157  findBestContributor_(x, y, _emptySet_, graph, mutualInformation, rank);
158  }
159 
160  ++current_step_;
161  if (onProgress.hasListener()) {
162  GUM_EMIT3(onProgress, (current_step_ * 33) / steps_init, 0., timer_.step());
163  }
164  }
165  }
double step() const
Returns the delta time between now and the last reset() call (or the constructor).
Definition: timer_inl.h:41
Signaler3< Size, double, double > onProgress
Progression, error and time.
void findBestContributor_(NodeId x, NodeId y, const std::vector< NodeId > &ui, const MixedGraph &graph, CorrectedMutualInformation<> &mutualInformation, Heap< CondRanking, GreaterPairOn2nd > &rank)
finds the best contributor node for a pair given a conditioning set
Definition: Miic.cpp:570
Set< Edge > EdgeSet
Some typdefs and define for shortcuts ...
const std::vector< NodeId > _emptySet_
an empty conditioning set
Definition: Miic.h:325
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
Size current_step_
The current step.
#define GUM_EMIT3(signal, arg1, arg2, arg3)
Definition: signaler3.h:41
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ isEnabledEpsilon()

INLINE bool gum::ApproximationScheme::isEnabledEpsilon ( ) const
virtualinherited

Returns true if stopping criterion on epsilon is enabled, false otherwise.

Returns
Returns true if stopping criterion on epsilon is enabled, false otherwise.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 60 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

60 { return enabled_eps_; }
bool enabled_eps_
If true, the threshold convergence is enabled.
+ Here is the call graph for this function:

◆ isEnabledMaxIter()

INLINE bool gum::ApproximationScheme::isEnabledMaxIter ( ) const
virtualinherited

Returns true if stopping criterion on max iterations is enabled, false otherwise.

Returns
Returns true if stopping criterion on max iterations is enabled, false otherwise.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 101 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

101 { return enabled_max_iter_; }
bool enabled_max_iter_
If true, the maximum iterations stopping criterion is enabled.
+ Here is the call graph for this function:

◆ isEnabledMaxTime()

INLINE bool gum::ApproximationScheme::isEnabledMaxTime ( ) const
virtualinherited

Returns true if stopping criterion on timeout is enabled, false otherwise.

Returns
Returns true if stopping criterion on timeout is enabled, false otherwise.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 125 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

125 { return enabled_max_time_; }
bool enabled_max_time_
If true, the timeout is enabled.
+ Here is the call graph for this function:

◆ isEnabledMinEpsilonRate()

INLINE bool gum::ApproximationScheme::isEnabledMinEpsilonRate ( ) const
virtualinherited

Returns true if stopping criterion on epsilon rate is enabled, false otherwise.

Returns
Returns true if stopping criterion on epsilon rate is enabled, false otherwise.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 81 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

81 { return enabled_min_rate_eps_; }
bool enabled_min_rate_eps_
If true, the minimal threshold for epsilon rate is enabled.
+ Here is the call graph for this function:

◆ isForbidenArc_()

bool gum::learning::Miic::isForbidenArc_ ( NodeId  x,
NodeId  y 
) const
protected

Definition at line 1169 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

1169  {
1170  return (_initialMarks_.exists({x, y}) && _initialMarks_[{x, y}] == '-');
1171  }
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
HashTable< std::pair< NodeId, NodeId >, char > _initialMarks_
Initial marks for the orientation phase, used to convey constraints.
Definition: Miic.h:338
+ Here is the call graph for this function:

◆ isOrientable_()

bool gum::learning::Miic::isOrientable_ ( const MixedGraph graph,
NodeId  xi,
NodeId  xj 
) const
protected

Definition at line 823 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

823  {
824  // no cycle
825  if (_existsDirectedPath_(graph, xj, xi)) {
826  GUM_TRACE("cycle(" << xi << "-" << xj << ")")
827  return false;
828  }
829 
830  // R1
831  if (!(graph.parents(xi) - graph.adjacents(xj)).empty()) {
832  GUM_TRACE("R1(" << xi << "-" << xj << ")")
833  return true;
834  }
835 
836  // R2
837  if (_existsDirectedPath_(graph, xi, xj)) {
838  GUM_TRACE("R2(" << xi << "-" << xj << ")")
839  return true;
840  }
841 
842  // R3
843  int nbr = 0;
844  for (const auto p: graph.parents(xj)) {
845  if (!graph.mixedOrientedPath(xi, p).empty()) {
846  nbr += 1;
847  if (nbr == 2) {
848  GUM_TRACE("R3(" << xi << "-" << xj << ")")
849  return true;
850  }
851  }
852  }
853  return false;
854  }
static bool _existsDirectedPath_(const MixedGraph &graph, NodeId n1, NodeId n2)
checks for directed paths in a graph, consider double arcs like edges
Definition: Miic.cpp:962
+ Here is the call graph for this function:

◆ iteration_()

void gum::learning::Miic::iteration_ ( CorrectedMutualInformation<> &  mutualInformation,
MixedGraph graph,
HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sepSet,
Heap< CondRanking, GreaterPairOn2nd > &  rank 
)
protected

Iteration phase.

As long as we find important nodes for edges, we go over them to see if we can assess the conditional independence of the variables.

Parameters
mutualInformationA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph returned from the previous phase
sepSetthe separation set for independent couples, built during the iterations of the phase
rankthe heap of ranks of the algorithm

Definition at line 173 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

176  {
177  // if no triples to further examine pass
178  CondRanking best;
179 
180  Size steps_init = current_step_;
181  Size steps_iter = rank.size();
182 
183  try {
184  while (rank.top().second > 0.5) {
185  best = rank.pop();
186 
187  const NodeId x = std::get< 0 >(*(best.first));
188  const NodeId y = std::get< 1 >(*(best.first));
189  const NodeId z = std::get< 2 >(*(best.first));
190  std::vector< NodeId > ui = std::move(std::get< 3 >(*(best.first)));
191 
192  ui.push_back(z);
193  const double i_xy_ui = mutualInformation.score(x, y, ui);
194  if (i_xy_ui < 0) {
195  graph.eraseEdge(Edge(x, y));
196  sepSet.insert(std::make_pair(x, y), std::move(ui));
197  } else {
198  findBestContributor_(x, y, ui, graph, mutualInformation, rank);
199  }
200 
201  delete best.first;
202 
203  ++current_step_;
204  if (onProgress.hasListener()) {
206  (current_step_ * 66) / (steps_init + steps_iter),
207  0.,
208  timer_.step());
209  }
210  }
211  } catch (...) {} // here, rank is empty
212  current_step_ = steps_init + steps_iter;
213  if (onProgress.hasListener()) { GUM_EMIT3(onProgress, 66, 0., timer_.step()); }
214  current_step_ = steps_init + steps_iter;
215  }
double step() const
Returns the delta time between now and the last reset() call (or the constructor).
Definition: timer_inl.h:41
Signaler3< Size, double, double > onProgress
Progression, error and time.
void findBestContributor_(NodeId x, NodeId y, const std::vector< NodeId > &ui, const MixedGraph &graph, CorrectedMutualInformation<> &mutualInformation, Heap< CondRanking, GreaterPairOn2nd > &rank)
finds the best contributor node for a pair given a conditioning set
Definition: Miic.cpp:570
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
Size current_step_
The current step.
#define GUM_EMIT3(signal, arg1, arg2, arg3)
Definition: signaler3.h:41
std::pair< CondThreePoints *, double > CondRanking
Definition: Miic.h:58
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ latentVariables()

const std::vector< Arc > gum::learning::Miic::latentVariables ( ) const

get the list of arcs hiding latent variables

Definition at line 929 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

929 { return _latentCouples_; }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
+ Here is the call graph for this function:

◆ learnBN()

template<typename GUM_SCALAR , typename GRAPH_CHANGES_SELECTOR , typename PARAM_ESTIMATOR >
BayesNet< GUM_SCALAR > gum::learning::Miic::learnBN ( GRAPH_CHANGES_SELECTOR &  selector,
PARAM_ESTIMATOR &  estimator,
DAG  initial_dag = DAG() 
)

learns the structure and the parameters of a BN

Parameters
selectorA selector class that computes the best changes that can be applied and that enables the user to get them very easily. Typically, the selector is a GraphChangesSelector4DiGraph<SCORE, STRUCT_CONSTRAINT, GRAPH_CHANGES_GENERATOR>.
estimatorA estimator.
namesThe variables names.
modalthe domain sizes of the random variables observed in the database
translatorThe cell translator to use.
initial_dagthe DAG we start from for our learning

Definition at line 933 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

935  {
936  return DAG2BNLearner<>::createBN< GUM_SCALAR >(estimator,
937  learnStructure(selector, initial_dag));
938  }
static BayesNet< GUM_SCALAR > createBN(ParamEstimator< ALLOC > &estimator, const DAG &dag)
create a BN from a DAG using a one pass generator (typically ML)
DAG learnStructure(CorrectedMutualInformation<> &I, MixedGraph graph)
learns the structure of a Bayesian network, i.e. a DAG, by first learning an Essential graph and then...
Definition: Miic.cpp:764
+ Here is the call graph for this function:

◆ learnMixedStructure()

MixedGraph gum::learning::Miic::learnMixedStructure ( CorrectedMutualInformation<> &  mutualInformation,
MixedGraph  graph 
)

learns the structure of an Essential Graph

learns the structure of a MixedGraph

Parameters
mutualInformationA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph we start from for the learning

Definition at line 106 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

107  {
108  timer_.reset();
109  current_step_ = 0;
110 
111  // clear the vector of latent arcs to be sure
112  _latentCouples_.clear();
113 
115  Heap< CondRanking, GreaterPairOn2nd > rank;
116 
118  HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > sep_set;
119 
120  initiation_(mutualInformation, graph, sep_set, rank);
121 
122  iteration_(mutualInformation, graph, sep_set, rank);
123 
124  if (_useMiic_) {
125  orientationMiic_(mutualInformation, graph, sep_set);
126  } else {
127  orientation3off2_(mutualInformation, graph, sep_set);
128  }
129 
130  return graph;
131  }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
void iteration_(CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet, Heap< CondRanking, GreaterPairOn2nd > &rank)
Iteration phase.
Definition: Miic.cpp:173
void orientationMiic_(CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet)
Orientation phase from the MIIC algorithm, returns a mixed graph that may contain circles...
Definition: Miic.cpp:497
void reset()
Reset the timer.
Definition: timer_inl.h:31
void orientation3off2_(CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet)
Orientation phase from the 3off2 algorithm, returns a CPDAG.
Definition: Miic.cpp:222
bool _useMiic_
wether to use the miic algorithm or not
Definition: Miic.h:332
void initiation_(CorrectedMutualInformation<> &mutualInformation, MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet, Heap< CondRanking, GreaterPairOn2nd > &rank)
Initiation phase.
Definition: Miic.cpp:140
Size current_step_
The current step.
+ Here is the call graph for this function:

◆ learnStructure()

DAG gum::learning::Miic::learnStructure ( CorrectedMutualInformation<> &  I,
MixedGraph  graph 
)

learns the structure of a Bayesian network, i.e. a DAG, by first learning an Essential graph and then directing the remaining edges.

learns the structure of an Bayesian network, ie a DAG, from an Essential graph.

Parameters
IA mutual information instance that will do the computations and has loaded the database
graphthe MixedGraph we start from for the learning

Definition at line 764 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

764  {
765  MixedGraph essentialGraph = learnMixedStructure(I, initialGraph);
766  // orientate remaining edges
767 
768  const Sequence< NodeId > order = essentialGraph.topologicalOrder();
769 
770  // first, forbidden arcs force arc in the other direction
771  for (NodeId x: order) {
772  const auto nei_x = essentialGraph.neighbours(x);
773  for (NodeId y: nei_x)
774  if (isForbidenArc_(x, y)) {
775  essentialGraph.eraseEdge(Edge(x, y));
776  if (isForbidenArc_(y, x)) {
777  GUM_TRACE("Neither arc allowed for edge (" << x << "," << y << ")")
778  } else {
779  GUM_TRACE("Forced orientation : " << y << "->" << x)
780  essentialGraph.addArc(y, x);
781  }
782  } else if (isForbidenArc_(y, x)) {
783  essentialGraph.eraseEdge(Edge(x, y));
784  GUM_TRACE("Forced orientation : " << x << "->" << y)
785  essentialGraph.addArc(x, y);
786  }
787  }
788  GUM_TRACE(essentialGraph.toDot());
789 
790  // first, propagate existing orientations
791  bool newOrientation = true;
792  while (newOrientation) {
793  newOrientation = false;
794  for (NodeId x: order) {
795  if (!essentialGraph.parents(x).empty()) {
796  newOrientation |= propagatesRemainingOrientableEdges_(essentialGraph, x);
797  }
798  }
799  }
800  GUM_TRACE(essentialGraph.toDot());
802  GUM_TRACE(essentialGraph.toDot());
803 
804  // then decide the orientation for double arcs
805  for (NodeId x: order)
806  for (NodeId y: essentialGraph.parents(x))
807  if (essentialGraph.parents(y).contains(x)) {
808  GUM_TRACE(" + Resolving double arcs (poorly)")
809  essentialGraph.eraseArc(Arc(y, x));
810  }
811 
812  DAG dag;
813  for (auto node: essentialGraph) {
814  dag.addNodeWithId(node);
815  }
816  for (const Arc& arc: essentialGraph.arcs()) {
817  dag.addArc(arc.tail(), arc.head());
818  }
819 
820  return dag;
821  }
void propagatesOrientationInChainOfRemainingEdges_(MixedGraph &graph)
heuristic for remaining edges when everything else has been tried
Definition: Miic.cpp:856
bool isForbidenArc_(NodeId x, NodeId y) const
Definition: Miic.cpp:1169
bool propagatesRemainingOrientableEdges_(MixedGraph &graph, NodeId xj)
Propagates the orientation from a node to its neighbours.
Definition: Miic.cpp:898
MixedGraph learnMixedStructure(CorrectedMutualInformation<> &mutualInformation, MixedGraph graph)
learns the structure of an Essential Graph
Definition: Miic.cpp:106
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ maxIter()

INLINE Size gum::ApproximationScheme::maxIter ( ) const
virtualinherited

Returns the criterion on number of iterations.

Returns
Returns the criterion on number of iterations.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 91 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

91 { return max_iter_; }
Size max_iter_
The maximum iterations.
+ Here is the call graph for this function:

◆ maxTime()

INLINE double gum::ApproximationScheme::maxTime ( ) const
virtualinherited

Returns the timeout (in seconds).

Returns
Returns the timeout (in seconds).

Implements gum::IApproximationSchemeConfiguration.

Definition at line 112 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

112 { return max_time_; }
double max_time_
The timeout.
+ Here is the call graph for this function:

◆ messageApproximationScheme()

INLINE std::string gum::IApproximationSchemeConfiguration::messageApproximationScheme ( ) const
inherited

Returns the approximation scheme message.

Returns
Returns the approximation scheme message.

Definition at line 38 of file IApproximationSchemeConfiguration_inl.h.

References gum::Set< Key, Alloc >::emplace().

38  {
39  std::stringstream s;
40 
41  switch (stateApproximationScheme()) {
43  s << "in progress";
44  break;
45 
47  s << "stopped with epsilon=" << epsilon();
48  break;
49 
51  s << "stopped with rate=" << minEpsilonRate();
52  break;
53 
55  s << "stopped with max iteration=" << maxIter();
56  break;
57 
59  s << "stopped with timeout=" << maxTime();
60  break;
61 
63  s << "stopped on request";
64  break;
65 
67  s << "undefined state";
68  break;
69  };
70 
71  return s.str();
72  }
virtual double epsilon() const =0
Returns the value of epsilon.
virtual ApproximationSchemeSTATE stateApproximationScheme() const =0
Returns the approximation scheme state.
virtual double maxTime() const =0
Returns the timeout (in seconds).
virtual Size maxIter() const =0
Returns the criterion on number of iterations.
virtual double minEpsilonRate() const =0
Returns the value of the minimal epsilon rate.
+ Here is the call graph for this function:

◆ minEpsilonRate()

INLINE double gum::ApproximationScheme::minEpsilonRate ( ) const
virtualinherited

Returns the value of the minimal epsilon rate.

Returns
Returns the value of the minimal epsilon rate.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 71 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

71 { return min_rate_eps_; }
double min_rate_eps_
Threshold for the epsilon rate.
+ Here is the call graph for this function:

◆ nbrIterations()

INLINE Size gum::ApproximationScheme::nbrIterations ( ) const
virtualinherited

Returns the number of iterations.

Returns
Returns the number of iterations.
Exceptions
OperationNotAllowedRaised if the scheme did not perform.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 148 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

148  {
150  GUM_ERROR(OperationNotAllowed, "state of the approximation scheme is undefined")
151  }
152 
153  return current_step_;
154  }
ApproximationSchemeSTATE stateApproximationScheme() const
Returns the approximation scheme state.
Size current_step_
The current step.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ operator=() [1/2]

Miic & gum::learning::Miic::operator= ( const Miic from)

copy operator

Definition at line 63 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

63  {
64  ApproximationScheme::operator=(from);
65  return *this;
66  }
+ Here is the call graph for this function:

◆ operator=() [2/2]

Miic & gum::learning::Miic::operator= ( Miic &&  from)

move operator

Definition at line 69 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

69  {
70  ApproximationScheme::operator=(std::move(from));
71  return *this;
72  }
+ Here is the call graph for this function:

◆ orientation3off2_()

void gum::learning::Miic::orientation3off2_ ( CorrectedMutualInformation<> &  mutualInformation,
MixedGraph graph,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sepSet 
)
protected

Orientation phase from the 3off2 algorithm, returns a CPDAG.

Parameters
mutualInformationA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph returned from the previous phase
sepSetthe separation set for independent couples, built during the previous phase

Definition at line 222 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

225  {
226  std::vector< Ranking > triples = unshieldedTriples_(graph, mutualInformation, sepSet);
227  Size steps_orient = triples.size();
228  Size past_steps = current_step_;
229 
230  // marks always correspond to the head of the arc/edge. - is for a forbidden
231  // arc, > for a mandatory arc
232  // we start by adding the mandatory arcs
233  for (auto iter = _initialMarks_.begin(); iter != _initialMarks_.end(); ++iter) {
234  if (graph.existsEdge(iter.key().first, iter.key().second) && iter.val() == '>') {
235  graph.eraseEdge(Edge(iter.key().first, iter.key().second));
236  graph.addArc(iter.key().first, iter.key().second);
237  }
238  }
239 
240  NodeId i = 0;
241  // list of elements that we shouldn't read again, ie elements that are
242  // eligible to
243  // rule 0 after the first time they are tested, and elements on which rule 1
244  // has been applied
245  while (i < triples.size()) {
246  // if i not in do_not_reread
247  Ranking triple = triples[i];
248  NodeId x, y, z;
249  x = std::get< 0 >(*triple.first);
250  y = std::get< 1 >(*triple.first);
251  z = std::get< 2 >(*triple.first);
252 
253  std::vector< NodeId > ui;
254  std::pair< NodeId, NodeId > key = {x, y};
255  std::pair< NodeId, NodeId > rev_key = {y, x};
256  if (sepSet.exists(key)) {
257  ui = sepSet[key];
258  } else if (sepSet.exists(rev_key)) {
259  ui = sepSet[rev_key];
260  }
261  double Ixyz_ui = triple.second;
262  bool reset{false};
263  // try Rule 0
264  if (Ixyz_ui < 0) {
265  // if ( z not in Sep[x,y])
266  if (std::find(ui.begin(), ui.end(), z) == ui.end()) {
267  if (!graph.existsArc(x, z) && !graph.existsArc(z, x)) {
268  // when we try to add an arc to the graph, we always verify if
269  // we are allowed to do so, ie it is not a forbidden arc an it
270  // does not create a cycle
271  if (!_existsDirectedPath_(graph, z, x) && !isForbidenArc_(x, z)) {
272  reset = true;
273  graph.eraseEdge(Edge(x, z));
274  graph.addArc(x, z);
275  } else if (_existsDirectedPath_(graph, z, x) && !isForbidenArc_(z, x)) {
276  reset = true;
277  graph.eraseEdge(Edge(x, z));
278  // if we find a cycle, we force the competing edge
279  graph.addArc(z, x);
280  if (std::find(_latentCouples_.begin(), _latentCouples_.end(), Arc(z, x))
281  == _latentCouples_.end()) {
282  _latentCouples_.emplace_back(z, x);
283  }
284  }
285  } else if (!graph.existsArc(y, z) && !graph.existsArc(z, y)) {
286  if (!_existsDirectedPath_(graph, z, y) && !isForbidenArc_(x, z)) {
287  reset = true;
288  graph.eraseEdge(Edge(y, z));
289  graph.addArc(y, z);
290  } else if (_existsDirectedPath_(graph, z, y) && !isForbidenArc_(z, y)) {
291  reset = true;
292  graph.eraseEdge(Edge(y, z));
293  // if we find a cycle, we force the competing edge
294  graph.addArc(z, y);
295  if (std::find(_latentCouples_.begin(), _latentCouples_.end(), Arc(z, y))
296  == _latentCouples_.end()) {
297  _latentCouples_.emplace_back(z, y);
298  }
299  }
300  } else {
301  // checking if the anti-directed arc already exists, to register a
302  // latent variable
303  if (graph.existsArc(z, x) && _isNotLatentCouple_(z, x)) {
304  _latentCouples_.emplace_back(z, x);
305  }
306  if (graph.existsArc(z, y) && _isNotLatentCouple_(z, y)) {
307  _latentCouples_.emplace_back(z, y);
308  }
309  }
310  }
311  } else { // try Rule 1
312  if (graph.existsArc(x, z) && !graph.existsArc(z, y) && !graph.existsArc(y, z)) {
313  if (!_existsDirectedPath_(graph, y, z) && !isForbidenArc_(z, y)) {
314  reset = true;
315  graph.eraseEdge(Edge(z, y));
316  graph.addArc(z, y);
317  } else if (_existsDirectedPath_(graph, y, z) && !isForbidenArc_(y, z)) {
318  reset = true;
319  graph.eraseEdge(Edge(z, y));
320  // if we find a cycle, we force the competing edge
321  graph.addArc(y, z);
322  if (std::find(_latentCouples_.begin(), _latentCouples_.end(), Arc(y, z))
323  == _latentCouples_.end()) {
324  _latentCouples_.emplace_back(y, z);
325  }
326  }
327  }
328  if (graph.existsArc(y, z) && !graph.existsArc(z, x) && !graph.existsArc(x, z)) {
329  if (!_existsDirectedPath_(graph, x, z) && !isForbidenArc_(z, x)) {
330  reset = true;
331  graph.eraseEdge(Edge(z, x));
332  graph.addArc(z, x);
333  } else if (_existsDirectedPath_(graph, x, z) && !isForbidenArc_(x, z)) {
334  reset = true;
335  graph.eraseEdge(Edge(z, x));
336  // if we find a cycle, we force the competing edge
337  graph.addArc(x, z);
338  if (std::find(_latentCouples_.begin(), _latentCouples_.end(), Arc(x, z))
339  == _latentCouples_.end()) {
340  _latentCouples_.emplace_back(x, z);
341  }
342  }
343  }
344  } // if rule 0 or rule 1
345 
346  // if what we want to add already exists : pass to the next triplet
347  if (reset) {
348  i = 0;
349  } else {
350  ++i;
351  }
352  if (onProgress.hasListener()) {
354  ((current_step_ + i) * 100) / (past_steps + steps_orient),
355  0.,
356  timer_.step());
357  }
358  } // while
359 
360  // erasing the the double headed arcs
361  for (const Arc& arc: _latentCouples_) {
362  graph.eraseArc(Arc(arc.head(), arc.tail()));
363  }
364  }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
iterator begin()
Returns an unsafe iterator pointing to the beginning of the hashtable.
double step() const
Returns the delta time between now and the last reset() call (or the constructor).
Definition: timer_inl.h:41
Signaler3< Size, double, double > onProgress
Progression, error and time.
const iterator & end() noexcept
Returns the unsafe iterator pointing to the end of the hashtable.
std::pair< ThreePoints *, double > Ranking
Definition: Miic.h:61
bool isForbidenArc_(NodeId x, NodeId y) const
Definition: Miic.cpp:1169
static bool _existsDirectedPath_(const MixedGraph &graph, NodeId n1, NodeId n2)
checks for directed paths in a graph, consider double arcs like edges
Definition: Miic.cpp:962
HashTable< std::pair< NodeId, NodeId >, char > _initialMarks_
Initial marks for the orientation phase, used to convey constraints.
Definition: Miic.h:338
bool _isNotLatentCouple_(NodeId x, NodeId y)
Definition: Miic.cpp:1161
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
Size current_step_
The current step.
#define GUM_EMIT3(signal, arg1, arg2, arg3)
Definition: signaler3.h:41
std::vector< Ranking > unshieldedTriples_(const MixedGraph &graph, CorrectedMutualInformation<> &mutualInformation, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet)
gets the list of unshielded triples in the graph in decreasing value of |I&#39;(x, y, z|{ui})| ...
Definition: Miic.cpp:646
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ orientationLatents_()

void gum::learning::Miic::orientationLatents_ ( CorrectedMutualInformation<> &  mutualInformation,
MixedGraph graph,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sepSet 
)
protected

Modified version of the orientation phase that tries to propagate orientations from both orientations in case of a bidirected arc, not used.

variant trying to propagate both orientations in a bidirected arc

Parameters
mutualInformationA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph returned from the previous phase
sepSetthe separation set for independent couples, built during the previous phase

Definition at line 367 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

370  {
371  std::vector< Ranking > triples = unshieldedTriples_(graph, mutualInformation, sepSet);
372  Size steps_orient = triples.size();
373  Size past_steps = current_step_;
374 
375  NodeId i = 0;
376  // list of elements that we shouldnt read again, ie elements that are
377  // eligible to
378  // rule 0 after the first time they are tested, and elements on which rule 1
379  // has been applied
380  while (i < triples.size()) {
381  // if i not in do_not_reread
382  Ranking triple = triples[i];
383  NodeId x, y, z;
384  x = std::get< 0 >(*triple.first);
385  y = std::get< 1 >(*triple.first);
386  z = std::get< 2 >(*triple.first);
387 
388  std::vector< NodeId > ui;
389  std::pair< NodeId, NodeId > key = {x, y};
390  std::pair< NodeId, NodeId > rev_key = {y, x};
391  if (sepSet.exists(key)) {
392  ui = sepSet[key];
393  } else if (sepSet.exists(rev_key)) {
394  ui = sepSet[rev_key];
395  }
396  double Ixyz_ui = triple.second;
397  // try Rule 0
398  if (Ixyz_ui < 0) {
399  // if ( z not in Sep[x,y])
400  if (std::find(ui.begin(), ui.end(), z) == ui.end()) {
401  // if what we want to add already exists : pass
402  if ((graph.existsArc(x, z) || graph.existsArc(z, x))
403  && (graph.existsArc(y, z) || graph.existsArc(z, y))) {
404  ++i;
405  } else {
406  i = 0;
407  graph.eraseEdge(Edge(x, z));
408  graph.eraseEdge(Edge(y, z));
409  // checking for cycles
410  if (graph.existsArc(z, x)) {
411  graph.eraseArc(Arc(z, x));
412  try {
413  std::vector< NodeId > path = graph.directedPath(z, x);
414  // if we find a cycle, we force the competing edge
415  _latentCouples_.emplace_back(z, x);
416  } catch (gum::NotFound) { graph.addArc(x, z); }
417  graph.addArc(z, x);
418  } else {
419  try {
420  std::vector< NodeId > path = graph.directedPath(z, x);
421  // if we find a cycle, we force the competing edge
422  graph.addArc(z, x);
423  _latentCouples_.emplace_back(z, x);
424  } catch (gum::NotFound) { graph.addArc(x, z); }
425  }
426  if (graph.existsArc(z, y)) {
427  graph.eraseArc(Arc(z, y));
428  try {
429  std::vector< NodeId > path = graph.directedPath(z, y);
430  // if we find a cycle, we force the competing edge
431  _latentCouples_.emplace_back(z, y);
432  } catch (gum::NotFound) { graph.addArc(y, z); }
433  graph.addArc(z, y);
434  } else {
435  try {
436  std::vector< NodeId > path = graph.directedPath(z, y);
437  // if we find a cycle, we force the competing edge
438  graph.addArc(z, y);
439  _latentCouples_.emplace_back(z, y);
440 
441  } catch (gum::NotFound) { graph.addArc(y, z); }
442  }
443  if (graph.existsArc(z, x) && _isNotLatentCouple_(z, x)) {
444  _latentCouples_.emplace_back(z, x);
445  }
446  if (graph.existsArc(z, y) && _isNotLatentCouple_(z, y)) {
447  _latentCouples_.emplace_back(z, y);
448  }
449  }
450  } else {
451  ++i;
452  }
453  } else { // try Rule 1
454  bool reset{false};
455  if (graph.existsArc(x, z) && !graph.existsArc(z, y) && !graph.existsArc(y, z)) {
456  reset = true;
457  graph.eraseEdge(Edge(z, y));
458  try {
459  std::vector< NodeId > path = graph.directedPath(y, z);
460  // if we find a cycle, we force the competing edge
461  graph.addArc(y, z);
462  _latentCouples_.emplace_back(y, z);
463  } catch (gum::NotFound) { graph.addArc(z, y); }
464  }
465  if (graph.existsArc(y, z) && !graph.existsArc(z, x) && !graph.existsArc(x, z)) {
466  reset = true;
467  graph.eraseEdge(Edge(z, x));
468  try {
469  std::vector< NodeId > path = graph.directedPath(x, z);
470  // if we find a cycle, we force the competing edge
471  graph.addArc(x, z);
472  _latentCouples_.emplace_back(x, z);
473  } catch (gum::NotFound) { graph.addArc(z, x); }
474  }
475 
476  if (reset) {
477  i = 0;
478  } else {
479  ++i;
480  }
481  } // if rule 0 or rule 1
482  if (onProgress.hasListener()) {
484  ((current_step_ + i) * 100) / (past_steps + steps_orient),
485  0.,
486  timer_.step());
487  }
488  } // while
489 
490  // erasing the the double headed arcs
491  for (const Arc& arc: _latentCouples_) {
492  graph.eraseArc(Arc(arc.head(), arc.tail()));
493  }
494  }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
double step() const
Returns the delta time between now and the last reset() call (or the constructor).
Definition: timer_inl.h:41
Signaler3< Size, double, double > onProgress
Progression, error and time.
std::pair< ThreePoints *, double > Ranking
Definition: Miic.h:61
bool _isNotLatentCouple_(NodeId x, NodeId y)
Definition: Miic.cpp:1161
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
Size current_step_
The current step.
#define GUM_EMIT3(signal, arg1, arg2, arg3)
Definition: signaler3.h:41
std::vector< Ranking > unshieldedTriples_(const MixedGraph &graph, CorrectedMutualInformation<> &mutualInformation, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet)
gets the list of unshielded triples in the graph in decreasing value of |I&#39;(x, y, z|{ui})| ...
Definition: Miic.cpp:646
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ orientationMiic_()

void gum::learning::Miic::orientationMiic_ ( CorrectedMutualInformation<> &  mutualInformation,
MixedGraph graph,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sepSet 
)
protected

Orientation phase from the MIIC algorithm, returns a mixed graph that may contain circles.

varient using the orientation protocol of MIIC

Parameters
mutualInformationA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph returned from the previous phase
sepSetthe separation set for independent couples, built during the previous phase

Definition at line 497 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

500  {
501  // structure to store the orientations marks -, o, or >,
502  // Considers the head of the arc/edge first node -* second node
503  HashTable< std::pair< NodeId, NodeId >, char > marks = _initialMarks_;
504 
505  // marks always correspond to the head of the arc/edge. - is for a forbidden
506  // arc, > for a mandatory arc
507  // we start by adding the mandatory arcs
508  for (auto iter = marks.begin(); iter != marks.end(); ++iter) {
509  if (graph.existsEdge(iter.key().first, iter.key().second) && iter.val() == '>') {
510  graph.eraseEdge(Edge(iter.key().first, iter.key().second));
511  graph.addArc(iter.key().first, iter.key().second);
512  }
513  }
514 
515  std::vector< ProbabilisticRanking > proba_triples
516  = unshieldedTriplesMiic_(graph, mutualInformation, sepSet, marks);
517 
518  const Size steps_orient = proba_triples.size();
519  Size past_steps = current_step_;
520 
522  if (steps_orient > 0) { best = proba_triples[0]; }
523 
524  while (!proba_triples.empty() && std::max(std::get< 2 >(best), std::get< 3 >(best)) > 0.5) {
525  const NodeId x = std::get< 0 >(*std::get< 0 >(best));
526  const NodeId y = std::get< 1 >(*std::get< 0 >(best));
527  const NodeId z = std::get< 2 >(*std::get< 0 >(best));
528 
529  const double i3 = std::get< 1 >(best);
530 
531  const double p1 = std::get< 2 >(best);
532  const double p2 = std::get< 3 >(best);
533  if (i3 <= 0) {
534  _orientingVstructureMiic_(graph, marks, x, y, z, p1, p2);
535  } else {
536  _propagatingOrientationMiic_(graph, marks, x, y, z, p1, p2);
537  }
538 
539  delete std::get< 0 >(best);
540  proba_triples.erase(proba_triples.begin());
541  // actualisation of the list of triples
542  proba_triples = updateProbaTriples_(graph, proba_triples);
543 
544  if (!proba_triples.empty()) best = proba_triples[0];
545 
546  ++current_step_;
547  if (onProgress.hasListener()) {
549  (current_step_ * 100) / (steps_orient + past_steps),
550  0.,
551  timer_.step());
552  }
553  } // while
554 
555  // erasing the double headed arcs
556  for (auto iter = _latentCouples_.rbegin(); iter != _latentCouples_.rend(); ++iter) {
557  graph.eraseArc(Arc(iter->head(), iter->tail()));
558  if (_existsDirectedPath_(graph, iter->head(), iter->tail())) {
559  // if we find a cycle, we force the competing edge
560  graph.addArc(iter->head(), iter->tail());
561  graph.eraseArc(Arc(iter->tail(), iter->head()));
562  *iter = Arc(iter->head(), iter->tail());
563  }
564  }
565 
566  if (onProgress.hasListener()) { GUM_EMIT3(onProgress, 100, 0., timer_.step()); }
567  }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
double step() const
Returns the delta time between now and the last reset() call (or the constructor).
Definition: timer_inl.h:41
Signaler3< Size, double, double > onProgress
Progression, error and time.
std::vector< ProbabilisticRanking > updateProbaTriples_(const MixedGraph &graph, std::vector< ProbabilisticRanking > probaTriples)
Gets the orientation probabilities like MIIC for the orientation phase.
Definition: Miic.cpp:724
std::vector< ProbabilisticRanking > unshieldedTriplesMiic_(const MixedGraph &graph, CorrectedMutualInformation<> &mutualInformation, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sepSet, HashTable< std::pair< NodeId, NodeId >, char > &marks)
gets the list of unshielded triples in the graph in decreasing value of |I&#39;(x, y, z|{ui})|...
Definition: Miic.cpp:683
static bool _existsDirectedPath_(const MixedGraph &graph, NodeId n1, NodeId n2)
checks for directed paths in a graph, consider double arcs like edges
Definition: Miic.cpp:962
HashTable< std::pair< NodeId, NodeId >, char > _initialMarks_
Initial marks for the orientation phase, used to convey constraints.
Definition: Miic.h:338
void _propagatingOrientationMiic_(MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, char > &marks, NodeId x, NodeId y, NodeId z, double p1, double p2)
Definition: Miic.cpp:1089
std::tuple< ThreePoints *, double, double, double > ProbabilisticRanking
Definition: Miic.h:63
void _orientingVstructureMiic_(MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, char > &marks, NodeId x, NodeId y, NodeId z, double p1, double p2)
Definition: Miic.cpp:996
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
Size current_step_
The current step.
#define GUM_EMIT3(signal, arg1, arg2, arg3)
Definition: signaler3.h:41
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ periodSize()

INLINE Size gum::ApproximationScheme::periodSize ( ) const
virtualinherited

Returns the period size.

Returns
Returns the period size.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 134 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

134 { return period_size_; }
Size period_size_
Checking criteria frequency.
+ Here is the call graph for this function:

◆ propagatesOrientationInChainOfRemainingEdges_()

void gum::learning::Miic::propagatesOrientationInChainOfRemainingEdges_ ( MixedGraph graph)
protected

heuristic for remaining edges when everything else has been tried

Definition at line 856 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

856  {
857  // then decide the orientation for remaining edges
858  while (!essentialGraph.edges().empty()) {
859  const auto& edge = *(essentialGraph.edges().begin());
860  NodeId root = edge.first();
861  Size size_children_root = essentialGraph.children(root).size();
862  NodeSet visited;
863  NodeSet stack{root};
864  // check the best root for the set of neighbours
865  while (!stack.empty()) {
866  NodeId next = *(stack.begin());
867  stack.erase(next);
868  if (visited.contains(next)) continue;
869  if (essentialGraph.children(next).size() > size_children_root) {
870  size_children_root = essentialGraph.children(next).size();
871  root = next;
872  }
873  for (const auto n: essentialGraph.neighbours(next))
874  if (!stack.contains(n) && !visited.contains(n)) stack.insert(n);
875  visited.insert(next);
876  }
877  // orientation now
878  visited.clear();
879  stack.clear();
880  stack.insert(root);
881  while (!stack.empty()) {
882  NodeId next = *(stack.begin());
883  stack.erase(next);
884  if (visited.contains(next)) continue;
885  const auto nei = essentialGraph.neighbours(next);
886  for (const auto n: nei) {
887  if (!stack.contains(n) && !visited.contains(n)) stack.insert(n);
888  GUM_TRACE(" + amap reasonably orientation for " << n << "->" << next);
889  essentialGraph.eraseEdge(Edge(n, next));
890  essentialGraph.addArc(n, next);
891  }
892  visited.insert(next);
893  }
894  }
895  }
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ propagatesRemainingOrientableEdges_()

bool gum::learning::Miic::propagatesRemainingOrientableEdges_ ( MixedGraph graph,
NodeId  xj 
)
protected

Propagates the orientation from a node to its neighbours.

Definition at line 898 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

898  {
899  bool res = false;
900  const auto neighbours = graph.neighbours(xj);
901  for (auto& xi: neighbours) {
902  bool i_j = isOrientable_(graph, xi, xj);
903  bool j_i = isOrientable_(graph, xj, xi);
904  if (i_j || j_i) {
905  GUM_TRACE(" + Removing edge (" << xi << "," << xj << ")")
906  graph.eraseEdge(Edge(xi, xj));
907  res = true;
908  }
909  if (i_j) {
910  GUM_TRACE(" + add arc (" << xi << "," << xj << ")")
911  graph.addArc(xi, xj);
913  }
914  if (j_i) {
915  GUM_TRACE(" + add arc (" << xi << "," << xj << ")")
916  graph.addArc(xj, xi);
918  }
919  if (i_j && j_i) {
920  GUM_TRACE(" + add arc (" << xi << "," << xj << ")")
921  _latentCouples_.emplace_back(xi, xj);
922  }
923  }
924 
925  return res;
926  }
std::vector< Arc > _latentCouples_
an empty vector of arcs
Definition: Miic.h:327
bool isOrientable_(const MixedGraph &graph, NodeId xi, NodeId xj) const
Definition: Miic.cpp:823
bool propagatesRemainingOrientableEdges_(MixedGraph &graph, NodeId xj)
Propagates the orientation from a node to its neighbours.
Definition: Miic.cpp:898
+ Here is the call graph for this function:

◆ remainingBurnIn()

INLINE Size gum::ApproximationScheme::remainingBurnIn ( )
inherited

Returns the remaining burn in.

Returns
Returns the remaining burn in.

Definition at line 191 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

191  {
192  if (burn_in_ > current_step_) {
193  return burn_in_ - current_step_;
194  } else {
195  return 0;
196  }
197  }
Size burn_in_
Number of iterations before checking stopping criteria.
Size current_step_
The current step.
+ Here is the call graph for this function:

◆ set3of2Behaviour()

void gum::learning::Miic::set3of2Behaviour ( )

Sets the orientation phase to follow the one of the 3off2 algorithm.

Definition at line 942 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

942 { this->_useMiic_ = false; }
bool _useMiic_
wether to use the miic algorithm or not
Definition: Miic.h:332
+ Here is the call graph for this function:

◆ setEpsilon()

INLINE void gum::ApproximationScheme::setEpsilon ( double  eps)
virtualinherited

Given that we approximate f(t), stopping criterion on |f(t+1)-f(t)|.

If the criterion was disabled it will be enabled.

Parameters
epsThe new epsilon value.
Exceptions
OutOfBoundsRaised if eps < 0.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 42 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

42  {
43  if (eps < 0.) { GUM_ERROR(OutOfBounds, "eps should be >=0") }
44 
45  eps_ = eps;
46  enabled_eps_ = true;
47  }
double eps_
Threshold for convergence.
bool enabled_eps_
If true, the threshold convergence is enabled.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ setMaxIter()

INLINE void gum::ApproximationScheme::setMaxIter ( Size  max)
virtualinherited

Stopping criterion on number of iterations.

If the criterion was disabled it will be enabled.

Parameters
maxThe maximum number of iterations.
Exceptions
OutOfBoundsRaised if max <= 1.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 84 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

84  {
85  if (max < 1) { GUM_ERROR(OutOfBounds, "max should be >=1") }
86  max_iter_ = max;
87  enabled_max_iter_ = true;
88  }
bool enabled_max_iter_
If true, the maximum iterations stopping criterion is enabled.
Size max_iter_
The maximum iterations.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ setMaxTime()

INLINE void gum::ApproximationScheme::setMaxTime ( double  timeout)
virtualinherited

Stopping criterion on timeout.

If the criterion was disabled it will be enabled.

Parameters
timeoutThe timeout value in seconds.
Exceptions
OutOfBoundsRaised if timeout <= 0.0.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 105 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

105  {
106  if (timeout <= 0.) { GUM_ERROR(OutOfBounds, "timeout should be >0.") }
107  max_time_ = timeout;
108  enabled_max_time_ = true;
109  }
double max_time_
The timeout.
bool enabled_max_time_
If true, the timeout is enabled.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ setMiicBehaviour()

void gum::learning::Miic::setMiicBehaviour ( )

Sets the orientation phase to follow the one of the MIIC algorithm.

Definition at line 940 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

940 { this->_useMiic_ = true; }
bool _useMiic_
wether to use the miic algorithm or not
Definition: Miic.h:332
+ Here is the call graph for this function:

◆ setMinEpsilonRate()

INLINE void gum::ApproximationScheme::setMinEpsilonRate ( double  rate)
virtualinherited

Given that we approximate f(t), stopping criterion on d/dt(|f(t+1)-f(t)|).

If the criterion was disabled it will be enabled

Parameters
rateThe minimal epsilon rate.
Exceptions
OutOfBoundsif rate<0

Implements gum::IApproximationSchemeConfiguration.

Definition at line 63 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

63  {
64  if (rate < 0) { GUM_ERROR(OutOfBounds, "rate should be >=0") }
65 
66  min_rate_eps_ = rate;
67  enabled_min_rate_eps_ = true;
68  }
double min_rate_eps_
Threshold for the epsilon rate.
bool enabled_min_rate_eps_
If true, the minimal threshold for epsilon rate is enabled.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ setPeriodSize()

INLINE void gum::ApproximationScheme::setPeriodSize ( Size  p)
virtualinherited

How many samples between two stopping is enable.

Parameters
pThe new period value.
Exceptions
OutOfBoundsRaised if p < 1.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 128 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

128  {
129  if (p < 1) { GUM_ERROR(OutOfBounds, "p should be >=1") }
130 
131  period_size_ = p;
132  }
Size period_size_
Checking criteria frequency.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ setVerbosity()

INLINE void gum::ApproximationScheme::setVerbosity ( bool  v)
virtualinherited

Set the verbosity on (true) or off (false).

Parameters
vIf true, then verbosity is turned on.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 137 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

137 { verbosity_ = v; }
bool verbosity_
If true, verbosity is enabled.
+ Here is the call graph for this function:

◆ startOfPeriod()

INLINE bool gum::ApproximationScheme::startOfPeriod ( )
inherited

Returns true if we are at the beginning of a period (compute error is mandatory).

Returns
Returns true if we are at the beginning of a period (compute error is mandatory).

Definition at line 178 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

178  {
179  if (current_step_ < burn_in_) { return false; }
180 
181  if (period_size_ == 1) { return true; }
182 
183  return ((current_step_ - burn_in_) % period_size_ == 0);
184  }
Size burn_in_
Number of iterations before checking stopping criteria.
Size period_size_
Checking criteria frequency.
Size current_step_
The current step.
+ Here is the call graph for this function:

◆ stateApproximationScheme()

INLINE IApproximationSchemeConfiguration::ApproximationSchemeSTATE gum::ApproximationScheme::stateApproximationScheme ( ) const
virtualinherited

Returns the approximation scheme state.

Returns
Returns the approximation scheme state.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 143 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

143  {
144  return current_state_;
145  }
ApproximationSchemeSTATE current_state_
The current state.
+ Here is the call graph for this function:

◆ stopApproximationScheme()

INLINE void gum::ApproximationScheme::stopApproximationScheme ( )
inherited

Stop the approximation scheme.

Definition at line 200 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

+ Here is the call graph for this function:

◆ unshieldedTriples_()

std::vector< Ranking > gum::learning::Miic::unshieldedTriples_ ( const MixedGraph graph,
CorrectedMutualInformation<> &  mutualInformation,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sepSet 
)
protected

gets the list of unshielded triples in the graph in decreasing value of |I'(x, y, z|{ui})|

Definition at line 646 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

649  {
650  std::vector< Ranking > triples;
651  for (NodeId z: graph) {
652  for (NodeId x: graph.neighbours(z)) {
653  for (NodeId y: graph.neighbours(z)) {
654  if (y < x && !graph.existsEdge(x, y)) {
655  std::vector< NodeId > ui;
656  std::pair< NodeId, NodeId > key = {x, y};
657  std::pair< NodeId, NodeId > rev_key = {y, x};
658  if (sepSet.exists(key)) {
659  ui = sepSet[key];
660  } else if (sepSet.exists(rev_key)) {
661  ui = sepSet[rev_key];
662  }
663  // remove z from ui if it's present
664  const auto iter_z_place = std::find(ui.begin(), ui.end(), z);
665  if (iter_z_place != ui.end()) { ui.erase(iter_z_place); }
666 
667  double Ixyz_ui = mutualInformation.score(x, y, z, ui);
668  Ranking triple;
669  auto tup = new ThreePoints{x, y, z};
670  triple.first = tup;
671  triple.second = Ixyz_ui;
672  triples.push_back(triple);
673  }
674  }
675  }
676  }
677  std::sort(triples.begin(), triples.end(), GreaterAbsPairOn2nd());
678  return triples;
679  }
std::pair< ThreePoints *, double > Ranking
Definition: Miic.h:61
std::tuple< NodeId, NodeId, NodeId > ThreePoints
Definition: Miic.h:60
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ unshieldedTriplesMiic_()

std::vector< ProbabilisticRanking > gum::learning::Miic::unshieldedTriplesMiic_ ( const MixedGraph graph,
CorrectedMutualInformation<> &  mutualInformation,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sepSet,
HashTable< std::pair< NodeId, NodeId >, char > &  marks 
)
protected

gets the list of unshielded triples in the graph in decreasing value of |I'(x, y, z|{ui})|, prepares the orientation matrix for MIIC

Definition at line 683 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

687  {
688  std::vector< ProbabilisticRanking > triples;
689  for (NodeId z: graph) {
690  for (NodeId x: graph.neighbours(z)) {
691  for (NodeId y: graph.neighbours(z)) {
692  if (y < x && !graph.existsEdge(x, y)) {
693  std::vector< NodeId > ui;
694  std::pair< NodeId, NodeId > key = {x, y};
695  std::pair< NodeId, NodeId > rev_key = {y, x};
696  if (sepSet.exists(key)) {
697  ui = sepSet[key];
698  } else if (sepSet.exists(rev_key)) {
699  ui = sepSet[rev_key];
700  }
701  // remove z from ui if it's present
702  const auto iter_z_place = std::find(ui.begin(), ui.end(), z);
703  if (iter_z_place != ui.end()) { ui.erase(iter_z_place); }
704 
705  const double Ixyz_ui = mutualInformation.score(x, y, z, ui);
706  auto tup = new ThreePoints{x, y, z};
707  ProbabilisticRanking triple{tup, Ixyz_ui, 0.5, 0.5};
708  triples.push_back(triple);
709  if (!marks.exists({x, z})) { marks.insert({x, z}, 'o'); }
710  if (!marks.exists({z, x})) { marks.insert({z, x}, 'o'); }
711  if (!marks.exists({y, z})) { marks.insert({y, z}, 'o'); }
712  if (!marks.exists({z, y})) { marks.insert({z, y}, 'o'); }
713  }
714  }
715  }
716  }
717  triples = updateProbaTriples_(graph, triples);
718  std::sort(triples.begin(), triples.end(), GreaterTupleOnLast());
719  return triples;
720  }
std::vector< ProbabilisticRanking > updateProbaTriples_(const MixedGraph &graph, std::vector< ProbabilisticRanking > probaTriples)
Gets the orientation probabilities like MIIC for the orientation phase.
Definition: Miic.cpp:724
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
std::tuple< NodeId, NodeId, NodeId > ThreePoints
Definition: Miic.h:60
std::tuple< ThreePoints *, double, double, double > ProbabilisticRanking
Definition: Miic.h:63
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ updateApproximationScheme()

INLINE void gum::ApproximationScheme::updateApproximationScheme ( unsigned int  incr = 1)
inherited

Update the scheme w.r.t the new error and increment steps.

Parameters
incrThe new increment steps.

Definition at line 187 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

187  {
188  current_step_ += incr;
189  }
Size current_step_
The current step.
+ Here is the call graph for this function:

◆ updateProbaTriples_()

std::vector< ProbabilisticRanking > gum::learning::Miic::updateProbaTriples_ ( const MixedGraph graph,
std::vector< ProbabilisticRanking probaTriples 
)
protected

Gets the orientation probabilities like MIIC for the orientation phase.

Definition at line 724 of file Miic.cpp.

References gum::learning::genericBNLearner::Database::Database().

725  {
726  for (auto& triple: probaTriples) {
727  NodeId x, y, z;
728  x = std::get< 0 >(*std::get< 0 >(triple));
729  y = std::get< 1 >(*std::get< 0 >(triple));
730  z = std::get< 2 >(*std::get< 0 >(triple));
731  const double Ixyz = std::get< 1 >(triple);
732  double Pxz = std::get< 2 >(triple);
733  double Pyz = std::get< 3 >(triple);
734 
735  if (Ixyz <= 0) {
736  const double expo = std::exp(Ixyz);
737  const double P0 = (1 + expo) / (1 + 3 * expo);
738  // distinguish between the initialization and the update process
739  if (Pxz == Pyz && Pyz == 0.5) {
740  std::get< 2 >(triple) = P0;
741  std::get< 3 >(triple) = P0;
742  } else {
743  if (graph.existsArc(x, z) && Pxz >= P0) {
744  std::get< 3 >(triple) = Pxz * (1 / (1 + expo) - 0.5) + 0.5;
745  } else if (graph.existsArc(y, z) && Pyz >= P0) {
746  std::get< 2 >(triple) = Pyz * (1 / (1 + expo) - 0.5) + 0.5;
747  }
748  }
749  } else {
750  const double expo = std::exp(-Ixyz);
751  if (graph.existsArc(x, z) && Pxz >= 0.5) {
752  std::get< 3 >(triple) = Pxz * (1 / (1 + expo) - 0.5) + 0.5;
753  } else if (graph.existsArc(y, z) && Pyz >= 0.5) {
754  std::get< 2 >(triple) = Pyz * (1 / (1 + expo) - 0.5) + 0.5;
755  }
756  }
757  }
758  std::sort(probaTriples.begin(), probaTriples.end(), GreaterTupleOnLast());
759  return probaTriples;
760  }
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ verbosity()

INLINE bool gum::ApproximationScheme::verbosity ( ) const
virtualinherited

Returns true if verbosity is enabled.

Returns
Returns true if verbosity is enabled.

Implements gum::IApproximationSchemeConfiguration.

Definition at line 139 of file approximationScheme_inl.h.

References gum::Set< Key, Alloc >::emplace().

139 { return verbosity_; }
bool verbosity_
If true, verbosity is enabled.
+ Here is the call graph for this function:

Member Data Documentation

◆ _arcProbas_

ArcProperty< double > gum::learning::Miic::_arcProbas_
private

Storing the propabilities for each arc set in the graph.

Definition at line 335 of file Miic.h.

◆ _emptySet_

const std::vector< NodeId > gum::learning::Miic::_emptySet_
private

an empty conditioning set

Definition at line 325 of file Miic.h.

◆ _initialMarks_

HashTable< std::pair< NodeId, NodeId >, char > gum::learning::Miic::_initialMarks_
private

Initial marks for the orientation phase, used to convey constraints.

Definition at line 338 of file Miic.h.

◆ _latentCouples_

std::vector< Arc > gum::learning::Miic::_latentCouples_
private

an empty vector of arcs

Definition at line 327 of file Miic.h.

◆ _maxLog_

int gum::learning::Miic::_maxLog_ = 100
private

Fixes the maximum log that we accept in exponential computations.

Definition at line 323 of file Miic.h.

◆ _size_

Size gum::learning::Miic::_size_
private

size of the database

Definition at line 330 of file Miic.h.

◆ _useMiic_

bool gum::learning::Miic::_useMiic_ {false}
private

wether to use the miic algorithm or not

Definition at line 332 of file Miic.h.

◆ burn_in_

Size gum::ApproximationScheme::burn_in_
protectedinherited

Number of iterations before checking stopping criteria.

Definition at line 413 of file approximationScheme.h.

◆ current_epsilon_

double gum::ApproximationScheme::current_epsilon_
protectedinherited

Current epsilon.

Definition at line 368 of file approximationScheme.h.

◆ current_rate_

double gum::ApproximationScheme::current_rate_
protectedinherited

Current rate.

Definition at line 374 of file approximationScheme.h.

◆ current_state_

ApproximationSchemeSTATE gum::ApproximationScheme::current_state_
protectedinherited

The current state.

Definition at line 383 of file approximationScheme.h.

◆ current_step_

Size gum::ApproximationScheme::current_step_
protectedinherited

The current step.

Definition at line 377 of file approximationScheme.h.

◆ enabled_eps_

bool gum::ApproximationScheme::enabled_eps_
protectedinherited

If true, the threshold convergence is enabled.

Definition at line 392 of file approximationScheme.h.

◆ enabled_max_iter_

bool gum::ApproximationScheme::enabled_max_iter_
protectedinherited

If true, the maximum iterations stopping criterion is enabled.

Definition at line 410 of file approximationScheme.h.

◆ enabled_max_time_

bool gum::ApproximationScheme::enabled_max_time_
protectedinherited

If true, the timeout is enabled.

Definition at line 404 of file approximationScheme.h.

◆ enabled_min_rate_eps_

bool gum::ApproximationScheme::enabled_min_rate_eps_
protectedinherited

If true, the minimal threshold for epsilon rate is enabled.

Definition at line 398 of file approximationScheme.h.

◆ eps_

double gum::ApproximationScheme::eps_
protectedinherited

Threshold for convergence.

Definition at line 389 of file approximationScheme.h.

◆ history_

std::vector< double > gum::ApproximationScheme::history_
protectedinherited

The scheme history, used only if verbosity == true.

Definition at line 386 of file approximationScheme.h.

◆ last_epsilon_

double gum::ApproximationScheme::last_epsilon_
protectedinherited

Last epsilon value.

Definition at line 371 of file approximationScheme.h.

◆ max_iter_

Size gum::ApproximationScheme::max_iter_
protectedinherited

The maximum iterations.

Definition at line 407 of file approximationScheme.h.

◆ max_time_

double gum::ApproximationScheme::max_time_
protectedinherited

The timeout.

Definition at line 401 of file approximationScheme.h.

◆ min_rate_eps_

double gum::ApproximationScheme::min_rate_eps_
protectedinherited

Threshold for the epsilon rate.

Definition at line 395 of file approximationScheme.h.

◆ onProgress

Signaler3< Size, double, double > gum::IApproximationSchemeConfiguration::onProgress
inherited

Progression, error and time.

Definition at line 58 of file IApproximationSchemeConfiguration.h.

◆ onStop

Signaler1< std::string > gum::IApproximationSchemeConfiguration::onStop
inherited

Criteria messageApproximationScheme.

Definition at line 61 of file IApproximationSchemeConfiguration.h.

◆ period_size_

Size gum::ApproximationScheme::period_size_
protectedinherited

Checking criteria frequency.

Definition at line 416 of file approximationScheme.h.

◆ timer_

Timer gum::ApproximationScheme::timer_
protectedinherited

The timer.

Definition at line 380 of file approximationScheme.h.

◆ verbosity_

bool gum::ApproximationScheme::verbosity_
protectedinherited

If true, verbosity is enabled.

Definition at line 419 of file approximationScheme.h.


The documentation for this class was generated from the following files: