aGrUM  0.20.2
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 ()
 destructor More...
 
Accessors / Modifiers
MixedGraph learnMixedStructure (CorrectedMutualInformation<> &I, MixedGraph graph)
 learns the structure of an Essential Graph More...
 
DAG learnStructure (CorrectedMutualInformation<> &I, MixedGraph graph)
 learns the structure of an Bayesian network, ie 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 set3off2Behaviour ()
 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<> &I, Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, GreaterPairOn2nd > &rank_)
 finds the best contributor node for a pair given a conditioning set More...
 
std::vector< std::pair< std::tuple< NodeId, NodeId, NodeId > *, double > > getUnshieldedTriples_ (const MixedGraph &graph, CorrectedMutualInformation<> &I, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set)
 gets the list of unshielded triples in the graph in decreasing value of |I'(x, y, z|{ui})| More...
 
std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > getUnshieldedTriplesMIIC_ (const MixedGraph &graph, CorrectedMutualInformation<> &I, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set, 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< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > updateProbaTriples_ (const MixedGraph &graph, std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > proba_triples)
 Gets the orientation probabilities like MIIC for the orientation phase. More...
 
void propagatesHead_ (MixedGraph &graph, NodeId node)
 Propagates the orientation from a node to its neighbours. More...
 
Main phases
void initiation_ (CorrectedMutualInformation<> &I, MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set, Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, GreaterPairOn2nd > &rank_)
 Initiation phase. More...
 
void iteration_ (CorrectedMutualInformation<> &I, MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set, Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, GreaterPairOn2nd > &rank_)
 Iteration phase. More...
 
void orientation_3off2_ (CorrectedMutualInformation<> &I, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set)
 Orientation phase from the 3off2 algorithm, returns a CPDAG. More...
 
void orientation_latents_ (CorrectedMutualInformation<> &I, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set)
 Modified version of the orientation phase that tries to propagate orientations from both orientations in case of a bidirected arc, not used. More...
 
void orientation_miic_ (CorrectedMutualInformation<> &I, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set)
 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 105 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 43 of file Miic.cpp.

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

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

◆ Miic() [2/4]

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

default constructor with maxLog

Definition at line 46 of file Miic.cpp.

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

46 : maxLog__(maxLog) { GUM_CONSTRUCTOR(Miic); }
int maxLog__
Fixes the maximum log that we accept in exponential computations.
Definition: Miic.h:349
Miic()
default constructor
Definition: Miic.cpp:43
+ Here is the call graph for this function:

◆ Miic() [3/4]

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

copy constructor

Definition at line 49 of file Miic.cpp.

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

49  : ApproximationScheme(from) {
50  GUM_CONS_CPY(Miic);
51  }
ApproximationScheme(bool verbosity=false)
Miic()
default constructor
Definition: Miic.cpp:43
+ Here is the call graph for this function:

◆ Miic() [4/4]

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

move constructor

Definition at line 54 of file Miic.cpp.

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

54  : ApproximationScheme(std::move(from)) {
55  GUM_CONS_MOV(Miic);
56  }
ApproximationScheme(bool verbosity=false)
Miic()
default constructor
Definition: Miic.cpp:43
+ Here is the call graph for this function:

◆ ~Miic()

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

destructor

Definition at line 59 of file Miic.cpp.

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

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

Member Function Documentation

◆ 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 1256 of file Miic.cpp.

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

1257  {
1258  this->initial_marks__ = constraints;
1259  }
HashTable< std::pair< NodeId, NodeId >, char > initial_marks__
Initial marks for the orientation phase, used to convey constraints.
Definition: Miic.h:364
+ 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 226 of file approximationScheme_inl.h.

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

226  {
227  // For coherence, we fix the time used in the method
228 
229  double timer_step = timer_.step();
230 
231  if (enabled_max_time_) {
232  if (timer_step > max_time_) {
234  return false;
235  }
236  }
237 
238  if (!startOfPeriod()) { return true; }
239 
241  GUM_ERROR(OperationNotAllowed,
242  "state of the approximation scheme is not correct : "
244  }
245 
246  if (verbosity()) { history_.push_back(error); }
247 
248  if (enabled_max_iter_) {
249  if (current_step_ > max_iter_) {
251  return false;
252  }
253  }
254 
256  current_epsilon_ = error; // eps rate isEnabled needs it so affectation was
257  // moved from eps isEnabled below
258 
259  if (enabled_eps_) {
260  if (current_epsilon_ <= eps_) {
262  return false;
263  }
264  }
265 
266  if (last_epsilon_ >= 0.) {
267  if (current_epsilon_ > .0) {
268  // ! current_epsilon_ can be 0. AND epsilon
269  // isEnabled can be disabled !
272  }
273  // limit with current eps ---> 0 is | 1 - ( last_eps / 0 ) | --->
274  // infinity the else means a return false if we isEnabled the rate below,
275  // as we would have returned false if epsilon isEnabled was enabled
276  else {
278  }
279 
280  if (enabled_min_rate_eps_) {
281  if (current_rate_ <= min_rate_eps_) {
283  return false;
284  }
285  }
286  }
287 
289  if (onProgress.hasListener()) {
291  }
292 
293  return true;
294  } else {
295  return false;
296  }
297  }
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:54
+ 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 127 of file approximationScheme_inl.h.

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

127 { 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 104 of file approximationScheme_inl.h.

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

104 { 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 130 of file approximationScheme_inl.h.

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

130 { 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 78 of file approximationScheme_inl.h.

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

78  {
79  enabled_min_rate_eps_ = false;
80  }
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 107 of file approximationScheme_inl.h.

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

107 { 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 133 of file approximationScheme_inl.h.

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

133 { 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 83 of file approximationScheme_inl.h.

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

83  {
84  enabled_min_rate_eps_ = true;
85  }
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:

◆ existsDirectedPath__()

const bool gum::learning::Miic::existsDirectedPath__ ( const MixedGraph graph,
const NodeId  n1,
const NodeId  n2,
const bool  countArc = true 
) const
private

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

Definition at line 1262 of file Miic.cpp.

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

1265  {
1266  // not recursive version => use a FIFO for simulating the recursion
1267  List< NodeId > nodeFIFO;
1268  nodeFIFO.pushBack(n2);
1269 
1270  // mark[node] = successor if visited, else mark[node] does not exist
1271  NodeProperty< NodeId > mark;
1272  mark.insert(n2, n2);
1273 
1274  NodeId current;
1275 
1276  while (!nodeFIFO.empty()) {
1277  current = nodeFIFO.front();
1278  nodeFIFO.popFront();
1279 
1280  // check the parents
1281 
1282  for (const auto new_one: graph.parents(current)) {
1283  if (!countArc && current == n2
1284  && new_one == n1) // If countArc is set to false
1285  continue; // paths of length 1 are ignored
1286 
1287  if (mark.exists(new_one)) // if this node is already marked, do not
1288  continue; // check it again
1289 
1290  if (graph.existsArc(current,
1291  new_one)) // if there is a double arc, pass
1292  continue;
1293 
1294  mark.insert(new_one, current);
1295 
1296  if (new_one == n1) { return true; }
1297 
1298  nodeFIFO.pushBack(new_one);
1299  }
1300  }
1301 
1302  return false;
1303  }
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ 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<> &  I,
Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, GreaterPairOn2nd > &  rank_ 
)
protected

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

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

Definition at line 901 of file Miic.cpp.

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

910  {
911  double maxP = -1.0;
912  NodeId maxZ = 0;
913 
914  // compute N
915  //__N = I.N();
916  const double Ixy_ui = I.score(x, y, ui);
917 
918  for (const NodeId z: graph) {
919  // if z!=x and z!=y and z not in ui
920  if (z != x && z != y && std::find(ui.begin(), ui.end(), z) == ui.end()) {
921  double Pnv;
922  double Pb;
923 
924  // Computing Pnv
925  const double Ixyz_ui = I.score(x, y, z, ui);
926  double calc_expo1 = -Ixyz_ui * M_LN2;
927  // if exponentials are too high or to low, crop them at |__maxLog|
928  if (calc_expo1 > maxLog__) {
929  Pnv = 0.0;
930  } else if (calc_expo1 < -maxLog__) {
931  Pnv = 1.0;
932  } else {
933  Pnv = 1 / (1 + std::exp(calc_expo1));
934  }
935 
936  // Computing Pb
937  const double Ixz_ui = I.score(x, z, ui);
938  const double Iyz_ui = I.score(y, z, ui);
939 
940  calc_expo1 = -(Ixz_ui - Ixy_ui) * M_LN2;
941  double calc_expo2 = -(Iyz_ui - Ixy_ui) * M_LN2;
942 
943  // if exponentials are too high or to low, crop them at maxLog__
944  if (calc_expo1 > maxLog__ || calc_expo2 > maxLog__) {
945  Pb = 0.0;
946  } else if (calc_expo1 < -maxLog__ && calc_expo2 < -maxLog__) {
947  Pb = 1.0;
948  } else {
949  double expo1, expo2;
950  if (calc_expo1 < -maxLog__) {
951  expo1 = 0.0;
952  } else {
953  expo1 = std::exp(calc_expo1);
954  }
955  if (calc_expo2 < -maxLog__) {
956  expo2 = 0.0;
957  } else {
958  expo2 = std::exp(calc_expo2);
959  }
960  Pb = 1 / (1 + expo1 + expo2);
961  }
962 
963  // Getting max(min(Pnv, pb))
964  const double min_pnv_pb = std::min(Pnv, Pb);
965  if (min_pnv_pb > maxP) {
966  maxP = min_pnv_pb;
967  maxZ = z;
968  }
969  } // if z not in (x, y)
970  } // for z in graph.nodes
971  // storing best z in rank_
972  std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > >*,
973  double >
974  final;
975  auto tup
976  = new std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > >{x,
977  y,
978  maxZ,
979  ui};
980  final.first = tup;
981  final.second = maxP;
982  rank_.insert(final);
983  }
int maxLog__
Fixes the maximum log that we accept in exponential computations.
Definition: Miic.h:349
#define M_LN2
Definition: math_utils.h:43
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ getUnshieldedTriples_()

std::vector< std::pair< std::tuple< NodeId, NodeId, NodeId > *, double > > gum::learning::Miic::getUnshieldedTriples_ ( const MixedGraph graph,
CorrectedMutualInformation<> &  I,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sep_set 
)
protected

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

Definition at line 988 of file Miic.cpp.

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

992  {
993  std::vector< std::pair< std::tuple< NodeId, NodeId, NodeId >*, double > >
994  triples;
995  for (NodeId z: graph) {
996  for (NodeId x: graph.neighbours(z)) {
997  for (NodeId y: graph.neighbours(z)) {
998  if (y < x && !graph.existsEdge(x, y)) {
999  std::vector< NodeId > ui;
1000  std::pair< NodeId, NodeId > key = {x, y};
1001  std::pair< NodeId, NodeId > rev_key = {y, x};
1002  if (sep_set.exists(key)) {
1003  ui = sep_set[key];
1004  } else if (sep_set.exists(rev_key)) {
1005  ui = sep_set[rev_key];
1006  }
1007  // remove z from ui if it's present
1008  const auto iter_z_place = std::find(ui.begin(), ui.end(), z);
1009  if (iter_z_place != ui.end()) { ui.erase(iter_z_place); }
1010 
1011  double Ixyz_ui = I.score(x, y, z, ui);
1012  std::pair< std::tuple< NodeId, NodeId, NodeId >*, double > triple;
1013  auto tup = new std::tuple< NodeId, NodeId, NodeId >{x, y, z};
1014  triple.first = tup;
1015  triple.second = Ixyz_ui;
1016  triples.push_back(triple);
1017  }
1018  }
1019  }
1020  }
1021  std::sort(triples.begin(), triples.end(), GreaterAbsPairOn2nd());
1022  return triples;
1023  }
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ getUnshieldedTriplesMIIC_()

std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > gum::learning::Miic::getUnshieldedTriplesMIIC_ ( const MixedGraph graph,
CorrectedMutualInformation<> &  I,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sep_set,
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 1030 of file Miic.cpp.

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

1035  {
1036  std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId >*,
1037  double,
1038  double,
1039  double > >
1040  triples;
1041  for (NodeId z: graph) {
1042  for (NodeId x: graph.neighbours(z)) {
1043  for (NodeId y: graph.neighbours(z)) {
1044  if (y < x && !graph.existsEdge(x, y)) {
1045  std::vector< NodeId > ui;
1046  std::pair< NodeId, NodeId > key = {x, y};
1047  std::pair< NodeId, NodeId > rev_key = {y, x};
1048  if (sep_set.exists(key)) {
1049  ui = sep_set[key];
1050  } else if (sep_set.exists(rev_key)) {
1051  ui = sep_set[rev_key];
1052  }
1053  // remove z from ui if it's present
1054  const auto iter_z_place = std::find(ui.begin(), ui.end(), z);
1055  if (iter_z_place != ui.end()) { ui.erase(iter_z_place); }
1056 
1057  const double Ixyz_ui = I.score(x, y, z, ui);
1058  auto tup = new std::tuple< NodeId, NodeId, NodeId >{x, y, z};
1059  std::tuple< std::tuple< NodeId, NodeId, NodeId >*,
1060  double,
1061  double,
1062  double >
1063  triple{tup, Ixyz_ui, 0.5, 0.5};
1064  triples.push_back(triple);
1065  if (!marks.exists({x, z})) { marks.insert({x, z}, 'o'); }
1066  if (!marks.exists({z, x})) { marks.insert({z, x}, 'o'); }
1067  if (!marks.exists({y, z})) { marks.insert({y, z}, 'o'); }
1068  if (!marks.exists({z, y})) { marks.insert({z, y}, 'o'); }
1069  }
1070  }
1071  }
1072  }
1073  triples = updateProbaTriples_(graph, triples);
1074  std::sort(triples.begin(), triples.end(), GreaterTupleOnLast());
1075  return triples;
1076  }
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > updateProbaTriples_(const MixedGraph &graph, std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > proba_triples)
Gets the orientation probabilities like MIIC for the orientation phase.
Definition: Miic.cpp:1082
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:

◆ 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 172 of file approximationScheme_inl.h.

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

172  {
174  GUM_ERROR(OperationNotAllowed,
175  "state of the approximation scheme is udefined");
176  }
177 
178  if (verbosity() == false) {
179  GUM_ERROR(OperationNotAllowed, "No history when verbosity=false");
180  }
181 
182  return history_;
183  }
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:54
+ Here is the call graph for this function:

◆ initApproximationScheme()

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

Initialise the scheme.

Definition at line 186 of file approximationScheme_inl.h.

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

186  {
188  current_step_ = 0;
190  history_.clear();
191  timer_.reset();
192  }
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<> &  I,
MixedGraph graph,
HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sep_set,
Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, 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
IA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph we start from for the learning
sep_setthe separation set for independent couples, here set to {}
rank_the heap of ranks of the algorithm

Definition at line 161 of file Miic.cpp.

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

168  {
169  NodeId x, y;
170  EdgeSet edges = graph.edges();
171  Size steps_init = edges.size();
172 
173  for (const Edge& edge: edges) {
174  x = edge.first();
175  y = edge.second();
176  double Ixy = I.score(x, y);
177 
178  if (Ixy <= 0) { //< K
179  graph.eraseEdge(edge);
180  sep_set.insert(std::make_pair(x, y), empty_set__);
181  } else {
182  findBestContributor_(x, y, empty_set__, graph, I, rank_);
183  }
184 
185  ++current_step_;
186  if (onProgress.hasListener()) {
188  (current_step_ * 33) / steps_init,
189  0.,
190  timer_.step());
191  }
192  }
193  }
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<> &I, Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, GreaterPairOn2nd > &rank_)
finds the best contributor node for a pair given a conditioning set
Definition: Miic.cpp:901
Set< Edge > EdgeSet
Some typdefs and define for shortcuts ...
const std::vector< NodeId > empty_set__
an empty conditioning set
Definition: Miic.h:351
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  {
61  return enabled_eps_;
62  }
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 111 of file approximationScheme_inl.h.

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

111  {
112  return enabled_max_iter_;
113  }
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 137 of file approximationScheme_inl.h.

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

137  {
138  return enabled_max_time_;
139  }
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 89 of file approximationScheme_inl.h.

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

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

◆ iteration_()

void gum::learning::Miic::iteration_ ( CorrectedMutualInformation<> &  I,
MixedGraph graph,
HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sep_set,
Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, 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
IA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph returned from the previous phase
sep_setthe separation set for independent couples, built during the iterations of the phase
rank_the heap of ranks of the algorithm

Definition at line 201 of file Miic.cpp.

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

208  {
209  // if no triples to further examine pass
210  std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > >*,
211  double >
212  best;
213 
214  Size steps_init = current_step_;
215  Size steps_iter = rank_.size();
216 
217  try {
218  while (rank_.top().second > 0.5) {
219  best = rank_.pop();
220 
221  const NodeId x = std::get< 0 >(*(best.first));
222  const NodeId y = std::get< 1 >(*(best.first));
223  const NodeId z = std::get< 2 >(*(best.first));
224  std::vector< NodeId > ui = std::move(std::get< 3 >(*(best.first)));
225 
226  ui.push_back(z);
227  const double Ixy_ui = I.score(x, y, ui);
228  if (Ixy_ui < 0) {
229  graph.eraseEdge(Edge(x, y));
230  sep_set.insert(std::make_pair(x, y), std::move(ui));
231  } else {
232  findBestContributor_(x, y, ui, graph, I, rank_);
233  }
234 
235  delete best.first;
236 
237  ++current_step_;
238  if (onProgress.hasListener()) {
240  (current_step_ * 66) / (steps_init + steps_iter),
241  0.,
242  timer_.step());
243  }
244  }
245  } catch (...) {} // here, rank is empty
246  current_step_ = steps_init + steps_iter;
247  if (onProgress.hasListener()) {
248  GUM_EMIT3(onProgress, 66, 0., timer_.step());
249  }
250  current_step_ = steps_init + steps_iter;
251  }
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<> &I, Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, GreaterPairOn2nd > &rank_)
finds the best contributor node for a pair given a conditioning set
Definition: Miic.cpp:901
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:

◆ latentVariables()

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

get the list of arcs hiding latent variables

Definition at line 1237 of file Miic.cpp.

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

1237  {
1238  return latent_couples__;
1239  }
std::vector< Arc > latent_couples__
an empty vector of arcs
Definition: Miic.h:353
+ 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 1245 of file Miic.cpp.

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

1247  {
1248  return DAG2BNLearner<>::createBN< GUM_SCALAR >(
1249  estimator,
1250  learnStructure(selector, initial_dag));
1251  }
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 an Bayesian network, ie a DAG, by first learning an Essential graph and then ...
Definition: Miic.cpp:1126
+ Here is the call graph for this function:

◆ learnMixedStructure()

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

learns the structure of an Essential Graph

learns the structure of a MixedGraph

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

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

120  {
121  timer_.reset();
122  current_step_ = 0;
123 
124  // clear the vector of latent arcs to be sure
125  latent_couples__.clear();
126 
128  Heap<
129  std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > >*,
130  double >,
131  GreaterPairOn2nd >
132  rank_;
133 
135  HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > sep_set;
136 
137  initiation_(I, graph, sep_set, rank_);
138 
139  iteration_(I, graph, sep_set, rank_);
140 
141  // std::cout << "Le graphe contient: " << graph.sizeEdges() << " edges." <<
142  // std::endl; std::cout << "En voici la liste: " << graph.edges() <<
143  // std::endl;
144 
145  if (usemiic__) {
146  orientation_miic_(I, graph, sep_set);
147  } else {
148  orientation_3off2_(I, graph, sep_set);
149  }
150 
151  return graph;
152  }
void orientation_miic_(CorrectedMutualInformation<> &I, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set)
Orientation phase from the MIIC algorithm, returns a mixed graph that may contain circles...
Definition: Miic.cpp:602
void orientation_3off2_(CorrectedMutualInformation<> &I, MixedGraph &graph, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set)
Orientation phase from the 3off2 algorithm, returns a CPDAG.
Definition: Miic.cpp:258
void reset()
Reset the timer.
Definition: timer_inl.h:31
void initiation_(CorrectedMutualInformation<> &I, MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set, Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, GreaterPairOn2nd > &rank_)
Initiation phase.
Definition: Miic.cpp:161
bool usemiic__
wether to use the miic algorithm or not
Definition: Miic.h:358
std::vector< Arc > latent_couples__
an empty vector of arcs
Definition: Miic.h:353
Size current_step_
The current step.
void iteration_(CorrectedMutualInformation<> &I, MixedGraph &graph, HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set, Heap< std::pair< std::tuple< NodeId, NodeId, NodeId, std::vector< NodeId > > *, double >, GreaterPairOn2nd > &rank_)
Iteration phase.
Definition: Miic.cpp:201
+ Here is the call graph for this function:

◆ learnStructure()

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

learns the structure of an Bayesian network, ie 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 1126 of file Miic.cpp.

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

1127  {
1128  MixedGraph essentialGraph = learnMixedStructure(I, initialGraph);
1129  // std::cout << "Le mixed graph mesdames et messieurs: "
1130  //<< essentialGraph.toDot() << std::endl;
1131 
1132  // Second, orientate remaining edges
1133  const Sequence< NodeId > order = essentialGraph.topologicalOrder();
1134  // first, propagate existing orientations
1135  for (NodeId x: order) {
1136  if (!essentialGraph.parents(x).empty()) {
1137  propagatesHead_(essentialGraph, x);
1138  }
1139  }
1140  // std::cout << "Le mixed graph après une première propagation mesdames et
1141  // messieurs: "
1142  //<< essentialGraph.toDot() << std::endl;
1143  // then decide the orientation by the topological order and propagate them
1144  for (NodeId x: order) {
1145  if (!essentialGraph.neighbours(x).empty()) {
1146  propagatesHead_(essentialGraph, x);
1147  }
1148  }
1149 
1150  // std::cout << "Le mixed graph après une deuxième propagation mesdames et
1151  // messieurs: "
1152  //<< essentialGraph.toDot() << std::endl;
1153  // std::cout << "Le graphe contient maintenant : " <<
1154  // essentialGraph.sizeArcs() << " arcs."
1155  //<< std::endl;
1156  // std::cout << "Que voici: " << essentialGraph.arcs() << std::endl;
1157  // turn the mixed graph into a dag
1158  DAG dag;
1159  for (auto node: essentialGraph) {
1160  dag.addNodeWithId(node);
1161  }
1162  for (const Arc& arc: essentialGraph.arcs()) {
1163  dag.addArc(arc.tail(), arc.head());
1164  }
1165 
1166  return dag;
1167  }
void propagatesHead_(MixedGraph &graph, NodeId node)
Propagates the orientation from a node to its neighbours.
Definition: Miic.cpp:1170
MixedGraph learnMixedStructure(CorrectedMutualInformation<> &I, MixedGraph graph)
learns the structure of an Essential Graph
Definition: Miic.cpp:119
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 101 of file approximationScheme_inl.h.

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

101 { 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 124 of file approximationScheme_inl.h.

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

124 { 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 39 of file IApproximationSchemeConfiguration_inl.h.

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

39  {
40  std::stringstream s;
41 
42  switch (stateApproximationScheme()) {
44  s << "in progress";
45  break;
46 
48  s << "stopped with epsilon=" << epsilon();
49  break;
50 
52  s << "stopped with rate=" << minEpsilonRate();
53  break;
54 
56  s << "stopped with max iteration=" << maxIter();
57  break;
58 
60  s << "stopped with timeout=" << maxTime();
61  break;
62 
64  s << "stopped on request";
65  break;
66 
68  s << "undefined state";
69  break;
70  };
71 
72  return s.str();
73  }
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 73 of file approximationScheme_inl.h.

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

73  {
74  return min_rate_eps_;
75  }
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 162 of file approximationScheme_inl.h.

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

162  {
164  GUM_ERROR(OperationNotAllowed,
165  "state of the approximation scheme is undefined");
166  }
167 
168  return current_step_;
169  }
ApproximationSchemeSTATE stateApproximationScheme() const
Returns the approximation scheme state.
Size current_step_
The current step.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:54
+ Here is the call graph for this function:

◆ operator=() [1/2]

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

copy operator

Definition at line 62 of file Miic.cpp.

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

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

◆ operator=() [2/2]

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

move operator

Definition at line 68 of file Miic.cpp.

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

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

◆ orientation_3off2_()

void gum::learning::Miic::orientation_3off2_ ( CorrectedMutualInformation<> &  I,
MixedGraph graph,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sep_set 
)
protected

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

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

Definition at line 258 of file Miic.cpp.

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

262  {
263  std::vector< std::pair< std::tuple< NodeId, NodeId, NodeId >*, double > >
264  triples = getUnshieldedTriples_(graph, I, sep_set);
265  Size steps_orient = triples.size();
266  Size past_steps = current_step_;
267 
268  // marks always correspond to the head of the arc/edge. - is for a forbidden
269  // arc, > for a mandatory arc
270  // we start by adding the mandatory arcs
271  for (auto iter = initial_marks__.begin(); iter != initial_marks__.end();
272  ++iter) {
273  if (graph.existsEdge(iter.key().first, iter.key().second)
274  && iter.val() == '>') {
275  graph.eraseEdge(Edge(iter.key().first, iter.key().second));
276  graph.addArc(iter.key().first, iter.key().second);
277  }
278  }
279 
280  NodeId i = 0;
281  // list of elements that we shouldnt read again, ie elements that are
282  // eligible to
283  // rule 0 after the first time they are tested, and elements on which rule 1
284  // has been applied
285  while (i < triples.size()) {
286  // if i not in do_not_reread
287  std::pair< std::tuple< NodeId, NodeId, NodeId >*, double > triple
288  = triples[i];
289  NodeId x, y, z;
290  x = std::get< 0 >(*triple.first);
291  y = std::get< 1 >(*triple.first);
292  z = std::get< 2 >(*triple.first);
293 
294  std::vector< NodeId > ui;
295  std::pair< NodeId, NodeId > key = {x, y};
296  std::pair< NodeId, NodeId > rev_key = {y, x};
297  if (sep_set.exists(key)) {
298  ui = sep_set[key];
299  } else if (sep_set.exists(rev_key)) {
300  ui = sep_set[rev_key];
301  }
302  double Ixyz_ui = triple.second;
303  bool reset{false};
304  // try Rule 0
305  if (Ixyz_ui < 0) {
306  // if ( z not in Sep[x,y])
307  if (std::find(ui.begin(), ui.end(), z) == ui.end()) {
308  if (!graph.existsArc(x, z) && !graph.existsArc(z, x)) {
309  // when we try to add an arc to the graph, we always verify if
310  // we are allowed to do so, ie it is not a forbidden arc an it
311  // does not create a cycle
312  if (!existsDirectedPath__(graph, z, x)
313  && !(initial_marks__.exists({x, z})
314  && initial_marks__[{x, z}] == '-')) {
315  reset = true;
316  graph.eraseEdge(Edge(x, z));
317  graph.addArc(x, z);
318  } else if (existsDirectedPath__(graph, z, x)
319  && !(initial_marks__.exists({z, x})
320  && initial_marks__[{z, x}] == '-')) {
321  reset = true;
322  graph.eraseEdge(Edge(x, z));
323  // if we find a cycle, we force the competing edge
324  graph.addArc(z, x);
325  if (std::find(latent_couples__.begin(),
326  latent_couples__.end(),
327  Arc(z, x))
328  == latent_couples__.end()) {
329  latent_couples__.push_back(Arc(z, x));
330  }
331  }
332  } else if (!graph.existsArc(y, z) && !graph.existsArc(z, y)) {
333  if (!existsDirectedPath__(graph, z, y)
334  && !(initial_marks__.exists({x, z})
335  && initial_marks__[{x, z}] == '-')) {
336  reset = true;
337  graph.eraseEdge(Edge(y, z));
338  graph.addArc(y, z);
339  } else if (existsDirectedPath__(graph, z, y)
340  && !(initial_marks__.exists({z, y})
341  && initial_marks__[{z, y}] == '-')) {
342  reset = true;
343  graph.eraseEdge(Edge(y, z));
344  // if we find a cycle, we force the competing edge
345  graph.addArc(z, y);
346  if (std::find(latent_couples__.begin(),
347  latent_couples__.end(),
348  Arc(z, y))
349  == latent_couples__.end()) {
350  latent_couples__.push_back(Arc(z, y));
351  }
352  }
353  } else {
354  // checking if the anti-directed arc already exists, to register a
355  // latent variable
356  if (graph.existsArc(z, x)
357  && std::find(latent_couples__.begin(),
358  latent_couples__.end(),
359  Arc(z, x))
360  == latent_couples__.end()
361  && std::find(latent_couples__.begin(),
362  latent_couples__.end(),
363  Arc(x, z))
364  == latent_couples__.end()) {
365  latent_couples__.push_back(Arc(z, x));
366  }
367  if (graph.existsArc(z, y)
368  && std::find(latent_couples__.begin(),
369  latent_couples__.end(),
370  Arc(z, y))
371  == latent_couples__.end()
372  && std::find(latent_couples__.begin(),
373  latent_couples__.end(),
374  Arc(y, z))
375  == latent_couples__.end()) {
376  latent_couples__.push_back(Arc(z, y));
377  }
378  }
379  }
380  } else { // try Rule 1
381  if (graph.existsArc(x, z) && !graph.existsArc(z, y)
382  && !graph.existsArc(y, z)) {
383  if (!existsDirectedPath__(graph, y, z)
384  && !(initial_marks__.exists({z, y})
385  && initial_marks__[{z, y}] == '-')) {
386  reset = true;
387  graph.eraseEdge(Edge(z, y));
388  graph.addArc(z, y);
389  } else if (existsDirectedPath__(graph, y, z)
390  && !(initial_marks__.exists({y, z})
391  && initial_marks__[{y, z}] == '-')) {
392  reset = true;
393  graph.eraseEdge(Edge(z, y));
394  // if we find a cycle, we force the competing edge
395  graph.addArc(y, z);
396  if (std::find(latent_couples__.begin(),
397  latent_couples__.end(),
398  Arc(y, z))
399  == latent_couples__.end()) {
400  latent_couples__.push_back(Arc(y, z));
401  }
402  }
403  }
404  if (graph.existsArc(y, z) && !graph.existsArc(z, x)
405  && !graph.existsArc(x, z)) {
406  if (!existsDirectedPath__(graph, x, z)
407  && !(initial_marks__.exists({z, x})
408  && initial_marks__[{z, x}] == '-')) {
409  reset = true;
410  graph.eraseEdge(Edge(z, x));
411  graph.addArc(z, x);
412  } else if (existsDirectedPath__(graph, x, z)
413  && !(initial_marks__.exists({x, z})
414  && initial_marks__[{x, z}] == '-')) {
415  reset = true;
416  graph.eraseEdge(Edge(z, x));
417  // if we find a cycle, we force the competing edge
418  graph.addArc(x, z);
419  if (std::find(latent_couples__.begin(),
420  latent_couples__.end(),
421  Arc(x, z))
422  == latent_couples__.end()) {
423  latent_couples__.push_back(Arc(x, z));
424  }
425  }
426  }
427  } // if rule 0 or rule 1
428 
429  // if what we want to add already exists : pass to the next triplet
430  if (reset) {
431  i = 0;
432  } else {
433  ++i;
434  }
435  if (onProgress.hasListener()) {
437  ((current_step_ + i) * 100) / (past_steps + steps_orient),
438  0.,
439  timer_.step());
440  }
441  } // while
442 
443  // erasing the the double headed arcs
444  for (const Arc& arc: latent_couples__) {
445  graph.eraseArc(Arc(arc.head(), arc.tail()));
446  }
447  }
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.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
std::vector< std::pair< std::tuple< NodeId, NodeId, NodeId > *, double > > getUnshieldedTriples_(const MixedGraph &graph, CorrectedMutualInformation<> &I, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set)
gets the list of unshielded triples in the graph in decreasing value of |I&#39;(x, y, z|{ui})| ...
Definition: Miic.cpp:988
const bool existsDirectedPath__(const MixedGraph &graph, const NodeId n1, const NodeId n2, const bool countArc=true) const
checks for directed paths in a graph, consider double arcs like edges
Definition: Miic.cpp:1262
HashTable< std::pair< NodeId, NodeId >, char > initial_marks__
Initial marks for the orientation phase, used to convey constraints.
Definition: Miic.h:364
std::vector< Arc > latent_couples__
an empty vector of arcs
Definition: Miic.h:353
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:

◆ orientation_latents_()

void gum::learning::Miic::orientation_latents_ ( CorrectedMutualInformation<> &  I,
MixedGraph graph,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sep_set 
)
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
IA mutual information instance that will do the computations and has loaded the database.
graphthe MixedGraph returned from the previous phase
sep_setthe separation set for independent couples, built during the previous phase

Definition at line 450 of file Miic.cpp.

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

454  {
455  std::vector< std::pair< std::tuple< NodeId, NodeId, NodeId >*, double > >
456  triples = getUnshieldedTriples_(graph, I, sep_set);
457  Size steps_orient = triples.size();
458  Size past_steps = current_step_;
459 
460  NodeId i = 0;
461  // list of elements that we shouldnt read again, ie elements that are
462  // eligible to
463  // rule 0 after the first time they are tested, and elements on which rule 1
464  // has been applied
465  while (i < triples.size()) {
466  // if i not in do_not_reread
467  std::pair< std::tuple< NodeId, NodeId, NodeId >*, double > triple
468  = triples[i];
469  NodeId x, y, z;
470  x = std::get< 0 >(*triple.first);
471  y = std::get< 1 >(*triple.first);
472  z = std::get< 2 >(*triple.first);
473 
474  std::vector< NodeId > ui;
475  std::pair< NodeId, NodeId > key = {x, y};
476  std::pair< NodeId, NodeId > rev_key = {y, x};
477  if (sep_set.exists(key)) {
478  ui = sep_set[key];
479  } else if (sep_set.exists(rev_key)) {
480  ui = sep_set[rev_key];
481  }
482  double Ixyz_ui = triple.second;
483  // try Rule 0
484  if (Ixyz_ui < 0) {
485  // if ( z not in Sep[x,y])
486  if (std::find(ui.begin(), ui.end(), z) == ui.end()) {
487  // if what we want to add already exists : pass
488  if ((graph.existsArc(x, z) || graph.existsArc(z, x))
489  && (graph.existsArc(y, z) || graph.existsArc(z, y))) {
490  ++i;
491  } else {
492  i = 0;
493  graph.eraseEdge(Edge(x, z));
494  graph.eraseEdge(Edge(y, z));
495  // checking for cycles
496  if (graph.existsArc(z, x)) {
497  graph.eraseArc(Arc(z, x));
498  try {
499  std::vector< NodeId > path = graph.directedPath(z, x);
500  // if we find a cycle, we force the competing edge
501  latent_couples__.push_back(Arc(z, x));
502  } catch (gum::NotFound) { graph.addArc(x, z); }
503  graph.addArc(z, x);
504  } else {
505  try {
506  std::vector< NodeId > path = graph.directedPath(z, x);
507  // if we find a cycle, we force the competing edge
508  graph.addArc(z, x);
509  latent_couples__.push_back(Arc(z, x));
510  } catch (gum::NotFound) { graph.addArc(x, z); }
511  }
512  if (graph.existsArc(z, y)) {
513  graph.eraseArc(Arc(z, y));
514  try {
515  std::vector< NodeId > path = graph.directedPath(z, y);
516  // if we find a cycle, we force the competing edge
517  latent_couples__.push_back(Arc(z, y));
518  } catch (gum::NotFound) { graph.addArc(y, z); }
519  graph.addArc(z, y);
520  } else {
521  try {
522  std::vector< NodeId > path = graph.directedPath(z, y);
523  // if we find a cycle, we force the competing edge
524  graph.addArc(z, y);
525  latent_couples__.push_back(Arc(z, y));
526 
527  } catch (gum::NotFound) { graph.addArc(y, z); }
528  }
529  if (graph.existsArc(z, x)
530  && std::find(latent_couples__.begin(),
531  latent_couples__.end(),
532  Arc(z, x))
533  == latent_couples__.end()
534  && std::find(latent_couples__.begin(),
535  latent_couples__.end(),
536  Arc(x, z))
537  == latent_couples__.end()) {
538  latent_couples__.push_back(Arc(z, x));
539  }
540  if (graph.existsArc(z, y)
541  && std::find(latent_couples__.begin(),
542  latent_couples__.end(),
543  Arc(z, y))
544  == latent_couples__.end()
545  && std::find(latent_couples__.begin(),
546  latent_couples__.end(),
547  Arc(y, z))
548  == latent_couples__.end()) {
549  latent_couples__.push_back(Arc(z, y));
550  }
551  }
552  } else {
553  ++i;
554  }
555  } else { // try Rule 1
556  bool reset{false};
557  if (graph.existsArc(x, z) && !graph.existsArc(z, y)
558  && !graph.existsArc(y, z)) {
559  reset = true;
560  graph.eraseEdge(Edge(z, y));
561  try {
562  std::vector< NodeId > path = graph.directedPath(y, z);
563  // if we find a cycle, we force the competing edge
564  graph.addArc(y, z);
565  latent_couples__.push_back(Arc(y, z));
566  } catch (gum::NotFound) { graph.addArc(z, y); }
567  }
568  if (graph.existsArc(y, z) && !graph.existsArc(z, x)
569  && !graph.existsArc(x, z)) {
570  reset = true;
571  graph.eraseEdge(Edge(z, x));
572  try {
573  std::vector< NodeId > path = graph.directedPath(x, z);
574  // if we find a cycle, we force the competing edge
575  graph.addArc(x, z);
576  latent_couples__.push_back(Arc(x, z));
577  } catch (gum::NotFound) { graph.addArc(z, x); }
578  }
579 
580  if (reset) {
581  i = 0;
582  } else {
583  ++i;
584  }
585  } // if rule 0 or rule 1
586  if (onProgress.hasListener()) {
588  ((current_step_ + i) * 100) / (past_steps + steps_orient),
589  0.,
590  timer_.step());
591  }
592  } // while
593 
594  // erasing the the double headed arcs
595  for (const Arc& arc: latent_couples__) {
596  graph.eraseArc(Arc(arc.head(), arc.tail()));
597  }
598  }
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< std::pair< std::tuple< NodeId, NodeId, NodeId > *, double > > getUnshieldedTriples_(const MixedGraph &graph, CorrectedMutualInformation<> &I, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set)
gets the list of unshielded triples in the graph in decreasing value of |I&#39;(x, y, z|{ui})| ...
Definition: Miic.cpp:988
std::vector< Arc > latent_couples__
an empty vector of arcs
Definition: Miic.h:353
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:

◆ orientation_miic_()

void gum::learning::Miic::orientation_miic_ ( CorrectedMutualInformation<> &  I,
MixedGraph graph,
const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &  sep_set 
)
protected

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

varient using the orientation protocol of MIIC

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

Definition at line 602 of file Miic.cpp.

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

605  {
606  // structure to store the orientations marks -, o, or >,
607  // Considers the head of the arc/edge first node -* second node
608  HashTable< std::pair< NodeId, NodeId >, char > marks = initial_marks__;
609 
610  // marks always correspond to the head of the arc/edge. - is for a forbidden
611  // arc, > for a mandatory arc
612  // we start by adding the mandatory arcs
613  for (auto iter = marks.begin(); iter != marks.end(); ++iter) {
614  if (graph.existsEdge(iter.key().first, iter.key().second)
615  && iter.val() == '>') {
616  graph.eraseEdge(Edge(iter.key().first, iter.key().second));
617  graph.addArc(iter.key().first, iter.key().second);
618  }
619  }
620 
621  std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId >*,
622  double,
623  double,
624  double > >
625  proba_triples = getUnshieldedTriplesMIIC_(graph, I, sep_set, marks);
626 
627  Size steps_orient = proba_triples.size();
628  Size past_steps = current_step_;
629 
630  std::tuple< std::tuple< NodeId, NodeId, NodeId >*, double, double, double >
631  best;
632  if (steps_orient > 0) { best = proba_triples[0]; }
633 
634  while (!proba_triples.empty()
635  && std::max(std::get< 2 >(best), std::get< 3 >(best)) > 0.5) {
636  NodeId x, y, z;
637  x = std::get< 0 >(*std::get< 0 >(best));
638  y = std::get< 1 >(*std::get< 0 >(best));
639  z = std::get< 2 >(*std::get< 0 >(best));
640  // std::cout << "Triple: (" << x << "," << y << "," << z << ")" <<
641  // std::endl;
642 
643  const double i3 = std::get< 1 >(best);
644 
645  if (i3 <= 0) {
646  // v-structure discovery
647  if (marks[{x, z}] == 'o' && marks[{y, z}] == 'o') { // If x-z-y
648  if (!existsDirectedPath__(graph, z, x, false)) {
649  graph.eraseEdge(Edge(x, z));
650  graph.addArc(x, z);
651  // std::cout << "1.a Removing edge (" << x << "," << z << ")" <<
652  // std::endl; std::cout << "1.a Adding arc (" << x << "," << z << ")"
653  // << std::endl;
654  marks[{x, z}] = '>';
655  if (graph.existsArc(z, x)
656  && std::find(latent_couples__.begin(),
657  latent_couples__.end(),
658  Arc(z, x))
659  == latent_couples__.end()
660  && std::find(latent_couples__.begin(),
661  latent_couples__.end(),
662  Arc(x, z))
663  == latent_couples__.end()) {
664  // std::cout << "Adding latent couple (" << z << "," << x << ")" <<
665  // std::endl;
666  latent_couples__.push_back(Arc(z, x));
667  }
668  if (!arc_probas__.exists(Arc(x, z)))
669  arc_probas__.insert(Arc(x, z), std::get< 2 >(best));
670  } else {
671  graph.eraseEdge(Edge(x, z));
672  // std::cout << "1.b Adding arc (" << x << "," << z << ")" <<
673  // std::endl;
674  if (!existsDirectedPath__(graph, x, z, false)) {
675  graph.addArc(z, x);
676  // std::cout << "1.b Removing edge (" << x << "," << z << ")" <<
677  // std::endl;
678  marks[{z, x}] = '>';
679  }
680  }
681 
682  if (!existsDirectedPath__(graph, z, y, false)) {
683  graph.eraseEdge(Edge(y, z));
684  graph.addArc(y, z);
685  // std::cout << "1.c Removing edge (" << y << "," << z << ")" <<
686  // std::endl; std::cout << "1.c Adding arc (" << y << "," << z << ")"
687  // << std::endl;
688  marks[{y, z}] = '>';
689  if (graph.existsArc(z, y)
690  && std::find(latent_couples__.begin(),
691  latent_couples__.end(),
692  Arc(z, y))
693  == latent_couples__.end()
694  && std::find(latent_couples__.begin(),
695  latent_couples__.end(),
696  Arc(y, z))
697  == latent_couples__.end()) {
698  latent_couples__.push_back(Arc(z, y));
699  }
700  if (!arc_probas__.exists(Arc(y, z)))
701  arc_probas__.insert(Arc(y, z), std::get< 3 >(best));
702  } else {
703  graph.eraseEdge(Edge(y, z));
704  // std::cout << "1.d Removing edge (" << y << "," << z << ")" <<
705  // std::endl;
706  if (!existsDirectedPath__(graph, y, z, false)) {
707  graph.addArc(z, y);
708  // std::cout << "1.d Adding arc (" << z << "," << y << ")" <<
709  // std::endl;
710  marks[{z, y}] = '>';
711  }
712  }
713  } else if (marks[{x, z}] == '>' && marks[{y, z}] == 'o') { // If x->z-y
714  if (!existsDirectedPath__(graph, z, y, false)) {
715  graph.eraseEdge(Edge(y, z));
716  graph.addArc(y, z);
717  // std::cout << "2.a Removing edge (" << y << "," << z << ")" <<
718  // std::endl; std::cout << "2.a Adding arc (" << y << "," << z << ")"
719  // << std::endl;
720  marks[{y, z}] = '>';
721  if (graph.existsArc(z, y)
722  && std::find(latent_couples__.begin(),
723  latent_couples__.end(),
724  Arc(z, y))
725  == latent_couples__.end()
726  && std::find(latent_couples__.begin(),
727  latent_couples__.end(),
728  Arc(y, z))
729  == latent_couples__.end()) {
730  latent_couples__.push_back(Arc(z, y));
731  }
732  if (!arc_probas__.exists(Arc(y, z)))
733  arc_probas__.insert(Arc(y, z), std::get< 3 >(best));
734  } else {
735  graph.eraseEdge(Edge(y, z));
736  // std::cout << "2.b Removing edge (" << y << "," << z << ")" <<
737  // std::endl;
738  if (!existsDirectedPath__(graph, y, z, false)) {
739  graph.addArc(z, y);
740  // std::cout << "2.b Adding arc (" << y << "," << z << ")" <<
741  // std::endl;
742  marks[{z, y}] = '>';
743  }
744  }
745  } else if (marks[{y, z}] == '>' && marks[{x, z}] == 'o') {
746  if (!existsDirectedPath__(graph, z, x, false)) {
747  graph.eraseEdge(Edge(x, z));
748  graph.addArc(x, z);
749  // std::cout << "3.a Removing edge (" << x << "," << z << ")" <<
750  // std::endl; std::cout << "3.a Adding arc (" << x << "," << z << ")"
751  // << std::endl;
752  marks[{x, z}] = '>';
753  if (graph.existsArc(z, x)
754  && std::find(latent_couples__.begin(),
755  latent_couples__.end(),
756  Arc(z, x))
757  == latent_couples__.end()
758  && std::find(latent_couples__.begin(),
759  latent_couples__.end(),
760  Arc(x, z))
761  == latent_couples__.end()) {
762  latent_couples__.push_back(Arc(z, x));
763  }
764  if (!arc_probas__.exists(Arc(x, z)))
765  arc_probas__.insert(Arc(x, z), std::get< 2 >(best));
766  } else {
767  graph.eraseEdge(Edge(x, z));
768  // std::cout << "3.b Removing edge (" << x << "," << z << ")" <<
769  // std::endl;
770  if (!existsDirectedPath__(graph, x, z, false)) {
771  graph.addArc(z, x);
772  // std::cout << "3.b Adding arc (" << x << "," << z << ")" <<
773  // std::endl;
774  marks[{z, x}] = '>';
775  }
776  }
777  }
778 
779  } else {
780  // orientation propagation
781  if (marks[{x, z}] == '>' && marks[{y, z}] == 'o'
782  && marks[{z, y}] != '-') {
783  graph.eraseEdge(Edge(z, y));
784  // std::cout << "4. Removing edge (" << z << "," << y << ")" <<
785  // std::endl;
786  if (!existsDirectedPath__(graph, y, z) && graph.parents(y).empty()) {
787  graph.addArc(z, y);
788  // std::cout << "4.a Adding arc (" << z << "," << y << ")" <<
789  // std::endl;
790  marks[{z, y}] = '>';
791  marks[{y, z}] = '-';
792  if (!arc_probas__.exists(Arc(z, y)))
793  arc_probas__.insert(Arc(z, y), std::get< 3 >(best));
794  } else if (!existsDirectedPath__(graph, z, y)
795  && graph.parents(z).empty()) {
796  graph.addArc(y, z);
797  // std::cout << "4.b Adding arc (" << y << "," << z << ")" <<
798  // std::endl;
799  marks[{z, y}] = '-';
800  marks[{y, z}] = '>';
801  latent_couples__.push_back(Arc(y, z));
802  if (!arc_probas__.exists(Arc(y, z)))
803  arc_probas__.insert(Arc(y, z), std::get< 3 >(best));
804  } else if (!existsDirectedPath__(graph, y, z)) {
805  graph.addArc(z, y);
806  // std::cout << "4.c Adding arc (" << z << "," << y << ")" <<
807  // std::endl;
808  marks[{z, y}] = '>';
809  marks[{y, z}] = '-';
810  if (!arc_probas__.exists(Arc(z, y)))
811  arc_probas__.insert(Arc(z, y), std::get< 3 >(best));
812  } else if (!existsDirectedPath__(graph, z, y)) {
813  graph.addArc(y, z);
814  // std::cout << "4.d Adding arc (" << y << "," << z << ")" <<
815  // std::endl;
816  latent_couples__.push_back(Arc(y, z));
817  marks[{z, y}] = '-';
818  marks[{y, z}] = '>';
819  if (!arc_probas__.exists(Arc(y, z)))
820  arc_probas__.insert(Arc(y, z), std::get< 3 >(best));
821  }
822 
823  } else if (marks[{y, z}] == '>' && marks[{x, z}] == 'o'
824  && marks[{z, x}] != '-') {
825  graph.eraseEdge(Edge(z, x));
826  // std::cout << "5. Removing edge (" << z << "," << x << ")" <<
827  // std::endl;
828  if (!existsDirectedPath__(graph, x, z) && graph.parents(x).empty()) {
829  graph.addArc(z, x);
830  // std::cout << "5.a Adding arc (" << z << "," << x << ")" <<
831  // std::endl;
832  marks[{z, x}] = '>';
833  marks[{x, z}] = '-';
834  if (!arc_probas__.exists(Arc(z, x)))
835  arc_probas__.insert(Arc(z, x), std::get< 2 >(best));
836  } else if (!existsDirectedPath__(graph, z, x)
837  && graph.parents(z).empty()) {
838  graph.addArc(x, z);
839  // std::cout << "5.b Adding arc (" << x << "," << z << ")" <<
840  // std::endl;
841  marks[{z, x}] = '-';
842  marks[{x, z}] = '>';
843  latent_couples__.push_back(Arc(x, z));
844  if (!arc_probas__.exists(Arc(x, z)))
845  arc_probas__.insert(Arc(x, z), std::get< 2 >(best));
846  } else if (!existsDirectedPath__(graph, x, z)) {
847  graph.addArc(z, x);
848  // std::cout << "5.c Adding arc (" << z << "," << x << ")" <<
849  // std::endl;
850  marks[{z, x}] = '>';
851  marks[{x, z}] = '-';
852  if (!arc_probas__.exists(Arc(z, x)))
853  arc_probas__.insert(Arc(z, x), std::get< 2 >(best));
854  } else if (!existsDirectedPath__(graph, z, x)) {
855  graph.addArc(x, z);
856  // std::cout << "5.d Adding arc (" << x << "," << z << ")" <<
857  // std::endl;
858  marks[{z, x}] = '-';
859  marks[{x, z}] = '>';
860  latent_couples__.push_back(Arc(x, z));
861  if (!arc_probas__.exists(Arc(x, z)))
862  arc_probas__.insert(Arc(x, z), std::get< 2 >(best));
863  }
864  }
865  }
866 
867  delete std::get< 0 >(best);
868  proba_triples.erase(proba_triples.begin());
869  // actualisation of the list of triples
870  proba_triples = updateProbaTriples_(graph, proba_triples);
871 
872  if (!proba_triples.empty()) best = proba_triples[0];
873 
874  ++current_step_;
875  if (onProgress.hasListener()) {
877  (current_step_ * 100) / (steps_orient + past_steps),
878  0.,
879  timer_.step());
880  }
881  } // while
882 
883  // erasing the double headed arcs
884  for (auto iter = latent_couples__.rbegin(); iter != latent_couples__.rend();
885  ++iter) {
886  graph.eraseArc(Arc(iter->head(), iter->tail()));
887  if (existsDirectedPath__(graph, iter->head(), iter->tail())) {
888  // if we find a cycle, we force the competing edge
889  graph.addArc(iter->head(), iter->tail());
890  graph.eraseArc(Arc(iter->tail(), iter->head()));
891  *iter = Arc(iter->head(), iter->tail());
892  }
893  }
894 
895  if (onProgress.hasListener()) {
896  GUM_EMIT3(onProgress, 100, 0., timer_.step());
897  }
898  }
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< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > getUnshieldedTriplesMIIC_(const MixedGraph &graph, CorrectedMutualInformation<> &I, const HashTable< std::pair< NodeId, NodeId >, std::vector< NodeId > > &sep_set, 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:1030
ArcProperty< double > arc_probas__
Storing the propabilities for each arc set in the graph.
Definition: Miic.h:361
std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > updateProbaTriples_(const MixedGraph &graph, std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > proba_triples)
Gets the orientation probabilities like MIIC for the orientation phase.
Definition: Miic.cpp:1082
const bool existsDirectedPath__(const MixedGraph &graph, const NodeId n1, const NodeId n2, const bool countArc=true) const
checks for directed paths in a graph, consider double arcs like edges
Definition: Miic.cpp:1262
HashTable< std::pair< NodeId, NodeId >, char > initial_marks__
Initial marks for the orientation phase, used to convey constraints.
Definition: Miic.h:364
std::vector< Arc > latent_couples__
an empty vector of arcs
Definition: Miic.h:353
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 148 of file approximationScheme_inl.h.

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

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

◆ propagatesHead_()

void gum::learning::Miic::propagatesHead_ ( MixedGraph graph,
NodeId  node 
)
protected

Propagates the orientation from a node to its neighbours.

Definition at line 1170 of file Miic.cpp.

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

1170  {
1171  const auto neighbours = graph.neighbours(node);
1172  for (auto& neighbour: neighbours) {
1173  // std::cout << "Orientation de l'edge (" << node << "," << neighbour <<
1174  // ")" << std::endl;
1175  if (graph.neighbours(neighbour).contains(node)) {
1176  if (!existsDirectedPath__(graph, neighbour, node)
1177  && !(initial_marks__.exists({node, neighbour})
1178  && initial_marks__[{node, neighbour}] == '-')
1179  && graph.parents(neighbour).empty()) {
1180  graph.eraseEdge(Edge(neighbour, node));
1181  graph.addArc(node, neighbour);
1182  // std::cout << "1. Removing edge (" << neighbour << "," << node << ")"
1183  // << std::endl; std::cout << "1. Adding arc (" << node << "," <<
1184  // neighbour << ")" << std::endl;
1185  propagatesHead_(graph, neighbour);
1186  } else if (!existsDirectedPath__(graph, node, neighbour)
1187  && !(initial_marks__.exists({neighbour, node})
1188  && initial_marks__[{neighbour, node}] == '-')
1189  && graph.parents(node).empty()) {
1190  graph.eraseEdge(Edge(neighbour, node));
1191  graph.addArc(neighbour, node);
1192  // std::cout << "2. Removing edge (" << neighbour << "," << node << ")"
1193  // << std::endl; std::cout << "2. Adding arc (" << neighbour << "," <<
1194  // node << ")" << std::endl;
1195  } else if (!existsDirectedPath__(graph, node, neighbour)
1196  && !(initial_marks__.exists({neighbour, node})
1197  && initial_marks__[{neighbour, node}] == '-')) {
1198  graph.eraseEdge(Edge(neighbour, node));
1199  graph.addArc(neighbour, node);
1200  if (!graph.parents(neighbour).empty()
1201  && !graph.parents(node).empty()) {
1202  latent_couples__.push_back(Arc(node, neighbour));
1203  }
1204 
1205  // std::cout << "3. Removing edge (" << neighbour << "," << node << ")"
1206  // << std::endl; std::cout << "3. Adding arc (" << neighbour << "," <<
1207  // node << ")" << std::endl;
1208  } else if (!existsDirectedPath__(graph, neighbour, node)
1209  && !(initial_marks__.exists({node, neighbour})
1210  && initial_marks__[{node, neighbour}] == '-')) {
1211  graph.eraseEdge(Edge(node, neighbour));
1212  graph.addArc(node, neighbour);
1213  if (!graph.parents(neighbour).empty()
1214  && !graph.parents(node).empty()) {
1215  latent_couples__.push_back(Arc(node, neighbour));
1216  }
1217  // std::cout << "4. Removing edge (" << neighbour << "," << node << ")"
1218  // << std::endl; std::cout << "4. Adding arc (" << node << "," <<
1219  // neighbour << ")" << std::endl;
1220  }
1221  // else if (!graph.parents(neighbour).empty()
1222  //&& !graph.parents(node).empty()) {
1223  // graph.eraseEdge(Edge(neighbour, node));
1224  // graph.addArc(node, neighbour);
1225  //__latent_couples.push_back(Arc(node, neighbour));
1226  //}
1227  else {
1228  graph.eraseEdge(Edge(neighbour, node));
1229  // std::cout << "5. Removing edge (" << neighbour << "," << node << ")"
1230  // << std::endl;
1231  }
1232  }
1233  }
1234  }
void propagatesHead_(MixedGraph &graph, NodeId node)
Propagates the orientation from a node to its neighbours.
Definition: Miic.cpp:1170
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
const bool existsDirectedPath__(const MixedGraph &graph, const NodeId n1, const NodeId n2, const bool countArc=true) const
checks for directed paths in a graph, consider double arcs like edges
Definition: Miic.cpp:1262
HashTable< std::pair< NodeId, NodeId >, char > initial_marks__
Initial marks for the orientation phase, used to convey constraints.
Definition: Miic.h:364
std::vector< Arc > latent_couples__
an empty vector of arcs
Definition: Miic.h:353
+ 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 209 of file approximationScheme_inl.h.

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

209  {
210  if (burn_in_ > current_step_) {
211  return burn_in_ - current_step_;
212  } else {
213  return 0;
214  }
215  }
Size burn_in_
Number of iterations before checking stopping criteria.
Size current_step_
The current step.
+ Here is the call graph for this function:

◆ set3off2Behaviour()

void gum::learning::Miic::set3off2Behaviour ( )

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

Definition at line 1254 of file Miic.cpp.

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

1254 { this->usemiic__ = false; }
bool usemiic__
wether to use the miic algorithm or not
Definition: Miic.h:358
+ 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:54
+ 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 94 of file approximationScheme_inl.h.

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

94  {
95  if (max < 1) { GUM_ERROR(OutOfLowerBound, "max should be >=1"); }
96  max_iter_ = max;
97  enabled_max_iter_ = true;
98  }
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:54
+ 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 117 of file approximationScheme_inl.h.

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

117  {
118  if (timeout <= 0.) { GUM_ERROR(OutOfLowerBound, "timeout should be >0."); }
119  max_time_ = timeout;
120  enabled_max_time_ = true;
121  }
double max_time_
The timeout.
bool enabled_max_time_
If true, the timeout is enabled.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:54
+ 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 1253 of file Miic.cpp.

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

1253 { this->usemiic__ = true; }
bool usemiic__
wether to use the miic algorithm or not
Definition: Miic.h:358
+ 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 65 of file approximationScheme_inl.h.

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

65  {
66  if (rate < 0) { GUM_ERROR(OutOfLowerBound, "rate should be >=0"); }
67 
68  min_rate_eps_ = rate;
69  enabled_min_rate_eps_ = true;
70  }
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:54
+ 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 142 of file approximationScheme_inl.h.

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

142  {
143  if (p < 1) { GUM_ERROR(OutOfLowerBound, "p should be >=1"); }
144 
145  period_size_ = p;
146  }
Size period_size_
Checking criteria frequency.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:54
+ 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 151 of file approximationScheme_inl.h.

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

151 { 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 196 of file approximationScheme_inl.h.

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

196  {
197  if (current_step_ < burn_in_) { return false; }
198 
199  if (period_size_ == 1) { return true; }
200 
201  return ((current_step_ - burn_in_) % period_size_ == 0);
202  }
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 157 of file approximationScheme_inl.h.

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

157  {
158  return current_state_;
159  }
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 218 of file approximationScheme_inl.h.

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

+ 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 205 of file approximationScheme_inl.h.

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

205  {
206  current_step_ += incr;
207  }
Size current_step_
The current step.
+ Here is the call graph for this function:

◆ updateProbaTriples_()

std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > > gum::learning::Miic::updateProbaTriples_ ( const MixedGraph graph,
std::vector< std::tuple< std::tuple< NodeId, NodeId, NodeId > *, double, double, double > >  proba_triples 
)
protected

Gets the orientation probabilities like MIIC for the orientation phase.

Definition at line 1082 of file Miic.cpp.

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

1087  {
1088  for (auto& triple: proba_triples) {
1089  NodeId x, y, z;
1090  x = std::get< 0 >(*std::get< 0 >(triple));
1091  y = std::get< 1 >(*std::get< 0 >(triple));
1092  z = std::get< 2 >(*std::get< 0 >(triple));
1093  const double Ixyz = std::get< 1 >(triple);
1094  double Pxz = std::get< 2 >(triple);
1095  double Pyz = std::get< 3 >(triple);
1096 
1097  if (Ixyz <= 0) {
1098  const double expo = std::exp(Ixyz);
1099  const double P0 = (1 + expo) / (1 + 3 * expo);
1100  // distinguish betweeen the initialization and the update process
1101  if (Pxz == Pyz && Pyz == 0.5) {
1102  std::get< 2 >(triple) = P0;
1103  std::get< 3 >(triple) = P0;
1104  } else {
1105  if (graph.existsArc(x, z) && Pxz >= P0) {
1106  std::get< 3 >(triple) = Pxz * (1 / (1 + expo) - 0.5) + 0.5;
1107  } else if (graph.existsArc(y, z) && Pyz >= P0) {
1108  std::get< 2 >(triple) = Pyz * (1 / (1 + expo) - 0.5) + 0.5;
1109  }
1110  }
1111  } else {
1112  const double expo = std::exp(-Ixyz);
1113  if (graph.existsArc(x, z) && Pxz >= 0.5) {
1114  std::get< 3 >(triple) = Pxz * (1 / (1 + expo) - 0.5) + 0.5;
1115  } else if (graph.existsArc(y, z) && Pyz >= 0.5) {
1116  std::get< 2 >(triple) = Pyz * (1 / (1 + expo) - 0.5) + 0.5;
1117  }
1118  }
1119  }
1120  std::sort(proba_triples.begin(), proba_triples.end(), GreaterTupleOnLast());
1121  return proba_triples;
1122  }
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 153 of file approximationScheme_inl.h.

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

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

Member Data Documentation

◆ arc_probas__

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

Storing the propabilities for each arc set in the graph.

Definition at line 361 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.

◆ empty_set__

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

an empty conditioning set

Definition at line 351 of file Miic.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.

◆ initial_marks__

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

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

Definition at line 364 of file Miic.h.

◆ last_epsilon_

double gum::ApproximationScheme::last_epsilon_
protectedinherited

Last epsilon value.

Definition at line 371 of file approximationScheme.h.

◆ latent_couples__

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

an empty vector of arcs

Definition at line 353 of file Miic.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.

◆ maxLog__

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

Fixes the maximum log that we accept in exponential computations.

Definition at line 349 of file Miic.h.

◆ min_rate_eps_

double gum::ApproximationScheme::min_rate_eps_
protectedinherited

Threshold for the epsilon rate.

Definition at line 395 of file approximationScheme.h.

◆ N__

Size gum::learning::Miic::N__
private

size of the database

Definition at line 356 of file Miic.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.

◆ usemiic__

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

wether to use the miic algorithm or not

Definition at line 358 of file Miic.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: