aGrUM 3.0.0
a C++ library for (probabilistic) graphical models
IBNLearner_inl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41#pragma once
42
43
52
53// to help IDE parser
56
57namespace gum::learning {
58
59
60 // returns the row filter
62
63 // returns the modalities of the variables
64 INLINE const std::vector< std::size_t >& IBNLearner::Database::domainSizes() const {
65 return _domain_sizes_;
66 }
67
68 // returns the names of the variables in the database
69 INLINE const std::vector< std::string >& IBNLearner::Database::names() const {
70 return _database_.variableNames();
71 }
72
74 INLINE void IBNLearner::Database::setDatabaseWeight(const double new_weight) {
75 if (_database_.nbRows() == std::size_t(0)) return;
76 const double weight = new_weight / double(_database_.nbRows());
77 _database_.setAllRowsWeight(weight);
78 }
79
80 // returns the node id corresponding to a variable name
81 INLINE NodeId IBNLearner::Database::idFromName(std::string_view var_name) const {
82 try {
83 const auto cols = _database_.columnsFromVariableName(var_name);
84 return _nodeId2cols_.first(cols[0]);
85 } catch (...) {
87 "Variable " << var_name << " could not be found in the database")
88 }
89 }
90
91 // returns the variable name corresponding to a given node id
92 INLINE const std::string& IBNLearner::Database::nameFromId(NodeId id) const {
93 try {
94 return _database_.variableName(_nodeId2cols_.second(id));
95 } catch (...) {
97 "Variable of Id " << id << " could not be found in the database")
98 }
99 }
100
103
105 INLINE const std::vector< std::string >& IBNLearner::Database::missingSymbols() const {
106 return _database_.missingSymbols();
107 }
108
113
115 INLINE std::size_t IBNLearner::Database::nbRows() const { return _database_.nbRows(); }
116
118 INLINE std::size_t IBNLearner::Database::size() const { return _database_.size(); }
119
121 INLINE void IBNLearner::Database::setWeight(const std::size_t i, const double weight) {
122 _database_.setWeight(i, weight);
123 }
124
126 INLINE double IBNLearner::Database::weight(const std::size_t i) const {
127 return _database_.weight(i);
128 }
129
131 INLINE double IBNLearner::Database::weight() const { return _database_.weight(); }
132
133 // ===========================================================================
134
135 // returns the node id corresponding to a variable name
136 INLINE NodeId IBNLearner::idFromName(std::string_view var_name) const {
137 return scoreDatabase_.idFromName(var_name);
138 }
139
140 // returns the variable name corresponding to a given node id
141 INLINE const std::string& IBNLearner::nameFromId(NodeId id) const {
142 return scoreDatabase_.nameFromId(id);
143 }
144
146 INLINE void IBNLearner::setDatabaseWeight(const double new_weight) {
147 scoreDatabase_.setDatabaseWeight(new_weight);
148 }
149
151 INLINE void IBNLearner::setRecordWeight(const std::size_t i, const double new_weight) {
152 scoreDatabase_.setWeight(i, new_weight);
153 }
154
156 INLINE double IBNLearner::recordWeight(const std::size_t i) const {
157 return scoreDatabase_.weight(i);
158 }
159
161 INLINE double IBNLearner::databaseWeight() const { return scoreDatabase_.weight(); }
162
163 // sets an initial DAG structure
164 INLINE void IBNLearner::setInitialDAG(const DAG& dag) { initialDag_ = dag; }
165
167
168 // indicate that we wish to use an AIC score
173
174 // indicate that we wish to use a BD score
179
180 // indicate that we wish to use a BDeu score
185
186 // indicate that we wish to use a BIC score
191
192 // indicate that we wish to use a fNML score
197
198 // indicate that we wish to use a K2 score
203
204 // indicate that we wish to use a Log2Likelihood score
209
210 // indicate that we wish to use a MDL score
215
216 // sets the max indegree
217 INLINE void IBNLearner::setMaxIndegree(Size max_indegree) {
218 constraintIndegree_.setMaxIndegree(max_indegree);
219 }
220
221 // indicate that we wish to use MIIC with constraints
223
224 // indicate that we wish to use the PC algorithm
226
227 // indicate that we wish to use the FCI algorithm
229
230 // select Chi2 independence test for FCI (default)
233 GUM_ERROR(OperationNotAllowed, "useFCIChi2Test() is only valid when using the FCI algorithm")
234 }
236 }
237
238 // select G2 independence test for FCI
241 GUM_ERROR(OperationNotAllowed, "useFCIG2Test() is only valid when using the FCI algorithm")
242 }
244 }
245
246 // set alpha threshold for FCI
247 INLINE void IBNLearner::setFCIAlpha(double alpha) {
249 GUM_ERROR(OperationNotAllowed, "setFCIAlpha() is only valid when using the FCI algorithm")
250 }
251 alphaFci_ = alpha;
252 }
253
254 // set max discriminating-path length for FCI R4 (Size(-1) = unlimited)
258 "setFCIMaxPathLength() is only valid when using the FCI algorithm")
259 }
260 maxPathLengthFci_ = max_len;
261 }
262
263 INLINE void IBNLearner::setFCIExhaustiveSepSet(bool exhaustive) {
266 "setFCIExhaustiveSepSet() is only valid when using the FCI algorithm")
267 }
268 exhaustiveSepSetFci_ = exhaustive;
269 }
270
274 "fciExhaustiveSepSet() is only valid when using the FCI algorithm")
275 }
277 }
278
279 // select Chi2 independence test for PC (default)
282 GUM_ERROR(OperationNotAllowed, "useChi2Test() is only valid when using the PC algorithm")
283 }
285 }
286
287 // select G2 independence test for PC
288 INLINE void IBNLearner::useG2Test() {
290 GUM_ERROR(OperationNotAllowed, "useG2Test() is only valid when using the PC algorithm")
291 }
293 }
294
295 // set the alpha threshold for PC
296 INLINE void IBNLearner::setPCAlpha(double alpha) {
298 GUM_ERROR(OperationNotAllowed, "setPCAlpha() is only valid when using the PC algorithm")
299 }
300 alphaPc_ = alpha;
301 }
302
303 // set stable mode for PC
304 INLINE void IBNLearner::setPCStable(bool stable) {
306 GUM_ERROR(OperationNotAllowed, "setPCStable() is only valid when using the PC algorithm")
307 }
308 stablePc_ = stable;
309 }
310
311 // set max conditioning set size for PC (Size(-1) = unlimited)
315 "setPCMaxCondSetSize() is only valid when using the PC algorithm")
316 }
317 maxCondSetSizePc_ = max_k;
318 }
319
320 // set unshielded-collider ordering for PC
324 "setPCUnshieldedColliderSorted() is only valid when using the PC algorithm")
325 }
326 sortedUCPc_ = sorted;
327 }
328
333
338
343
345 INLINE std::vector< Arc > IBNLearner::latentVariables() const {
346 return algoMiic_.latentVariables();
347 }
348
349 // indicate that we wish to use a K2 algorithm
350 INLINE void IBNLearner::useK2(const Sequence< NodeId >& order) {
352 algoK2_.setOrder(order);
353 }
354
355 // indicate that we wish to use a K2 algorithm
356 INLINE void IBNLearner::useK2(const std::vector< NodeId >& order) {
358 algoK2_.setOrder(order);
359 }
360
361 // indicate that we wish to use a greedy hill climbing algorithm
365
366 // indicate that we wish to use a greedy hill climbing algorithm
370
371 // indicate that we wish to use greedy thick-thinning
375
376 // enable or disable arc reversals in the thin phase of greedy thick-thinning
378 greedyThickThinning_.setAllowReversalsInThinPhase(allow);
379 }
380
381 // returns whether arc reversals are allowed in the thin phase
383 return greedyThickThinning_.allowReversalsInThinPhase();
384 }
385
386 // indicate that we wish to use a local search with tabu list
387 INLINE void IBNLearner::useLocalSearchWithTabuList(Size tabu_size, Size nb_decrease) {
389 nbDecreasingChanges_ = nb_decrease;
390 constraintTabuList_.setTabuListSize(tabu_size);
391 localSearchWithTabuList_.setMaxNbDecreasingChanges(nb_decrease);
392 }
393
395 INLINE void IBNLearner::useEM(const double epsilon, const double noise) {
396 if (epsilon < 0.0)
397 GUM_ERROR(OutOfBounds, "EM's min log-likelihood evolution rate must be non-negative");
398 if ((noise < 0.0) || (noise > 1.0))
399 GUM_ERROR(OutOfBounds, "EM's noise must belong to interval [0,1]");
400 if (epsilon > 0) {
401 useEM_ = true;
402 dag2BN_.setMinEpsilonRate(epsilon);
403 dag2BN_.setNoise(noise);
404 noiseEM_ = noise;
405 } else {
406 useEM_ = false; // epsilon == 0
407 }
408 }
409
411 INLINE void IBNLearner::useEMWithRateCriterion(const double epsilon, const double noise) {
412 if (epsilon <= 0.0)
413 GUM_ERROR(OutOfBounds, "EM's min log-likelihood evolution rate must be positive");
414 useEM(epsilon, noise);
415 }
416
418 INLINE void IBNLearner::useEMWithDiffCriterion(const double epsilon, const double noise) {
419 if (epsilon <= 0.0)
420 GUM_ERROR(OutOfBounds, "EM's min log-likelihood differences must be positive");
421 if ((noise < 0.0) || (noise > 1.0))
422 GUM_ERROR(OutOfBounds, "EM's noise must belong to interval [0,1]");
423 useEM_ = true;
424 dag2BN_.setEpsilon(epsilon);
425 dag2BN_.setNoise(noise);
426 noiseEM_ = noise;
427 }
428
430 INLINE void IBNLearner::forbidEM() { useEM_ = false; }
431
433 INLINE bool IBNLearner::isUsingEM() const { return useEM_; }
434
437 if (useEM_) return dag2BN_;
438 else GUM_ERROR(NotFound, "EM is currently forbidden. Please enable it with useEM()")
439 }
440
446
448 INLINE std::string IBNLearner::EMStateMessage() const {
449 if (useEM_) return dag2BN_.messageApproximationScheme();
450 else return "EM is currently forbidden. Please enable it with useEM()";
451 }
452
453 // allow (true)/forbid (false) to add arcs during learning
454 INLINE void IBNLearner::allowArcAdditions(bool allow) { allowArcAdditions_ = allow; }
455
456 // allow (true)/forbid (false) to delete arcs during learning
457 INLINE void IBNLearner::allowArcDeletions(bool allow) { allowArcDeletions_ = allow; }
458
459 // allow (true)/forbid (false) to reverse arcs during learning
460 INLINE void IBNLearner::allowArcReversals(bool allow) { allowArcReversals_ = allow; }
461
462 // allow (true)/forbid (false) to delete arc triangles during learning
465 }
466
467 INLINE bool IBNLearner::hasMissingValues() const {
468 return scoreDatabase_.databaseTable().hasMissingValues();
469 }
470
471 // assign a set of forbidden edges
472 INLINE void IBNLearner::setPossibleEdges(const EdgeSet& set) {
473 constraintPossibleEdges_.setEdges(set);
474 }
475
476 // assign a set of forbidden edges from an UndiGraph
480
481 // assign a new possible edge
482 INLINE void IBNLearner::addPossibleEdge(const Edge& edge) {
483 constraintPossibleEdges_.addEdge(edge);
484 }
485
486 // remove a forbidden edge
487 INLINE void IBNLearner::erasePossibleEdge(const Edge& edge) {
488 constraintPossibleEdges_.eraseEdge(edge);
489 }
490
491 // assign a new forbidden edge
492 INLINE void IBNLearner::addPossibleEdge(const NodeId tail, const NodeId head) {
493 addPossibleEdge(Edge(tail, head));
494 }
495
496 // remove a forbidden edge
497 INLINE void IBNLearner::erasePossibleEdge(const NodeId tail, const NodeId head) {
498 erasePossibleEdge(Edge(tail, head));
499 }
500
501 // assign a new forbidden edge
502 INLINE void IBNLearner::addPossibleEdge(std::string_view tail, std::string_view head) {
504 }
505
506 // remove a forbidden edge
507 INLINE void IBNLearner::erasePossibleEdge(std::string_view tail, std::string_view head) {
509 }
510
511 // assign a set of forbidden arcs
512 INLINE void IBNLearner::setForbiddenArcs(const ArcSet& set) {
513 constraintForbiddenArcs_.setArcs(set);
514 }
515
516 // assign a new forbidden arc
517 INLINE void IBNLearner::addForbiddenArc(const Arc& arc) { constraintForbiddenArcs_.addArc(arc); }
518
519 // remove a forbidden arc
520 INLINE void IBNLearner::eraseForbiddenArc(const Arc& arc) {
521 constraintForbiddenArcs_.eraseArc(arc);
522 }
523
524 // assign a new forbidden arc
525 INLINE void IBNLearner::addForbiddenArc(const NodeId tail, const NodeId head) {
526 addForbiddenArc(Arc(tail, head));
527 }
528
529 // remove a forbidden arc
530 INLINE void IBNLearner::eraseForbiddenArc(const NodeId tail, const NodeId head) {
531 eraseForbiddenArc(Arc(tail, head));
532 }
533
534 // assign a new forbidden arc
535 INLINE void IBNLearner::addForbiddenArc(std::string_view tail, std::string_view head) {
537 }
538
539 // remove a forbidden arc
540 INLINE void IBNLearner::eraseForbiddenArc(std::string_view tail, std::string_view head) {
542 }
543
544 // assign a set of forbidden arcs
545 INLINE void IBNLearner::setMandatoryArcs(const ArcSet& set) {
546 constraintMandatoryArcs_.setArcs(set);
547 }
548
549 // assign a new forbidden arc
550 INLINE void IBNLearner::addMandatoryArc(const Arc& arc) { constraintMandatoryArcs_.addArc(arc); }
551
552 // remove a forbidden arc
553 INLINE void IBNLearner::eraseMandatoryArc(const Arc& arc) {
554 constraintMandatoryArcs_.eraseArc(arc);
555 }
556
558
559 INLINE void IBNLearner::addNoParentNode(std::string_view name) {
561 }
562
564 constraintNoParentNodes_.eraseNode(node);
565 }
566
567 INLINE void IBNLearner::eraseNoParentNode(std::string_view name) {
569 }
570
572 constraintNoChildrenNodes_.addNode(node);
573 }
574
575 INLINE void IBNLearner::addNoChildrenNode(std::string_view name) {
577 }
578
580 constraintNoChildrenNodes_.eraseNode(node);
581 }
582
583 INLINE void IBNLearner::eraseNoChildrenNode(std::string_view name) {
585 }
586
587 // assign a new forbidden arc
588 INLINE void IBNLearner::addMandatoryArc(std::string_view tail, std::string_view head) {
590 }
591
592 // remove a forbidden arc
593 INLINE void IBNLearner::eraseMandatoryArc(std::string_view tail, std::string_view head) {
595 }
596
597 // assign a new forbidden arc
598 INLINE void IBNLearner::addMandatoryArc(NodeId tail, NodeId head) {
599 addMandatoryArc(Arc(tail, head));
600 }
601
602 // remove a forbidden arc
604 eraseMandatoryArc(Arc(tail, head));
605 }
606
607 // sets a partial order on the nodes
611
612 INLINE void IBNLearner::setSliceOrder(const std::vector< std::vector< std::string > >& slices) {
613 NodeProperty< NodeId > slice_order;
614 NodeId rank = 0;
615 for (const auto& slice: slices) {
616 for (const auto& name: slice) {
617 slice_order.insert(idFromName(name), rank);
618 }
619 rank++;
620 }
621 setSliceOrder(slice_order);
622 }
623
625
626 // sets a total order over some nodes
630
631 // sets a total order over some nodes
632 INLINE void IBNLearner::setTotalOrder(const std::vector< std::string >& order) {
633 Sequence< NodeId > sequence;
634 for (const auto& name: order) {
635 sequence.insert(idFromName(name));
636 }
637 setTotalOrder(sequence);
638 }
639
640 // removes the current total ordering constraint, if any
642
643 // sets the prior weight
644 INLINE void IBNLearner::_setPriorWeight_(double weight) {
645 if (weight < 0) { GUM_ERROR(OutOfBounds, "the weight of the prior must be positive") }
646
647 priorWeight_ = weight;
649 }
650
651 // use the prior smoothing
656
657 // use the prior smoothing
658 INLINE void IBNLearner::useSmoothingPrior(double weight) {
659 if (weight < 0) { GUM_ERROR(OutOfBounds, "the weight of the prior must be positive") }
660
662 _setPriorWeight_(weight);
663
665 }
666
667 // use the Dirichlet prior
668 INLINE void IBNLearner::useDirichletPrior(std::string_view filename, double weight) {
669 if (weight < 0) { GUM_ERROR(OutOfBounds, "the weight of the prior must be positive") }
670
671 priorDbname_ = filename;
673 _setPriorWeight_(weight);
674
676 }
677
678 // use the prior BDeu
679 INLINE void IBNLearner::useBDeuPrior(double weight) {
680 if (weight < 0) { GUM_ERROR(OutOfBounds, "the weight of the prior must be positive") }
681
683 _setPriorWeight_(weight);
684
686 }
687
688 // returns the type (as a string) of a given prior
690 switch (priorType_) {
692 case NO_prior : return PriorType::NoPriorType;
696 case BDEU : return PriorType::BDeuPriorType;
697 default :
699 "IBNLearner getPriorType does "
700 "not support yet this prior")
701 }
702 }
703
704 // returns the names of the variables in the database
705 INLINE const std::vector< std::string >& IBNLearner::names() const {
706 return scoreDatabase_.names();
707 }
708
709 // returns the modalities of the variables in the database
710 INLINE const std::vector< std::size_t >& IBNLearner::domainSizes() const {
711 return scoreDatabase_.domainSizes();
712 }
713
714 // returns the modalities of a variable in the database
715 INLINE Size IBNLearner::domainSize(NodeId var) const { return scoreDatabase_.domainSizes()[var]; }
716
717 // returns the modalities of a variables in the database
718 INLINE Size IBNLearner::domainSize(std::string_view var) const {
719 return scoreDatabase_.domainSizes()[idFromName(var)];
720 }
721
723 INLINE const std::vector< std::pair< std::size_t, std::size_t > >&
725 return ranges_;
726 }
727
729 INLINE void IBNLearner::clearDatabaseRanges() { ranges_.clear(); }
730
732 INLINE const DatabaseTable& IBNLearner::database() const {
733 return scoreDatabase_.databaseTable();
734 }
735
736 INLINE Size IBNLearner::nbCols() const { return scoreDatabase_.domainSizes().size(); }
737
738 INLINE Size IBNLearner::nbRows() const { return scoreDatabase_.databaseTable().size(); }
739
740 // sets the number max of threads that can be used
743 if (score_ != nullptr) score_->setNumberOfThreads(nb);
744 }
745
746 // ===========================================================================
747 // IBNLearner — inline implementations migrated from class body
748 // ===========================================================================
749
750 INLINE bool IBNLearner::isConstraintBased() const {
751 switch (selectedAlgo_) {
752 case AlgoType::K2 :
756 case AlgoType::GREEDY_THICK_THINNING : return false;
757 case AlgoType::MIIC :
758 case AlgoType::PC :
759 case AlgoType::FCI : return true;
760 default : throw OperationNotAllowed("Unknown algorithm");
761 }
762 }
763
764 INLINE bool IBNLearner::isScoreBased() const { return !isConstraintBased(); }
765
766 INLINE void
768 currentAlgorithm_ = approximationScheme;
769 }
770
771 INLINE void IBNLearner::distributeProgress(const ApproximationScheme* approximationScheme,
772 Size pourcent,
773 double error,
774 double time) {
775 setCurrentApproximationScheme(approximationScheme);
776 if (onProgress.hasListener()) GUM_EMIT3(onProgress, pourcent, error, time);
777 }
778
779 INLINE void IBNLearner::distributeStop(const ApproximationScheme* approximationScheme,
780 std::string_view message) {
781 setCurrentApproximationScheme(approximationScheme);
782 if (onStop.hasListener()) GUM_EMIT1(onStop, message);
783 }
784
785 INLINE void IBNLearner::setEpsilon(double eps) {
786 algoK2_.approximationScheme().setEpsilon(eps);
787 greedyHillClimbing_.setEpsilon(eps);
788 localSearchWithTabuList_.setEpsilon(eps);
789 dag2BN_.setEpsilon(eps);
790 }
791
792 INLINE double IBNLearner::epsilon() const {
793 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->epsilon();
794 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
795 }
796
798 algoK2_.approximationScheme().disableEpsilon();
799 greedyHillClimbing_.disableEpsilon();
800 localSearchWithTabuList_.disableEpsilon();
801 dag2BN_.disableEpsilon();
802 }
803
805 algoK2_.approximationScheme().enableEpsilon();
806 greedyHillClimbing_.enableEpsilon();
807 localSearchWithTabuList_.enableEpsilon();
808 dag2BN_.enableEpsilon();
809 }
810
811 INLINE bool IBNLearner::isEnabledEpsilon() const {
812 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->isEnabledEpsilon();
813 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
814 }
815
816 INLINE void IBNLearner::setMinEpsilonRate(double rate) {
817 algoK2_.approximationScheme().setMinEpsilonRate(rate);
818 greedyHillClimbing_.setMinEpsilonRate(rate);
819 localSearchWithTabuList_.setMinEpsilonRate(rate);
820 dag2BN_.setMinEpsilonRate(rate);
821 }
822
823 INLINE double IBNLearner::minEpsilonRate() const {
824 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->minEpsilonRate();
825 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
826 }
827
829 algoK2_.approximationScheme().disableMinEpsilonRate();
830 greedyHillClimbing_.disableMinEpsilonRate();
831 localSearchWithTabuList_.disableMinEpsilonRate();
832 dag2BN_.disableMinEpsilonRate();
833 }
834
836 algoK2_.approximationScheme().enableMinEpsilonRate();
837 greedyHillClimbing_.enableMinEpsilonRate();
838 localSearchWithTabuList_.enableMinEpsilonRate();
839 dag2BN_.enableMinEpsilonRate();
840 }
841
843 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->isEnabledMinEpsilonRate();
844 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
845 }
846
847 INLINE void IBNLearner::setMaxIter(Size max) {
848 algoK2_.approximationScheme().setMaxIter(max);
849 greedyHillClimbing_.setMaxIter(max);
850 localSearchWithTabuList_.setMaxIter(max);
851 dag2BN_.setMaxIter(max);
852 }
853
854 INLINE Size IBNLearner::maxIter() const {
855 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->maxIter();
856 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
857 }
858
860 algoK2_.approximationScheme().disableMaxIter();
861 greedyHillClimbing_.disableMaxIter();
862 localSearchWithTabuList_.disableMaxIter();
863 dag2BN_.disableMaxIter();
864 }
865
867 algoK2_.approximationScheme().enableMaxIter();
868 greedyHillClimbing_.enableMaxIter();
869 localSearchWithTabuList_.enableMaxIter();
870 dag2BN_.enableMaxIter();
871 }
872
873 INLINE bool IBNLearner::isEnabledMaxIter() const {
874 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->isEnabledMaxIter();
875 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
876 }
877
878 INLINE void IBNLearner::setMaxTime(double timeout) {
879 algoK2_.approximationScheme().setMaxTime(timeout);
880 greedyHillClimbing_.setMaxTime(timeout);
881 localSearchWithTabuList_.setMaxTime(timeout);
882 dag2BN_.setMaxTime(timeout);
883 }
884
885 INLINE double IBNLearner::maxTime() const {
886 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->maxTime();
887 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
888 }
889
890 INLINE double IBNLearner::currentTime() const {
891 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->currentTime();
892 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
893 }
894
896 algoK2_.approximationScheme().disableMaxTime();
897 greedyHillClimbing_.disableMaxTime();
898 localSearchWithTabuList_.disableMaxTime();
899 dag2BN_.disableMaxTime();
900 }
901
903 algoK2_.approximationScheme().enableMaxTime();
904 greedyHillClimbing_.enableMaxTime();
905 localSearchWithTabuList_.enableMaxTime();
906 dag2BN_.enableMaxTime();
907 }
908
909 INLINE bool IBNLearner::isEnabledMaxTime() const {
910 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->isEnabledMaxTime();
911 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
912 }
913
915 algoK2_.approximationScheme().setPeriodSize(p);
916 greedyHillClimbing_.setPeriodSize(p);
917 localSearchWithTabuList_.setPeriodSize(p);
918 dag2BN_.setPeriodSize(p);
919 }
920
922 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->periodSize();
923 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
924 }
925
926 INLINE void IBNLearner::setVerbosity(bool v) {
927 algoK2_.approximationScheme().setVerbosity(v);
928 greedyHillClimbing_.setVerbosity(v);
929 localSearchWithTabuList_.setVerbosity(v);
930 dag2BN_.setVerbosity(v);
931 }
932
933 INLINE bool IBNLearner::verbosity() const {
934 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->verbosity();
935 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
936 }
937
940 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->stateApproximationScheme();
941 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
942 }
943
945 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->nbrIterations();
946 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
947 }
948
949 INLINE const std::vector< double >& IBNLearner::history() const {
950 if (currentAlgorithm_ != nullptr) return currentAlgorithm_->history();
951 else GUM_ERROR(FatalError, "No chosen algorithm for learning")
952 }
953
954 // EM methods
955
956 INLINE void IBNLearner::EMsetEpsilon(double eps) { dag2BN_.setEpsilon(eps); }
957
958 INLINE double IBNLearner::EMEpsilon() const { return dag2BN_.epsilon(); }
959
960 INLINE void IBNLearner::EMdisableEpsilon() { dag2BN_.disableEpsilon(); }
961
962 INLINE void IBNLearner::EMenableEpsilon() { dag2BN_.enableEpsilon(); }
963
964 INLINE bool IBNLearner::EMisEnabledEpsilon() const { return dag2BN_.isEnabledEpsilon(); }
965
966 INLINE void IBNLearner::EMsetMinEpsilonRate(double rate) { dag2BN_.setMinEpsilonRate(rate); }
967
968 INLINE double IBNLearner::EMMinEpsilonRate() const { return dag2BN_.minEpsilonRate(); }
969
970 INLINE void IBNLearner::EMdisableMinEpsilonRate() { dag2BN_.disableMinEpsilonRate(); }
971
972 INLINE void IBNLearner::EMenableMinEpsilonRate() { dag2BN_.enableMinEpsilonRate(); }
973
975 return dag2BN_.isEnabledMinEpsilonRate();
976 }
977
978 INLINE void IBNLearner::EMsetMaxIter(Size max) { dag2BN_.setMaxIter(max); }
979
980 INLINE Size IBNLearner::EMMaxIter() const { return dag2BN_.maxIter(); }
981
982 INLINE void IBNLearner::EMdisableMaxIter() { dag2BN_.disableMaxIter(); }
983
984 INLINE void IBNLearner::EMenableMaxIter() { dag2BN_.enableMaxIter(); }
985
986 INLINE bool IBNLearner::EMisEnabledMaxIter() const { return dag2BN_.isEnabledMaxIter(); }
987
988 INLINE void IBNLearner::EMsetMaxTime(double timeout) { dag2BN_.setMaxTime(timeout); }
989
990 INLINE double IBNLearner::EMMaxTime() const { return dag2BN_.maxTime(); }
991
992 INLINE double IBNLearner::EMCurrentTime() const { return dag2BN_.currentTime(); }
993
994 INLINE void IBNLearner::EMdisableMaxTime() { dag2BN_.disableMaxTime(); }
995
996 INLINE void IBNLearner::EMenableMaxTime() { dag2BN_.enableMaxTime(); }
997
998 INLINE bool IBNLearner::EMisEnabledMaxTime() const { return dag2BN_.isEnabledMaxTime(); }
999
1000 INLINE void IBNLearner::EMsetPeriodSize(Size p) { dag2BN_.setPeriodSize(p); }
1001
1002 INLINE Size IBNLearner::EMPeriodSize() const { return dag2BN_.periodSize(); }
1003
1004 INLINE void IBNLearner::EMsetVerbosity(bool v) { dag2BN_.setVerbosity(v); }
1005
1006 INLINE bool IBNLearner::EMVerbosity() const { return dag2BN_.verbosity(); }
1007
1010 return dag2BN_.stateApproximationScheme();
1011 }
1012
1013 INLINE Size IBNLearner::EMnbrIterations() const { return dag2BN_.nbrIterations(); }
1014
1015 INLINE const std::vector< double >& IBNLearner::EMHistory() const { return dag2BN_.history(); }
1016
1017 /* namespace learning */
1018} // namespace gum::learning
A class for generic framework of learning algorithms that can easily be used.
The base class for all directed edges.
Base class for dag.
Definition DAG.h:121
const EdgeSet & edges() const
returns the set of edges stored within the EdgeGraphPart
The base class for all undirected edges.
Exception : fatal (unknown ?) error.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Signaler< Size, double, double > onProgress
Progression, error and time.
ApproximationSchemeSTATE
The different state of an approximation scheme.
Signaler< std::string_view > onStop
Criteria messageApproximationScheme.
Error: A name of variable is not found in the database.
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
Exception : out of bound.
void setNumberOfThreads(Size nb) override
sets the number max of threads to be used by the class containing this ThreadNumberManager
Base class for undirected graphs.
Definition undiGraph.h:130
the class used to read a row in the database and to transform it into a set of DBRow instances that c...
The class representing a tabular database as used by learning tasks.
A class for parameterizing EM's parameter learning approximations.
const std::vector< std::string > & missingSymbols() const
returns the set of missing symbols taken into account
const DatabaseTable & databaseTable() const
returns the internal database table
std::size_t size() const
returns the number of records in the database
std::vector< std::size_t > _domain_sizes_
the domain sizes of the variables (useful to speed-up computations)
Definition IBNLearner.h:280
DatabaseTable _database_
the database itself
Definition IBNLearner.h:274
const std::string & nameFromId(NodeId id) const
returns the variable name corresponding to a given node id
double weight(const std::size_t i) const
returns the weight of the ith record
Bijection< NodeId, std::size_t > _nodeId2cols_
a bijection assigning to each variable name its NodeId
Definition IBNLearner.h:283
const std::vector< std::string > & names() const
returns the names of the variables in the database
void setWeight(const std::size_t i, const double weight)
sets the weight of the ith record
const Bijection< NodeId, std::size_t > & nodeId2Columns() const
returns the mapping between node ids and their columns in the database
DBRowGeneratorParser & parser()
returns the parser for the database
DBRowGeneratorParser * _parser_
the parser used for reading the database
Definition IBNLearner.h:277
NodeId idFromName(std::string_view var_name) const
returns the node id corresponding to a variable name
void setDatabaseWeight(const double new_weight)
assign a weight to all the rows of the database so that the sum of their weights is equal to new_weig...
std::size_t nbRows() const
returns the number of records in the database
const std::vector< std::size_t > & domainSizes() const
returns the domain sizes of the variables
double weight() const
returns the weight of the whole database
void usePC()
indicate that we wish to use PC (Chi2 test by default)
StructuralConstraintPossibleEdges constraintPossibleEdges_
the constraint on possible Edges
StructuralConstraintNoParentNodes constraintNoParentNodes_
the constraint on no parent nodes
Size periodSize() const override
how many samples between 2 stopping isEnableds
void eraseNoChildrenNode(NodeId node)
double recordWeight(const std::size_t i) const
returns the weight of the ith record
BNLearnerPriorType priorType_
the a priorselected for the score and parameters
void EMenableEpsilon()
Enable the log-likelihood min diff stopping criterion in EM.
bool EMisEnabledEpsilon() const
return true if EM's stopping criterion is the log-likelihood min diff
void EMsetPeriodSize(Size p)
how many samples between 2 stoppings isEnabled
const std::vector< std::size_t > & domainSizes() const
returns the domain sizes of the variables in the database
Size nbrIterations() const override
void setMinEpsilonRate(double rate) override
Given that we approximate f(t), stopping criterion on d/dt(|f(t+1)-f(t)|) If the criterion was disabl...
void useGreedyHillClimbing()
indicate that we wish to use a greedy hill climbing algorithm
void useScoreBDeu()
indicate that we wish to use a BDeu score
void addNoParentNode(NodeId node)
Size EMnbrIterations() const
returns the number of iterations performed by the last EM execution
void enableMaxTime() override
stopping criterion on timeout If the criterion was disabled it will be enabled
void setSliceOrder(const NodeProperty< NodeId > &slice_order)
sets a partial order on the nodes
bool isUsingEM() const
indicates whether we use EM for parameter learning
bool isScoreBased() const
indicate if the selected algorithm is score-based
void setForbiddenArcs(const ArcSet &set)
removes a total
std::string priorDbname_
the filename for the Dirichlet a priori, if any
double priorWeight_
the weight of the prior
void enableEpsilon() override
Enable stopping criterion on epsilon.
double maxTime() const override
returns the timeout (in seconds)
double noiseEM_
the noise factor (in (0,1)) used by EM for perturbing the CPT during init
std::vector< std::pair< std::size_t, std::size_t > > ranges_
the set of rows' ranges within the database in which learning is done
void setDatabaseWeight(const double new_weight)
assign a weight to all the rows of the learning database so that the sum of their weights is equal to...
std::vector< Arc > latentVariables() const
get the list of arcs hiding latent variables
void useFCIChi2Test()
indicate that we wish to use Chi2 independence test for FCI
void clearDatabaseRanges()
reset the ranges to the one range corresponding to the whole database
std::string checkScorePriorCompatibility() const
checks whether the current score and prior are compatible
void useBDeuPrior(double weight=1.0)
use the BDeu prior
void setMandatoryArcs(const ArcSet &set)
assign a set of mandatory arcs
bool greedyThickThinningReversals() const
returns whether arc reversals are allowed in the thin phase of greedy thick-thinning
ApproximationSchemeSTATE EMState() const
returns the state of the last EM algorithm executed
void distributeStop(const ApproximationScheme *approximationScheme, std::string_view message)
distribute signals
bool allowArcTriangleDeletions_
whether we allow or not arc deletions during learning
void EMdisableMinEpsilonRate()
Disable the log-likelihood evolution rate stopping criterion.
void useExtendedGreedyHillClimbing()
indicate that we wish to use the extended greedy hill climbing algorithm
double EMMaxTime() const
@brief returns EM's timeout (in milliseconds)
void setFCIMaxPathLength(Size max_len)
set maximum discriminating-path length for FCI R4 (default Size(-1) = unlimited)
ApproximationSchemeSTATE EMStateApproximationScheme() const
get the current state of EM
const std::string & nameFromId(NodeId id) const
returns the variable name corresponding to a given node id
double databaseWeight() const
returns the weight of the whole database
const std::vector< double > & history() const override
void setMaxIter(Size max) override
stopping criterion on number of iterationsIf the criterion was disabled it will be enabled
K2 algoK2_
the K2 algorithm
IndepTestType indepTestTypeFCI_
independence test type for FCI (reuses IndepTestType defined above)
void addMandatoryArc(const Arc &arc)
AlgoType selectedAlgo_
the selected learning algorithm
const std::vector< std::pair< std::size_t, std::size_t > > & databaseRanges() const
returns the current database rows' ranges used for learning
void EMenableMaxIter()
Enable stopping criterion on max iterations.
void useFCI()
indicate that we wish to use FCI (Chi2 test by default)
void enableMinEpsilonRate() override
Enable stopping criterion on epsilon rate.
bool allowArcAdditions_
whether we allow or not arc additions during learning
void useFCIG2Test()
indicate that we wish to use G2 independence test for FCI
void setEpsilon(double eps) override
Given that we approximate f(t), stopping criterion on |f(t+1)-f(t)| If the criterion was disabled it ...
void setMaxIndegree(Size max_indegree)
sets the max indegree
void EMdisableEpsilon()
Disable the min log-likelihood diff stopping criterion for EM.
void addPossibleEdge(const Edge &edge)
bool isEnabledMaxIter() const override
void EMsetMaxIter(Size max)
add a max iteration stopping criterion
void useChi2Test()
indicate that we wish to use Chi2 independence test for PC
void setInitialDAG(const DAG &)
sets an initial DAG structure
void useK2(const Sequence< NodeId > &order)
indicate that we wish to use K2
Database scoreDatabase_
the database to be used by the scores and parameter estimators
void allowArcDeletions(bool allow=true)
allow (true)/forbid (false) to delete arcs during learning.
void setMaxTime(double timeout) override
stopping criterion on timeout If the criterion was disabled it will be enabled
double epsilon() const override
Get the value of epsilon.
double EMEpsilon() const
Get the value of EM's min diff epsilon.
bool useEM_
a Boolean indicating whether we should use EM for parameter learning or not
DAG2BNLearner dag2BN_
the parametric EM
void EMsetMinEpsilonRate(double rate)
sets the stopping criterion of EM as being the minimal log-likelihood's evolution rate
bool isEnabledMaxTime() const override
double EMMinEpsilonRate() const
Get the value of the minimal log-likelihood evolution rate of EM.
void distributeProgress(const ApproximationScheme *approximationScheme, Size pourcent, double error, double time)
{@ /// distribute signals
void setGreedyThickThinningReversals(bool allow)
enable or disable arc reversals in the thin phase of greedy thick-thinning
void setPeriodSize(Size p) override
how many samples between 2 stopping isEnableds
Size EMMaxIter() const
return the max number of iterations criterion
void disableMinEpsilonRate() override
Disable stopping criterion on epsilon rate.
void EMdisableMaxIter()
Disable stopping criterion on max iterations.
BNLearnerPriorType
an enumeration to select the prior
Definition IBNLearner.h:114
bool isEnabledMinEpsilonRate() const override
void erasePossibleEdge(const Edge &edge)
void setNumberOfThreads(Size nb) override
sets the number max of threads that can be used
void useScoreBIC()
indicate that we wish to use a BIC score
void allowArcTriangleDeletions(bool allow=true)
allow (true)/forbid (false) to delete arc triangles during learning.
const std::vector< double > & EMHistory() const
returns the history of the last EM execution
StructuralConstraintNoChildrenNodes constraintNoChildrenNodes_
the constraint on no children nodes
DAG initialDAG()
returns the initial DAG structure
void EMsetVerbosity(bool v)
sets or unsets EM's verbosity
void setPossibleEdges(const EdgeSet &set)
assign a set of possible edges
Size maxIter() const override
void useNoPrior()
use no prior
ScoreType scoreType_
the score selected for learning
bool EMVerbosity() const
returns the EM's verbosity status
const ApproximationScheme * currentAlgorithm_
void eraseForbiddenArc(const Arc &arc)
void useSmoothingPrior(double weight=1)
use the prior smoothing
bool isEnabledEpsilon() const override
PriorType getPriorType_() const
returns the type (as a string) of a given prior
void allowArcAdditions(bool allow=true)
allow (true)/forbid (false) to add arcs during learning.
double alphaFci_
FCI parameters.
void useLocalSearchWithTabuList(Size tabu_size=100, Size nb_decrease=2)
indicate that we wish to use a local search with tabu list
void useScoreK2()
indicate that we wish to use a K2 score
double alphaPc_
PC parameters.
StructuralConstraintIndegree constraintIndegree_
the constraint for indegrees
bool allowArcDeletions_
whether we allow or not arc deletions during learning
void _setPriorWeight_(double weight)
sets the prior weight
bool verbosity() const override
verbosity
void useGreedyThickThinning()
indicate that we wish to use greedy thick-thinning
void disableMaxTime() override
Disable stopping criterion on timeout.
double currentTime() const override
get the current running time in second (double)
void disableEpsilon() override
Disable stopping criterion on epsilon.
void disableMaxIter() override
Disable stopping criterion on max iterations.
void useG2Test()
indicate that we wish to use G2 independence test for PC
void setPossibleSkeleton(const UndiGraph &skeleton)
assign a set of possible edges
void useEMWithRateCriterion(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters with the rate stopping criterion
void useNMLCorrection()
indicate that we wish to use the NML correction for and MIIC
void useEM(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters
void useEMWithDiffCriterion(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters with the diff stopping criterion
bool hasMissingValues() const
returns true if the learner's database has missing values
void forbidEM()
prevent using the EM algorithm for parameter learning
NodeId idFromName(std::string_view var_name) const
returns the node id corresponding to a variable name
Score * score_
the score used
void setPCMaxCondSetSize(Size max_k)
set maximum conditioning set size for PC (default Size(-1) = unlimited)
StructuralConstraintMandatoryArcs constraintMandatoryArcs_
the constraint on mandatory arcs
Miic algoMiic_
the Constraint MIIC algorithm
void unsetSliceOrder()
removes the slice order constraint
void EMenableMaxTime()
sets the stopping criterion of EM as being the minimal difference between two consecutive log-likelih...
EMApproximationScheme & EM()
returns the EM parameter learning approximation scheme if EM is enabled
IndepTestType indepTestTypePC_
void useNoCorrection()
indicate that we wish to use the NoCorr correction for MIIC
StructuralConstraintForbiddenArcs constraintForbiddenArcs_
the constraint on forbidden arcs
StructuralConstraintTotalOrder constraintTotalOrder_
the total order ing constraint
void useScoreLog2Likelihood()
indicate that we wish to use a Log2Likelihood score
void setRecordWeight(const std::size_t i, const double weight)
sets the weight of the ith record of the database
void useDirichletPrior(std::string_view filename, double weight=1)
use the Dirichlet prior from a database
void unsetTotalOrder()
removes the current total ordering constraint, if any
GreedyHillClimbing greedyHillClimbing_
the greedy hill climbing algorithm
void useMDLCorrection()
indicate that we wish to use the MDL correction for MIIC
void setFCIAlpha(double alpha)
set the significance threshold alpha for FCI (default 0.05)
bool fciExhaustiveSepSet() const
return true when FCI uses exhaustive sepset mode
void setPCAlpha(double alpha)
set the significance threshold alpha for PC (default 0.05)
void setVerbosity(bool v) override
verbosity
StructuralConstraintTabuList constraintTabuList_
the constraint for tabu lists
void addForbiddenArc(const Arc &arc)
DAG initialDag_
an initial DAG given to learners
void addNoChildrenNode(NodeId node)
GreedyThickThinning greedyThickThinning_
the greedy thick-thinning algorithm
void EMsetMaxTime(double timeout)
add a stopping criterion on timeout
ApproximationSchemeSTATE stateApproximationScheme() const override
history
void EMenableMinEpsilonRate()
Enable the log-likelihood evolution rate stopping criterion.
void useScoreMDL()
indicate that we wish to use a MDL score
void setFCIExhaustiveSepSet(bool exhaustive)
enable exhaustive sepset mode for FCI skeleton learning (default false)
Size domainSize(NodeId var) const
learn a structure from a file (must have read the db before)
void useScorefNML()
indicate that we wish to use a fNML score
void setTotalOrder(const Sequence< NodeId > &order)
sets a total order over some nodes
void useScoreAIC()
indicate that we wish to use an AIC score
bool allowArcReversals_
whether we allow or not arc reversals during learning
const std::vector< std::string > & names() const
returns the names of the variables in the database
Size EMPeriodSize() const
sets the stopping criterion of EM as being the minimal difference between two consecutive log-likelih...
void eraseMandatoryArc(const Arc &arc)
double EMCurrentTime() const
get the current running time in second (double)
void allowArcReversals(bool allow=true)
allow (true)/forbid (false) to reverse arcs during learning.
void useMIIC()
indicate that we wish to use MIIC
LocalSearchWithTabuList localSearchWithTabuList_
the local search with tabu list algorithm
void setCurrentApproximationScheme(const ApproximationScheme *approximationScheme)
{@ /// distribute signals
StructuralConstraintSliceOrder constraintSliceOrder_
the constraint for 2TBNs
const DatabaseTable & database() const
returns the database used by the BNLearner
bool EMisEnabledMinEpsilonRate() const
void EMdisableMaxTime()
Disable EM's timeout stopping criterion.
void eraseNoParentNode(NodeId node)
void setPCUnshieldedColliderSorted(bool sorted)
set unshielded-collider ordering for PC: sorted=true uses descending p-value order (strongest evidenc...
void EMsetEpsilon(double eps)
sets the stopping criterion of EM as being the minimal difference between two consecutive log-likelih...
void enableMaxIter() override
Enable stopping criterion on max iterations.
void setPCStable(bool stable)
set stable mode for PC — defer removals to end of each depth level (default true)
CorrectedMutualInformation::KModeTypes kmodeMiic_
the penalty used in MIIC
double minEpsilonRate() const override
Get the value of the minimal epsilon rate.
void useScoreBD()
indicate that we wish to use a BD score
bool isConstraintBased() const
indicate if the selected algorithm is constraint-based
std::string EMStateMessage() const
returns the state of the EM algorithm
the structural constraint imposing a partial order over nodes
the structural constraint imposing a total order over some nodes
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Set< Edge > EdgeSet
Some typdefs and define for shortcuts ...
Size NodeId
Type for node ids.
Set< Arc > ArcSet
Some typdefs and define for shortcuts ...
HashTable< NodeId, VAL > NodeProperty
Property on graph elements.
include the inlined functions if necessary
Definition CSVParser.h:55
#define GUM_EMIT1(signal, arg1)
Definition signaler.h:289
#define GUM_EMIT3(signal, arg1, arg2, arg3)
Definition signaler.h:291
Base classes for undirected graphs.