aGrUM  0.20.3
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 974 of file Miic.cpp.

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

974  {
975  // not recursive version => use a FIFO for simulating the recursion
976  List< NodeId > nodeFIFO;
977  // mark[node] = successor if visited, else mark[node] does not exist
978  Set< NodeId > mark;
979 
980  mark.insert(n2);
981  nodeFIFO.pushBack(n2);
982 
983  NodeId current;
984 
985  while (!nodeFIFO.empty()) {
986  current = nodeFIFO.front();
987  nodeFIFO.popFront();
988 
989  // check the parents
990  for (const auto new_one: graph.parents(current)) {
991  if (graph.existsArc(current,
992  new_one)) // if there is a double arc, pass
993  continue;
994 
995  if (new_one == n1) { return true; }
996 
997  if (mark.exists(new_one)) // if this node is already marked, do not
998  continue; // check it again
999 
1000  mark.insert(new_one);
1001  nodeFIFO.pushBack(new_one);
1002  }
1003  }
1004 
1005  return false;
1006  }
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 960 of file Miic.cpp.

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

962  {
963  for (const auto parent: graph.parents(n2)) {
964  if (graph.existsArc(parent,
965  n2)) // if there is a double arc, pass
966  continue;
967  if (parent == n1) // trivial directed path => not recognized
968  continue;
969  if (_existsDirectedPath_(graph, n1, parent)) return true;
970  }
971  return false;
972  }
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:974
+ Here is the call graph for this function:

◆ _isNotLatentCouple_()

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

Definition at line 1173 of file Miic.cpp.

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

1173  {
1174  const auto& lbeg = _latentCouples_.begin();
1175  const auto& lend = _latentCouples_.end();
1176 
1177  return (std::find(lbeg, lend, Arc(x, y)) == lend)
1178  && (std::find(lbeg, lend, Arc(y, x)) == lend);
1179  }
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 1008 of file Miic.cpp.

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

1014  {
1015  // v-structure discovery
1016  if (marks[{x, z}] == 'o' && marks[{y, z}] == 'o') { // If x-z-y
1017  if (!_existsNonTrivialDirectedPath_(graph, z, x)) {
1018  graph.eraseEdge(Edge(x, z));
1019  graph.addArc(x, z);
1020  GUM_TRACE("1.a Removing edge (" << x << "," << z << ")")
1021  GUM_TRACE("1.a Adding arc (" << x << "," << z << ")")
1022  marks[{x, z}] = '>';
1023  if (graph.existsArc(z, x) && _isNotLatentCouple_(z, x)) {
1024  GUM_TRACE("Adding latent couple (" << z << "," << x << ")")
1025  _latentCouples_.emplace_back(z, x);
1026  }
1027  if (!_arcProbas_.exists(Arc(x, z))) _arcProbas_.insert(Arc(x, z), p1);
1028  } else {
1029  graph.eraseEdge(Edge(x, z));
1030  GUM_TRACE("1.b Adding arc (" << x << "," << z << ")")
1031  if (!_existsNonTrivialDirectedPath_(graph, x, z)) {
1032  graph.addArc(z, x);
1033  GUM_TRACE("1.b Removing edge (" << x << "," << z << ")")
1034  marks[{z, x}] = '>';
1035  }
1036  }
1037 
1038  if (!_existsNonTrivialDirectedPath_(graph, z, y)) {
1039  graph.eraseEdge(Edge(y, z));
1040  graph.addArc(y, z);
1041  GUM_TRACE("1.c Removing edge (" << y << "," << z << ")")
1042  GUM_TRACE("1.c Adding arc (" << y << "," << z << ")")
1043  marks[{y, z}] = '>';
1044  if (graph.existsArc(z, y) && _isNotLatentCouple_(z, y)) {
1045  _latentCouples_.emplace_back(z, y);
1046  }
1047  if (!_arcProbas_.exists(Arc(y, z))) _arcProbas_.insert(Arc(y, z), p2);
1048  } else {
1049  graph.eraseEdge(Edge(y, z));
1050  GUM_TRACE("1.d Removing edge (" << y << "," << z << ")")
1051  if (!_existsNonTrivialDirectedPath_(graph, y, z)) {
1052  graph.addArc(z, y);
1053  GUM_TRACE("1.d Adding arc (" << z << "," << y << ")")
1054  marks[{z, y}] = '>';
1055  }
1056  }
1057  } else if (marks[{x, z}] == '>' && marks[{y, z}] == 'o') { // If x->z-y
1058  if (!_existsNonTrivialDirectedPath_(graph, z, y)) {
1059  graph.eraseEdge(Edge(y, z));
1060  graph.addArc(y, z);
1061  GUM_TRACE("2.a Removing edge (" << y << "," << z << ")")
1062  GUM_TRACE("2.a Adding arc (" << y << "," << z << ")")
1063  marks[{y, z}] = '>';
1064  if (graph.existsArc(z, y) && _isNotLatentCouple_(z, y)) {
1065  _latentCouples_.emplace_back(z, y);
1066  }
1067  if (!_arcProbas_.exists(Arc(y, z))) _arcProbas_.insert(Arc(y, z), p2);
1068  } else {
1069  graph.eraseEdge(Edge(y, z));
1070  GUM_TRACE("2.b Removing edge (" << y << "," << z << ")")
1071  if (!_existsNonTrivialDirectedPath_(graph, y, z)) {
1072  graph.addArc(z, y);
1073  GUM_TRACE("2.b Adding arc (" << y << "," << z << ")")
1074  marks[{z, y}] = '>';
1075  }
1076  }
1077  } else if (marks[{y, z}] == '>' && marks[{x, z}] == 'o') {
1078  if (!_existsNonTrivialDirectedPath_(graph, z, x)) {
1079  graph.eraseEdge(Edge(x, z));
1080  graph.addArc(x, z);
1081  GUM_TRACE("3.a Removing edge (" << x << "," << z << ")")
1082  GUM_TRACE("3.a Adding arc (" << x << "," << z << ")")
1083  marks[{x, z}] = '>';
1084  if (graph.existsArc(z, x) && _isNotLatentCouple_(z, x)) {
1085  _latentCouples_.emplace_back(z, x);
1086  }
1087  if (!_arcProbas_.exists(Arc(x, z))) _arcProbas_.insert(Arc(x, z), p1);
1088  } else {
1089  graph.eraseEdge(Edge(x, z));
1090  GUM_TRACE("3.b Removing edge (" << x << "," << z << ")")
1091  if (!_existsNonTrivialDirectedPath_(graph, x, z)) {
1092  graph.addArc(z, x);
1093  GUM_TRACE("3.b Adding arc (" << x << "," << z << ")")
1094  marks[{z, x}] = '>';
1095  }
1096  }
1097  }
1098  }
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:1173
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:960
+ 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 1101 of file Miic.cpp.

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

1107  {
1108  // orientation propagation
1109  if (marks[{x, z}] == '>' && marks[{y, z}] == 'o' && marks[{z, y}] != '-') {
1110  graph.eraseEdge(Edge(z, y));
1111  // std::cout << "4. Removing edge (" << z << "," << y << ")" <<
1112  // std::endl;
1113  if (!_existsDirectedPath_(graph, y, z) && graph.parents(y).empty()) {
1114  graph.addArc(z, y);
1115  GUM_TRACE("4.a Adding arc (" << z << "," << y << ")")
1116  marks[{z, y}] = '>';
1117  marks[{y, z}] = '-';
1118  if (!_arcProbas_.exists(Arc(z, y))) _arcProbas_.insert(Arc(z, y), p2);
1119  } else if (!_existsDirectedPath_(graph, z, y) && graph.parents(z).empty()) {
1120  graph.addArc(y, z);
1121  GUM_TRACE("4.b Adding arc (" << y << "," << z << ")")
1122  marks[{z, y}] = '-';
1123  marks[{y, z}] = '>';
1124  _latentCouples_.emplace_back(y, z);
1125  if (!_arcProbas_.exists(Arc(y, z))) _arcProbas_.insert(Arc(y, z), p2);
1126  } else if (!_existsDirectedPath_(graph, y, z)) {
1127  graph.addArc(z, y);
1128  GUM_TRACE("4.c Adding arc (" << z << "," << y << ")")
1129  marks[{z, y}] = '>';
1130  marks[{y, z}] = '-';
1131  if (!_arcProbas_.exists(Arc(z, y))) _arcProbas_.insert(Arc(z, y), p2);
1132  } else if (!_existsDirectedPath_(graph, z, y)) {
1133  graph.addArc(y, z);
1134  GUM_TRACE("4.d Adding arc (" << y << "," << z << ")")
1135  _latentCouples_.emplace_back(y, z);
1136  marks[{z, y}] = '-';
1137  marks[{y, z}] = '>';
1138  if (!_arcProbas_.exists(Arc(y, z))) _arcProbas_.insert(Arc(y, z), p2);
1139  }
1140  } else if (marks[{y, z}] == '>' && marks[{x, z}] == 'o' && marks[{z, x}] != '-') {
1141  graph.eraseEdge(Edge(z, x));
1142  GUM_TRACE("5. Removing edge (" << z << "," << x << ")")
1143  if (!_existsDirectedPath_(graph, x, z) && graph.parents(x).empty()) {
1144  graph.addArc(z, x);
1145  GUM_TRACE("5.a Adding arc (" << z << "," << x << ")")
1146  marks[{z, x}] = '>';
1147  marks[{x, z}] = '-';
1148  if (!_arcProbas_.exists(Arc(z, x))) _arcProbas_.insert(Arc(z, x), p1);
1149  } else if (!_existsDirectedPath_(graph, z, x) && graph.parents(z).empty()) {
1150  graph.addArc(x, z);
1151  GUM_TRACE("5.b Adding arc (" << x << "," << z << ")")
1152  marks[{z, x}] = '-';
1153  marks[{x, z}] = '>';
1154  _latentCouples_.emplace_back(x, z);
1155  if (!_arcProbas_.exists(Arc(x, z))) _arcProbas_.insert(Arc(x, z), p1);
1156  } else if (!_existsDirectedPath_(graph, x, z)) {
1157  graph.addArc(z, x);
1158  GUM_TRACE("5.c Adding arc (" << z << "," << x << ")")
1159  marks[{z, x}] = '>';
1160  marks[{x, z}] = '-';
1161  if (!_arcProbas_.exists(Arc(z, x))) _arcProbas_.insert(Arc(z, x), p1);
1162  } else if (!_existsDirectedPath_(graph, z, x)) {
1163  graph.addArc(x, z);
1164  GUM_TRACE("5.d Adding arc (" << x << "," << z << ")")
1165  marks[{z, x}] = '-';
1166  marks[{x, z}] = '>';
1167  _latentCouples_.emplace_back(x, z);
1168  if (!_arcProbas_.exists(Arc(x, z))) _arcProbas_.insert(Arc(x, z), p1);
1169  }
1170  }
1171  }
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:974
+ 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 956 of file Miic.cpp.

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

956  {
957  this->_initialMarks_ = constraints;
958  }
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 574 of file Miic.cpp.

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

579  {
580  double maxP = -1.0;
581  NodeId maxZ = 0;
582 
583  // compute N
584  // __N = I.N();
585  const double Ixy_ui = mutualInformation.score(x, y, ui);
586 
587  for (const NodeId z: graph) {
588  // if z!=x and z!=y and z not in ui
589  if (z != x && z != y && std::find(ui.begin(), ui.end(), z) == ui.end()) {
590  double Pnv;
591  double Pb;
592 
593  // Computing Pnv
594  const double Ixyz_ui = mutualInformation.score(x, y, z, ui);
595  double calc_expo1 = -Ixyz_ui * M_LN2;
596  // if exponentials are too high or to low, crop them at | __maxLog|
597  if (calc_expo1 > _maxLog_) {
598  Pnv = 0.0;
599  } else if (calc_expo1 < -_maxLog_) {
600  Pnv = 1.0;
601  } else {
602  Pnv = 1 / (1 + std::exp(calc_expo1));
603  }
604 
605  // Computing Pb
606  const double Ixz_ui = mutualInformation.score(x, z, ui);
607  const double Iyz_ui = mutualInformation.score(y, z, ui);
608 
609  calc_expo1 = -(Ixz_ui - Ixy_ui) * M_LN2;
610  double calc_expo2 = -(Iyz_ui - Ixy_ui) * M_LN2;
611 
612  // if exponentials are too high or to low, crop them at _maxLog_
613  if (calc_expo1 > _maxLog_ || calc_expo2 > _maxLog_) {
614  Pb = 0.0;
615  } else if (calc_expo1 < -_maxLog_ && calc_expo2 < -_maxLog_) {
616  Pb = 1.0;
617  } else {
618  double expo1, expo2;
619  if (calc_expo1 < -_maxLog_) {
620  expo1 = 0.0;
621  } else {
622  expo1 = std::exp(calc_expo1);
623  }
624  if (calc_expo2 < -_maxLog_) {
625  expo2 = 0.0;
626  } else {
627  expo2 = std::exp(calc_expo2);
628  }
629  Pb = 1 / (1 + expo1 + expo2);
630  }
631 
632  // Getting max(min(Pnv, pb))
633  const double min_pnv_pb = std::min(Pnv, Pb);
634  if (min_pnv_pb > maxP) {
635  maxP = min_pnv_pb;
636  maxZ = z;
637  }
638  } // if z not in (x, y)
639  } // for z in graph.nodes
640  // storing best z in rank_
641  CondRanking final;
642  auto tup = new CondThreePoints{x, y, maxZ, ui};
643  final.first = tup;
644  final.second = maxP;
645  rank.insert(final);
646  }
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 144 of file Miic.cpp.

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

147  {
148  NodeId x, y;
149  EdgeSet edges = graph.edges();
150  Size steps_init = edges.size();
151 
152  for (const Edge& edge: edges) {
153  x = edge.first();
154  y = edge.second();
155  double Ixy = mutualInformation.score(x, y);
156 
157  if (Ixy <= 0) { //< K
158  graph.eraseEdge(edge);
159  sepSet.insert(std::make_pair(x, y), _emptySet_);
160  } else {
161  findBestContributor_(x, y, _emptySet_, graph, mutualInformation, rank);
162  }
163 
164  ++current_step_;
165  if (onProgress.hasListener()) {
166  GUM_EMIT3(onProgress, (current_step_ * 33) / steps_init, 0., timer_.step());
167  }
168  }
169  }
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:574
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 1181 of file Miic.cpp.

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

1181  {
1182  return (_initialMarks_.exists({x, y}) && _initialMarks_[{x, y}] == '-');
1183  }
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 835 of file Miic.cpp.

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

835  {
836  // no cycle
837  if (_existsDirectedPath_(graph, xj, xi)) {
838  GUM_TRACE("cycle(" << xi << "-" << xj << ")")
839  return false;
840  }
841 
842  // R1
843  if (!(graph.parents(xi) - graph.adjacents(xj)).empty()) {
844  GUM_TRACE("R1(" << xi << "-" << xj << ")")
845  return true;
846  }
847 
848  // R2
849  if (_existsDirectedPath_(graph, xi, xj)) {
850  GUM_TRACE("R2(" << xi << "-" << xj << ")")
851  return true;
852  }
853 
854  // R3
855  int nbr = 0;
856  for (const auto p: graph.parents(xj)) {
857  if (!graph.mixedOrientedPath(xi, p).empty()) {
858  nbr += 1;
859  if (nbr == 2) {
860  GUM_TRACE("R3(" << xi << "-" << xj << ")")
861  return true;
862  }
863  }
864  }
865  return false;
866  }
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:974
+ 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 177 of file Miic.cpp.

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

180  {
181  // if no triples to further examine pass
182  CondRanking best;
183 
184  Size steps_init = current_step_;
185  Size steps_iter = rank.size();
186 
187  try {
188  while (rank.top().second > 0.5) {
189  best = rank.pop();
190 
191  const NodeId x = std::get< 0 >(*(best.first));
192  const NodeId y = std::get< 1 >(*(best.first));
193  const NodeId z = std::get< 2 >(*(best.first));
194  std::vector< NodeId > ui = std::move(std::get< 3 >(*(best.first)));
195 
196  ui.push_back(z);
197  const double i_xy_ui = mutualInformation.score(x, y, ui);
198  if (i_xy_ui < 0) {
199  graph.eraseEdge(Edge(x, y));
200  sepSet.insert(std::make_pair(x, y), std::move(ui));
201  } else {
202  findBestContributor_(x, y, ui, graph, mutualInformation, rank);
203  }
204 
205  delete best.first;
206 
207  ++current_step_;
208  if (onProgress.hasListener()) {
210  (current_step_ * 66) / (steps_init + steps_iter),
211  0.,
212  timer_.step());
213  }
214  }
215  } catch (...) {} // here, rank is empty
216  current_step_ = steps_init + steps_iter;
217  if (onProgress.hasListener()) { GUM_EMIT3(onProgress, 66, 0., timer_.step()); }
218  current_step_ = steps_init + steps_iter;
219  }
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:574
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 941 of file Miic.cpp.

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

941 { 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 945 of file Miic.cpp.

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

947  {
948  return DAG2BNLearner<>::createBN< GUM_SCALAR >(estimator,
949  learnStructure(selector, initial_dag));
950  }
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:768
+ 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  // std::cout << "Le graphe contient: " << graph.sizeEdges() << " edges." <<
125  // std::endl; std::cout << "En voici la liste: " << graph.edges() <<
126  // std::endl;
127 
128  if (_useMiic_) {
129  orientationMiic_(mutualInformation, graph, sep_set);
130  } else {
131  orientation3off2_(mutualInformation, graph, sep_set);
132  }
133 
134  return graph;
135  }
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:177
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:501
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:226
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:144
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 768 of file Miic.cpp.

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

768  {
769  MixedGraph essentialGraph = learnMixedStructure(I, initialGraph);
770  // orientate remaining edges
771 
772  const Sequence< NodeId > order = essentialGraph.topologicalOrder();
773 
774  // first, forbidden arcs force arc in the other direction
775  for (NodeId x: order) {
776  const auto nei_x = essentialGraph.neighbours(x);
777  for (NodeId y: nei_x)
778  if (isForbidenArc_(x, y)) {
779  essentialGraph.eraseEdge(Edge(x, y));
780  if (isForbidenArc_(y, x)) {
781  GUM_TRACE("Neither arc allowed for edge (" << x << "," << y << ")")
782  } else {
783  GUM_TRACE("Forced orientation : " << y << "->" << x)
784  essentialGraph.addArc(y, x);
785  }
786  } else if (isForbidenArc_(y, x)) {
787  essentialGraph.eraseEdge(Edge(x, y));
788  GUM_TRACE("Forced orientation : " << x << "->" << y)
789  essentialGraph.addArc(x, y);
790  }
791  }
792  GUM_TRACE(essentialGraph.toDot());
793 
794  // first, propagate existing orientations
795  bool newOrientation = true;
796  while (newOrientation) {
797  newOrientation = false;
798  for (NodeId x: order) {
799  if (!essentialGraph.parents(x).empty()) {
800  newOrientation |= propagatesRemainingOrientableEdges_(essentialGraph, x);
801  }
802  }
803  }
804  GUM_TRACE(essentialGraph.toDot());
806  GUM_TRACE(essentialGraph.toDot());
807 
808  // then decide the orientation for double arcs
809  for (NodeId x: order)
810  for (NodeId y: essentialGraph.parents(x))
811  if (essentialGraph.parents(y).contains(x)) {
812  GUM_TRACE(" + Resolving double arcs (poorly)")
813  essentialGraph.eraseArc(Arc(y, x));
814  }
815 
816  // std::cout << "Le mixed graph après une deuxième propagation mesdames et
817  // messieurs: "
818  //<< essentialGraph.toDot() << std::endl;
819  // std::cout << "Le graphe contient maintenant : " <<
820  // essentialGraph.sizeArcs() << " arcs."
821  //<< std::endl;
822  // std::cout << "Que voici: " << essentialGraph.arcs() << std::endl;
823  // turn the mixed graph into a dag
824  DAG dag;
825  for (auto node: essentialGraph) {
826  dag.addNodeWithId(node);
827  }
828  for (const Arc& arc: essentialGraph.arcs()) {
829  dag.addArc(arc.tail(), arc.head());
830  }
831 
832  return dag;
833  }
void propagatesOrientationInChainOfRemainingEdges_(MixedGraph &graph)
heuristic for remaining edges when everything else has been tried
Definition: Miic.cpp:868
bool isForbidenArc_(NodeId x, NodeId y) const
Definition: Miic.cpp:1181
bool propagatesRemainingOrientableEdges_(MixedGraph &graph, NodeId xj)
Propagates the orientation from a node to its neighbours.
Definition: Miic.cpp:910
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 226 of file Miic.cpp.

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

229  {
230  std::vector< Ranking > triples = unshieldedTriples_(graph, mutualInformation, sepSet);
231  Size steps_orient = triples.size();
232  Size past_steps = current_step_;
233 
234  // marks always correspond to the head of the arc/edge. - is for a forbidden
235  // arc, > for a mandatory arc
236  // we start by adding the mandatory arcs
237  for (auto iter = _initialMarks_.begin(); iter != _initialMarks_.end(); ++iter) {
238  if (graph.existsEdge(iter.key().first, iter.key().second) && iter.val() == '>') {
239  graph.eraseEdge(Edge(iter.key().first, iter.key().second));
240  graph.addArc(iter.key().first, iter.key().second);
241  }
242  }
243 
244  NodeId i = 0;
245  // list of elements that we shouldnt read again, ie elements that are
246  // eligible to
247  // rule 0 after the first time they are tested, and elements on which rule 1
248  // has been applied
249  while (i < triples.size()) {
250  // if i not in do_not_reread
251  Ranking triple = triples[i];
252  NodeId x, y, z;
253  x = std::get< 0 >(*triple.first);
254  y = std::get< 1 >(*triple.first);
255  z = std::get< 2 >(*triple.first);
256 
257  std::vector< NodeId > ui;
258  std::pair< NodeId, NodeId > key = {x, y};
259  std::pair< NodeId, NodeId > rev_key = {y, x};
260  if (sepSet.exists(key)) {
261  ui = sepSet[key];
262  } else if (sepSet.exists(rev_key)) {
263  ui = sepSet[rev_key];
264  }
265  double Ixyz_ui = triple.second;
266  bool reset{false};
267  // try Rule 0
268  if (Ixyz_ui < 0) {
269  // if ( z not in Sep[x,y])
270  if (std::find(ui.begin(), ui.end(), z) == ui.end()) {
271  if (!graph.existsArc(x, z) && !graph.existsArc(z, x)) {
272  // when we try to add an arc to the graph, we always verify if
273  // we are allowed to do so, ie it is not a forbidden arc an it
274  // does not create a cycle
275  if (!_existsDirectedPath_(graph, z, x) && !isForbidenArc_(x, z)) {
276  reset = true;
277  graph.eraseEdge(Edge(x, z));
278  graph.addArc(x, z);
279  } else if (_existsDirectedPath_(graph, z, x) && !isForbidenArc_(z, x)) {
280  reset = true;
281  graph.eraseEdge(Edge(x, z));
282  // if we find a cycle, we force the competing edge
283  graph.addArc(z, x);
284  if (std::find(_latentCouples_.begin(), _latentCouples_.end(), Arc(z, x))
285  == _latentCouples_.end()) {
286  _latentCouples_.emplace_back(z, x);
287  }
288  }
289  } else if (!graph.existsArc(y, z) && !graph.existsArc(z, y)) {
290  if (!_existsDirectedPath_(graph, z, y) && !isForbidenArc_(x, z)) {
291  reset = true;
292  graph.eraseEdge(Edge(y, z));
293  graph.addArc(y, z);
294  } else if (_existsDirectedPath_(graph, z, y) && !isForbidenArc_(z, y)) {
295  reset = true;
296  graph.eraseEdge(Edge(y, z));
297  // if we find a cycle, we force the competing edge
298  graph.addArc(z, y);
299  if (std::find(_latentCouples_.begin(), _latentCouples_.end(), Arc(z, y))
300  == _latentCouples_.end()) {
301  _latentCouples_.emplace_back(z, y);
302  }
303  }
304  } else {
305  // checking if the anti-directed arc already exists, to register a
306  // latent variable
307  if (graph.existsArc(z, x) && _isNotLatentCouple_(z, x)) {
308  _latentCouples_.emplace_back(z, x);
309  }
310  if (graph.existsArc(z, y) && _isNotLatentCouple_(z, y)) {
311  _latentCouples_.emplace_back(z, y);
312  }
313  }
314  }
315  } else { // try Rule 1
316  if (graph.existsArc(x, z) && !graph.existsArc(z, y) && !graph.existsArc(y, z)) {
317  if (!_existsDirectedPath_(graph, y, z) && !isForbidenArc_(z, y)) {
318  reset = true;
319  graph.eraseEdge(Edge(z, y));
320  graph.addArc(z, y);
321  } else if (_existsDirectedPath_(graph, y, z) && !isForbidenArc_(y, z)) {
322  reset = true;
323  graph.eraseEdge(Edge(z, y));
324  // if we find a cycle, we force the competing edge
325  graph.addArc(y, z);
326  if (std::find(_latentCouples_.begin(), _latentCouples_.end(), Arc(y, z))
327  == _latentCouples_.end()) {
328  _latentCouples_.emplace_back(y, z);
329  }
330  }
331  }
332  if (graph.existsArc(y, z) && !graph.existsArc(z, x) && !graph.existsArc(x, z)) {
333  if (!_existsDirectedPath_(graph, x, z) && !isForbidenArc_(z, x)) {
334  reset = true;
335  graph.eraseEdge(Edge(z, x));
336  graph.addArc(z, x);
337  } else if (_existsDirectedPath_(graph, x, z) && !isForbidenArc_(x, z)) {
338  reset = true;
339  graph.eraseEdge(Edge(z, x));
340  // if we find a cycle, we force the competing edge
341  graph.addArc(x, z);
342  if (std::find(_latentCouples_.begin(), _latentCouples_.end(), Arc(x, z))
343  == _latentCouples_.end()) {
344  _latentCouples_.emplace_back(x, z);
345  }
346  }
347  }
348  } // if rule 0 or rule 1
349 
350  // if what we want to add already exists : pass to the next triplet
351  if (reset) {
352  i = 0;
353  } else {
354  ++i;
355  }
356  if (onProgress.hasListener()) {
358  ((current_step_ + i) * 100) / (past_steps + steps_orient),
359  0.,
360  timer_.step());
361  }
362  } // while
363 
364  // erasing the the double headed arcs
365  for (const Arc& arc: _latentCouples_) {
366  graph.eraseArc(Arc(arc.head(), arc.tail()));
367  }
368  }
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:1181
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:974
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:1173
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:650
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.

varient 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 371 of file Miic.cpp.

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

374  {
375  std::vector< Ranking > triples = unshieldedTriples_(graph, mutualInformation, sepSet);
376  Size steps_orient = triples.size();
377  Size past_steps = current_step_;
378 
379  NodeId i = 0;
380  // list of elements that we shouldnt read again, ie elements that are
381  // eligible to
382  // rule 0 after the first time they are tested, and elements on which rule 1
383  // has been applied
384  while (i < triples.size()) {
385  // if i not in do_not_reread
386  Ranking triple = triples[i];
387  NodeId x, y, z;
388  x = std::get< 0 >(*triple.first);
389  y = std::get< 1 >(*triple.first);
390  z = std::get< 2 >(*triple.first);
391 
392  std::vector< NodeId > ui;
393  std::pair< NodeId, NodeId > key = {x, y};
394  std::pair< NodeId, NodeId > rev_key = {y, x};
395  if (sepSet.exists(key)) {
396  ui = sepSet[key];
397  } else if (sepSet.exists(rev_key)) {
398  ui = sepSet[rev_key];
399  }
400  double Ixyz_ui = triple.second;
401  // try Rule 0
402  if (Ixyz_ui < 0) {
403  // if ( z not in Sep[x,y])
404  if (std::find(ui.begin(), ui.end(), z) == ui.end()) {
405  // if what we want to add already exists : pass
406  if ((graph.existsArc(x, z) || graph.existsArc(z, x))
407  && (graph.existsArc(y, z) || graph.existsArc(z, y))) {
408  ++i;
409  } else {
410  i = 0;
411  graph.eraseEdge(Edge(x, z));
412  graph.eraseEdge(Edge(y, z));
413  // checking for cycles
414  if (graph.existsArc(z, x)) {
415  graph.eraseArc(Arc(z, x));
416  try {
417  std::vector< NodeId > path = graph.directedPath(z, x);
418  // if we find a cycle, we force the competing edge
419  _latentCouples_.emplace_back(z, x);
420  } catch (gum::NotFound) { graph.addArc(x, z); }
421  graph.addArc(z, x);
422  } else {
423  try {
424  std::vector< NodeId > path = graph.directedPath(z, x);
425  // if we find a cycle, we force the competing edge
426  graph.addArc(z, x);
427  _latentCouples_.emplace_back(z, x);
428  } catch (gum::NotFound) { graph.addArc(x, z); }
429  }
430  if (graph.existsArc(z, y)) {
431  graph.eraseArc(Arc(z, y));
432  try {
433  std::vector< NodeId > path = graph.directedPath(z, y);
434  // if we find a cycle, we force the competing edge
435  _latentCouples_.emplace_back(z, y);
436  } catch (gum::NotFound) { graph.addArc(y, z); }
437  graph.addArc(z, y);
438  } else {
439  try {
440  std::vector< NodeId > path = graph.directedPath(z, y);
441  // if we find a cycle, we force the competing edge
442  graph.addArc(z, y);
443  _latentCouples_.emplace_back(z, y);
444 
445  } catch (gum::NotFound) { graph.addArc(y, z); }
446  }
447  if (graph.existsArc(z, x) && _isNotLatentCouple_(z, x)) {
448  _latentCouples_.emplace_back(z, x);
449  }
450  if (graph.existsArc(z, y) && _isNotLatentCouple_(z, y)) {
451  _latentCouples_.emplace_back(z, y);
452  }
453  }
454  } else {
455  ++i;
456  }
457  } else { // try Rule 1
458  bool reset{false};
459  if (graph.existsArc(x, z) && !graph.existsArc(z, y) && !graph.existsArc(y, z)) {
460  reset = true;
461  graph.eraseEdge(Edge(z, y));
462  try {
463  std::vector< NodeId > path = graph.directedPath(y, z);
464  // if we find a cycle, we force the competing edge
465  graph.addArc(y, z);
466  _latentCouples_.emplace_back(y, z);
467  } catch (gum::NotFound) { graph.addArc(z, y); }
468  }
469  if (graph.existsArc(y, z) && !graph.existsArc(z, x) && !graph.existsArc(x, z)) {
470  reset = true;
471  graph.eraseEdge(Edge(z, x));
472  try {
473  std::vector< NodeId > path = graph.directedPath(x, z);
474  // if we find a cycle, we force the competing edge
475  graph.addArc(x, z);
476  _latentCouples_.emplace_back(x, z);
477  } catch (gum::NotFound) { graph.addArc(z, x); }
478  }
479 
480  if (reset) {
481  i = 0;
482  } else {
483  ++i;
484  }
485  } // if rule 0 or rule 1
486  if (onProgress.hasListener()) {
488  ((current_step_ + i) * 100) / (past_steps + steps_orient),
489  0.,
490  timer_.step());
491  }
492  } // while
493 
494  // erasing the the double headed arcs
495  for (const Arc& arc: _latentCouples_) {
496  graph.eraseArc(Arc(arc.head(), arc.tail()));
497  }
498  }
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:1173
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:650
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 501 of file Miic.cpp.

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

504  {
505  // structure to store the orientations marks -, o, or >,
506  // Considers the head of the arc/edge first node -* second node
507  HashTable< std::pair< NodeId, NodeId >, char > marks = _initialMarks_;
508 
509  // marks always correspond to the head of the arc/edge. - is for a forbidden
510  // arc, > for a mandatory arc
511  // we start by adding the mandatory arcs
512  for (auto iter = marks.begin(); iter != marks.end(); ++iter) {
513  if (graph.existsEdge(iter.key().first, iter.key().second) && iter.val() == '>') {
514  graph.eraseEdge(Edge(iter.key().first, iter.key().second));
515  graph.addArc(iter.key().first, iter.key().second);
516  }
517  }
518 
519  std::vector< ProbabilisticRanking > proba_triples
520  = unshieldedTriplesMiic_(graph, mutualInformation, sepSet, marks);
521 
522  const Size steps_orient = proba_triples.size();
523  Size past_steps = current_step_;
524 
526  if (steps_orient > 0) { best = proba_triples[0]; }
527 
528  while (!proba_triples.empty() && std::max(std::get< 2 >(best), std::get< 3 >(best)) > 0.5) {
529  const NodeId x = std::get< 0 >(*std::get< 0 >(best));
530  const NodeId y = std::get< 1 >(*std::get< 0 >(best));
531  const NodeId z = std::get< 2 >(*std::get< 0 >(best));
532 
533  const double i3 = std::get< 1 >(best);
534 
535  const double p1 = std::get< 2 >(best);
536  const double p2 = std::get< 3 >(best);
537  if (i3 <= 0) {
538  _orientingVstructureMiic_(graph, marks, x, y, z, p1, p2);
539  } else {
540  _propagatingOrientationMiic_(graph, marks, x, y, z, p1, p2);
541  }
542 
543  delete std::get< 0 >(best);
544  proba_triples.erase(proba_triples.begin());
545  // actualisation of the list of triples
546  proba_triples = updateProbaTriples_(graph, proba_triples);
547 
548  if (!proba_triples.empty()) best = proba_triples[0];
549 
550  ++current_step_;
551  if (onProgress.hasListener()) {
553  (current_step_ * 100) / (steps_orient + past_steps),
554  0.,
555  timer_.step());
556  }
557  } // while
558 
559  // erasing the double headed arcs
560  for (auto iter = _latentCouples_.rbegin(); iter != _latentCouples_.rend(); ++iter) {
561  graph.eraseArc(Arc(iter->head(), iter->tail()));
562  if (_existsDirectedPath_(graph, iter->head(), iter->tail())) {
563  // if we find a cycle, we force the competing edge
564  graph.addArc(iter->head(), iter->tail());
565  graph.eraseArc(Arc(iter->tail(), iter->head()));
566  *iter = Arc(iter->head(), iter->tail());
567  }
568  }
569 
570  if (onProgress.hasListener()) { GUM_EMIT3(onProgress, 100, 0., timer_.step()); }
571  }
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:728
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:687
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:974
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:1101
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:1008
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 868 of file Miic.cpp.

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

868  {
869  // then decide the orientation for remaining edges
870  while (!essentialGraph.edges().empty()) {
871  const auto& edge = *(essentialGraph.edges().begin());
872  NodeId root = edge.first();
873  Size size_children_root = essentialGraph.children(root).size();
874  NodeSet visited;
875  NodeSet stack{root};
876  // check the best root for the set of neighbours
877  while (!stack.empty()) {
878  NodeId next = *(stack.begin());
879  stack.erase(next);
880  if (visited.contains(next)) continue;
881  if (essentialGraph.children(next).size() > size_children_root) {
882  size_children_root = essentialGraph.children(next).size();
883  root = next;
884  }
885  for (const auto n: essentialGraph.neighbours(next))
886  if (!stack.contains(n) && !visited.contains(n)) stack.insert(n);
887  visited.insert(next);
888  }
889  // orientation now
890  visited.clear();
891  stack.clear();
892  stack.insert(root);
893  while (!stack.empty()) {
894  NodeId next = *(stack.begin());
895  stack.erase(next);
896  if (visited.contains(next)) continue;
897  const auto nei = essentialGraph.neighbours(next);
898  for (const auto n: nei) {
899  if (!stack.contains(n) && !visited.contains(n)) stack.insert(n);
900  GUM_TRACE(" + amap reasonably orientation for " << n << "->" << next);
901  essentialGraph.eraseEdge(Edge(n, next));
902  essentialGraph.addArc(n, next);
903  }
904  visited.insert(next);
905  }
906  }
907  }
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 910 of file Miic.cpp.

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

910  {
911  bool res = false;
912  const auto neighbours = graph.neighbours(xj);
913  for (auto& xi: neighbours) {
914  bool i_j = isOrientable_(graph, xi, xj);
915  bool j_i = isOrientable_(graph, xj, xi);
916  if (i_j || j_i) {
917  GUM_TRACE(" + Removing edge (" << xi << "," << xj << ")")
918  graph.eraseEdge(Edge(xi, xj));
919  res = true;
920  }
921  if (i_j) {
922  GUM_TRACE(" + add arc (" << xi << "," << xj << ")")
923  graph.addArc(xi, xj);
925  }
926  if (j_i) {
927  GUM_TRACE(" + add arc (" << xi << "," << xj << ")")
928  graph.addArc(xj, xi);
930  }
931  if (i_j && j_i) {
932  GUM_TRACE(" + add arc (" << xi << "," << xj << ")")
933  _latentCouples_.emplace_back(xi, xj);
934  }
935  }
936 
937  return res;
938  }
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:835
bool propagatesRemainingOrientableEdges_(MixedGraph &graph, NodeId xj)
Propagates the orientation from a node to its neighbours.
Definition: Miic.cpp:910
+ 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 954 of file Miic.cpp.

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

954 { 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
OutOfLowerBoundRaised 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(OutOfLowerBound, "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
OutOfLowerBoundRaised 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(OutOfLowerBound, "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
OutOfLowerBoundRaised 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(OutOfLowerBound, "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 952 of file Miic.cpp.

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

952 { 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
OutOfLowerBoundif 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(OutOfLowerBound, "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
OutOfLowerBoundRaised 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(OutOfLowerBound, "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 650 of file Miic.cpp.

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

653  {
654  std::vector< Ranking > triples;
655  for (NodeId z: graph) {
656  for (NodeId x: graph.neighbours(z)) {
657  for (NodeId y: graph.neighbours(z)) {
658  if (y < x && !graph.existsEdge(x, y)) {
659  std::vector< NodeId > ui;
660  std::pair< NodeId, NodeId > key = {x, y};
661  std::pair< NodeId, NodeId > rev_key = {y, x};
662  if (sepSet.exists(key)) {
663  ui = sepSet[key];
664  } else if (sepSet.exists(rev_key)) {
665  ui = sepSet[rev_key];
666  }
667  // remove z from ui if it's present
668  const auto iter_z_place = std::find(ui.begin(), ui.end(), z);
669  if (iter_z_place != ui.end()) { ui.erase(iter_z_place); }
670 
671  double Ixyz_ui = mutualInformation.score(x, y, z, ui);
672  Ranking triple;
673  auto tup = new ThreePoints{x, y, z};
674  triple.first = tup;
675  triple.second = Ixyz_ui;
676  triples.push_back(triple);
677  }
678  }
679  }
680  }
681  std::sort(triples.begin(), triples.end(), GreaterAbsPairOn2nd());
682  return triples;
683  }
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 687 of file Miic.cpp.

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

691  {
692  std::vector< ProbabilisticRanking > triples;
693  for (NodeId z: graph) {
694  for (NodeId x: graph.neighbours(z)) {
695  for (NodeId y: graph.neighbours(z)) {
696  if (y < x && !graph.existsEdge(x, y)) {
697  std::vector< NodeId > ui;
698  std::pair< NodeId, NodeId > key = {x, y};
699  std::pair< NodeId, NodeId > rev_key = {y, x};
700  if (sepSet.exists(key)) {
701  ui = sepSet[key];
702  } else if (sepSet.exists(rev_key)) {
703  ui = sepSet[rev_key];
704  }
705  // remove z from ui if it's present
706  const auto iter_z_place = std::find(ui.begin(), ui.end(), z);
707  if (iter_z_place != ui.end()) { ui.erase(iter_z_place); }
708 
709  const double Ixyz_ui = mutualInformation.score(x, y, z, ui);
710  auto tup = new ThreePoints{x, y, z};
711  ProbabilisticRanking triple{tup, Ixyz_ui, 0.5, 0.5};
712  triples.push_back(triple);
713  if (!marks.exists({x, z})) { marks.insert({x, z}, 'o'); }
714  if (!marks.exists({z, x})) { marks.insert({z, x}, 'o'); }
715  if (!marks.exists({y, z})) { marks.insert({y, z}, 'o'); }
716  if (!marks.exists({z, y})) { marks.insert({z, y}, 'o'); }
717  }
718  }
719  }
720  }
721  triples = updateProbaTriples_(graph, triples);
722  std::sort(triples.begin(), triples.end(), GreaterTupleOnLast());
723  return triples;
724  }
std::vector< ProbabilisticRanking > updateProbaTriples_(const MixedGraph &graph, std::vector< ProbabilisticRanking > probaTriples)
Gets the orientation probabilities like MIIC for the orientation phase.
Definition: Miic.cpp:728
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 728 of file Miic.cpp.

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

729  {
730  for (auto& triple: probaTriples) {
731  NodeId x, y, z;
732  x = std::get< 0 >(*std::get< 0 >(triple));
733  y = std::get< 1 >(*std::get< 0 >(triple));
734  z = std::get< 2 >(*std::get< 0 >(triple));
735  const double Ixyz = std::get< 1 >(triple);
736  double Pxz = std::get< 2 >(triple);
737  double Pyz = std::get< 3 >(triple);
738 
739  if (Ixyz <= 0) {
740  const double expo = std::exp(Ixyz);
741  const double P0 = (1 + expo) / (1 + 3 * expo);
742  // distinguish betweeen the initialization and the update process
743  if (Pxz == Pyz && Pyz == 0.5) {
744  std::get< 2 >(triple) = P0;
745  std::get< 3 >(triple) = P0;
746  } else {
747  if (graph.existsArc(x, z) && Pxz >= P0) {
748  std::get< 3 >(triple) = Pxz * (1 / (1 + expo) - 0.5) + 0.5;
749  } else if (graph.existsArc(y, z) && Pyz >= P0) {
750  std::get< 2 >(triple) = Pyz * (1 / (1 + expo) - 0.5) + 0.5;
751  }
752  }
753  } else {
754  const double expo = std::exp(-Ixyz);
755  if (graph.existsArc(x, z) && Pxz >= 0.5) {
756  std::get< 3 >(triple) = Pxz * (1 / (1 + expo) - 0.5) + 0.5;
757  } else if (graph.existsArc(y, z) && Pyz >= 0.5) {
758  std::get< 2 >(triple) = Pyz * (1 / (1 + expo) - 0.5) + 0.5;
759  }
760  }
761  }
762  std::sort(probaTriples.begin(), probaTriples.end(), GreaterTupleOnLast());
763  return probaTriples;
764  }
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: