aGrUM 3.2.0
a C++ library for (probabilistic) graphical models
gum::learning::KTBNAdaptiveLearner< GUM_SCALAR > Class Template Reference

Learns a k-TBN (order k + structure + parameters) from trajectory CSVs. More...

#include <agrum/KTBN/learning/KTBNAdaptiveLearner.h>

Inheritance diagram for gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >:
[legend]
Collaboration diagram for gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >:
[legend]

Public Member Functions

Constructors / Destructors
 KTBNAdaptiveLearner (std::string_view dirPath, std::string_view csvBaseName, Size nbSamples, Size kMax, const std::unordered_set< std::string > &atemporalVars, const std::vector< std::string > &missingSymbols={"?"}, bool induceTypes=true)
 Constructor — the candidate orders are kMin..kMax.
 KTBNAdaptiveLearner (std::string_view dirPath, std::string_view csvBaseName, Size nbSamples, Size kMax, const std::vector< std::string > &missingSymbols={"?"}, bool induceTypes=true)
 Structure-learning constructor — atemporal variables inferred from the CSVs.
 KTBNAdaptiveLearner (std::string_view dirPath, std::string_view csvBaseName, Size nbSamples, Size kMax, const BayesNet< GUM_SCALAR > &bn, const std::unordered_set< std::string > &atemporalVars={}, const std::vector< std::string > &missingSymbols={"?"})
 Variable-schema constructor — types and domains supplied via a BN.
 ~KTBNAdaptiveLearner ()
 Constructor — the candidate orders are kMin..kMax.
Main learning methods
KTBN< GUM_SCALAR > learnKTBN () override
 Learns the best k in [kMin, kMax] together with the structure and the CPTs: one KTBNLearner is built and run per candidate k, the recorded configuration is replayed on each, and the k-TBN with the best model-selection score is returned. kMin starts at 2 and is raised by the structural-constraint setters (see class doc).
Size bestK () const
 Order k selected by the last learnKTBN() call.
const std::vector< std::pair< Size, double > > & scorePerCandidateK () const
 Per-candidate cross-k scores from the last learnKTBN() call, as (k, score) pairs for k = kMin..kMax in ascending k order — the values the order selection compared to choose bestK() (higher is better; the argmax is bestK()). Under the default useOrderScoreBIC() each score is \(\log_2 L - \tfrac{1}{2}\,d\,\log_2 N\) of the k-TBN learned for that k.
const std::vector< std::pair< std::string, std::string > > & latentVariables () const
 Engine-name (tail, head) pairs of arcs the selected model's MIIC run flagged as hiding a latent variable. Empty when the recorded algorithm is not MIIC (only MIIC produces latent-variable annotations) or when none were found.
Missing values
KTBNAdaptiveLearner< GUM_SCALAR > & ignoreMissingSymbols (bool ignore=true)
 Learn and score on the fully observed data only, dropping every row and every scoring instance that carries a missing symbol.
bool isIgnoringMissingSymbols () const
 Whether incomplete rows and instances are dropped. False by default.
Diagnostics
Size kMax () const
 Largest order explored (the kMax argument of the constructor).
std::string checkScorePriorCompatibility () const
 Warning string if the recorded score and prior are incompatible, empty otherwise. Data-free: it evaluates the recorded (score, prior) pair exactly as KTBNLearner/BNLearner would, so an incompatible combination can be caught before learnKTBN() reads any trajectory.
std::string toString () const
 Human-readable summary of the recorded configuration (candidate order range, algorithm / score / correction / prior, structural constraints) plus the selected k once learnKTBN() has run.
std::vector< std::tuple< std::string, std::string, std::string > > state () const
 The recorded configuration as (key, value, comment) tuples (mirrors KTBNLearner::state()); toString() is a formatted view of it.
Score selection (recorded, replayed on each candidate k)
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreAIC () override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreBD () override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreBDeu () override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreBIC () override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreLog2Likelihood () override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreMDL () override
void useScorefNML () override
Algorithm selection (recorded, replayed on each candidate k)
KTBNAdaptiveLearner< GUM_SCALAR > & useGreedyHillClimbing () override
KTBNAdaptiveLearner< GUM_SCALAR > & useExtendedGreedyHillClimbing () override
KTBNAdaptiveLearner< GUM_SCALAR > & useLocalSearchWithTabuList (Size tabu_size=100, Size nb_decrease=2) override
KTBNAdaptiveLearner< GUM_SCALAR > & useMIIC () override
MIIC correction (recorded, replayed on each candidate k)
KTBNAdaptiveLearner< GUM_SCALAR > & useNMLCorrection () override
KTBNAdaptiveLearner< GUM_SCALAR > & useMDLCorrection () override
KTBNAdaptiveLearner< GUM_SCALAR > & useNoCorrection () override
Prior selection (recorded, replayed on each candidate k)
KTBNAdaptiveLearner< GUM_SCALAR > & useSmoothingPrior (double weight=1.0) override
Structural constraints (recorded, replayed on each candidate k)
KTBNAdaptiveLearner< GUM_SCALAR > & addForbiddenArc (std::string_view tailNode, std::string_view headNode) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addForbiddenArc (std::string_view tailBase, int tailSlice, std::string_view headBase, int headSlice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseForbiddenArc (std::string_view tailNode, std::string_view headNode) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseForbiddenArc (std::string_view tailBase, int tailSlice, std::string_view headBase, int headSlice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addMandatoryArc (std::string_view tailNode, std::string_view headNode) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addMandatoryArc (std::string_view tailBase, int tailSlice, std::string_view headBase, int headSlice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseMandatoryArc (std::string_view tailNode, std::string_view headNode) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseMandatoryArc (std::string_view tailBase, int tailSlice, std::string_view headBase, int headSlice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addForbiddenKernelArc (std::string_view tailBase, int lag, std::string_view headBase)
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseForbiddenKernelArc (std::string_view tailBase, int lag, std::string_view headBase)
 Undo a previous addForbiddenKernelArc (same (tailBase, lag, headBase) triple).
KTBNAdaptiveLearner< GUM_SCALAR > & addMandatoryKernelArc (std::string_view tailBase, int lag, std::string_view headBase)
 Force an arc from tailBase, lag slices before the kernel, to headBase in the kernel. See addForbiddenKernelArc for the (base, slice) vs. kernel-relative distinction; the validity constraints (lag range, temporal bases, kMin effect) are the same. Always temporally feasible by construction (lag >= 0 guarantees headSlice = k-1 >= k-1-lag = tailSlice), so unlike the plain addMandatoryArc there is no separate feasibility check to run.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseMandatoryKernelArc (std::string_view tailBase, int lag, std::string_view headBase)
 Undo a previous addMandatoryKernelArc (same (tailBase, lag, headBase) triple).
KTBNAdaptiveLearner< GUM_SCALAR > & addForbiddenIntraSliceArc (std::string_view tailBase, std::string_view headBase) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseForbiddenIntraSliceArc (std::string_view tailBase, std::string_view headBase) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addForbiddenArcAllSlices (std::string_view tailBase, std::string_view headBase) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseForbiddenArcAllSlices (std::string_view tailBase, std::string_view headBase) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addNoParentNode (std::string_view base, int slice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addNoParentNode (std::string_view name) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseNoParentNode (std::string_view base, int slice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseNoParentNode (std::string_view name) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addNoChildrenNode (std::string_view base, int slice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addNoChildrenNode (std::string_view name) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseNoChildrenNode (std::string_view base, int slice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & eraseNoChildrenNode (std::string_view name) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addPossibleEdge (std::string_view tailBase, int tailSlice, std::string_view headBase, int headSlice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & addPossibleEdge (std::string_view tail, std::string_view head) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & erasePossibleEdge (std::string_view tailBase, int tailSlice, std::string_view headBase, int headSlice) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & erasePossibleEdge (std::string_view tail, std::string_view head) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & allowArcAdditions (bool allow=true) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & allowArcDeletions (bool allow=true) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & allowArcReversals (bool allow=true) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.
KTBNAdaptiveLearner< GUM_SCALAR > & setMaxIndegree (Size max_indegree) override
 Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Private Member Functions

const std::unordered_set< std::string > & _atemporalVarNames_ () const override
 atemporal base names for IKTBNLearner's shared encode/_determineNode_; the set recorded at construction.
bool _isKnownBase_ (std::string_view base) const override
 whether base is one of this learner's variables; the base names read at construction, from the CSV header or the schema BN.
void _verifyBase_ (std::string_view base, int slice) const
 Throw InvalidArgument unless base is a known base variable and slice is valid for it: base must be in baseNames; an atemporal base requires slice == KTBN::ATEMPORAL, a temporal one requires slice in [0, kMax). Used by the constraint setters to reject unknown names / out-of-range slices eagerly.
void _verifyKernelArc_ (std::string_view tailBase, std::string_view headBase, int lag) const
 Throw InvalidArgument unless tailBase and headBase are known, temporal base variables (a kernel-relative arc has no meaning for an atemporal one: it has no kernel-slice instance) and lag is in [0, kMax) — so some candidate k in [2,kMax] can place tailBase at slice k-1-lag >= 0 and headBase at the kernel slice k-1. Used by the four kernel-arc setters (add/eraseForbiddenKernelArc, add/eraseMandatoryKernelArc) to reject bad calls eagerly.
void _raiseKMinForSlice_ (int slice)
 Raise kMin, if needed, so that kMin > slice: a smaller candidate would silently drop a constraint naming that slice (the "slice < k" rule applyConstraints's fits() filter uses). O(1), since adding a constraint can only push kMin up. No-op for KTBN::ATEMPORAL.
void _recomputeKMin_ ()
 Recompute kMin from scratch: max(2, 1 + the largest concrete slice named by any recorded forbidden/mandatory arc, possible edge, or no-parent/no-children node (the kinds fits() can drop). Intra-slice / all-slices constraints carry no slice and are excluded. Unlike raiseKMinForSlice, an erase can lower kMin with no O(1) way to tell, so every erase* setter runs this full rescan instead.
void _applyConfig_ (KTBNLearner< GUM_SCALAR > &learner) const
 Apply the recorded score / algorithm / correction / prior onto a freshly-built learner. Only knobs that differ from their default are touched, and only those the chosen algorithm actually consumes (a score-based algo takes a score; MIIC takes a correction) — so an unconfigured learner is left at its defaults and no irrelevant setting can trip checkScorePriorCompatibility().
void _applyConstraints_ (KTBNLearner< GUM_SCALAR > &learner, Size k) const
 Replay the recorded structural constraints onto learner (built for order k). Engine-name constraints whose slice does not fit k (slice >= k) are skipped for this candidate; the base-only intra-slice / all-slices constraints are handed to learner, which expands them for its own k. The allow-* flags and max-indegree are applied when non-default.
template<typename PerInstance, typename PerNodeFinal>
void _forEachScoredNode_ (const KTBN< GUM_SCALAR > &net, PerInstance perInstance, PerNodeFinal perNodeFinal) const
 Stream every scored template-node instance of net over the recorded trajectories, driving both the likelihood and the fNML penalty off one data walk, so the width-k window logic lives in one place.
double _log2Likelihood_ (const KTBN< GUM_SCALAR > &net) const
 Factorized log2-likelihood of net over the recorded trajectories, comparable across candidate k (the raw score types are not: their flattened tables differ from one k to another). The data is complete, so this is a closed-form sum of CPT lookups — no inference. A thin reduction over forEachScoredNode that sums log2 of the CPT entry over every visited node instance.
double _countParameters_ (const KTBN< GUM_SCALAR > &net) const
 Number of free parameters of net's template: summed over every template node (all initial slices, the kernel slice and the atemporal nodes), \((|X|-1)\prod_{P\in pa(X)}|P|\). This is the model-complexity term of the cross-k BIC and AIC scores used by learnKTBN(): it grows with \(k\) (a higher order adds initial-slice CPTs and can widen the kernel), which is what offsets the monotonic likelihood gain and prevents always picking the largest \(k\).
double _fNMLScore_ (const KTBN< GUM_SCALAR > &net) const
 fNML order score of net over the recorded trajectories: \(\log_2 L - \sum_i \sum_j \log_2 C^{r_i}_{N_{ij}}\), with \(r_i\) the node's domain size and \(N_{ij}\) the count for parent configuration \(j\). Unlike BIC/AIC the penalty is data-dependent, so the regret needs the same per-instance walk as the likelihood — both are accumulated in one forEachScoredNode pass. Mirrors aGrUM's ScorefNML.
double _orderSelectionScore_ (const KTBN< GUM_SCALAR > &net, double logN) const
 The cross-k order-selection score of net under the recorded orderScore criterion, given logN = log2 of the sample size. The single dispatch point learnKTBN() uses to compare candidates; add a branch here for each new OrderScoreType.
 KTBNAdaptiveLearner (const KTBNAdaptiveLearner< GUM_SCALAR > &)=delete
 KTBNAdaptiveLearner (KTBNAdaptiveLearner< GUM_SCALAR > &&)=delete
KTBNAdaptiveLearner< GUM_SCALAR > & operator= (const KTBNAdaptiveLearner< GUM_SCALAR > &)=delete
KTBNAdaptiveLearner< GUM_SCALAR > & operator= (KTBNAdaptiveLearner< GUM_SCALAR > &&)=delete

Static Private Member Functions

static std::unordered_set< std::string > _inferAtemporalVars_ (std::string_view dirPath, std::string_view csvBaseName, Size nbSamples, Size kMax, const std::vector< std::string > &missingSymbols)
 checks kMax >= 2 and nbSamples >= 1, then delegates to the shared IKTBNLearner::scanConstantColumns(). Called from the atemporal-inferring constructor's member-initialiser list, before this object exists, so the checks live here rather than in the body — otherwise a bad argument would only surface after a wasted scan.

Private Attributes

std::string _dirPath_
 directory holding the trajectory CSV files
std::string _csvBaseName_
 stem of each trajectory file name
Size _nbSamples_
 number of CSV files to read
Size _kMax_
 largest order to explore (candidates are kMin..kMax)
Size _kMin_ {2}
 smallest order worth exploring (candidates are kMin..kMax). Starts at 2 and is recomputed by recomputeKMin() from the recorded slice-bearing constraints every time one is added or erased; never set directly. See recomputeKMin() for why it must be a recompute rather than an incremental raise/lower.
std::unordered_set< std::string > _atemporalVars_
 base names of the atemporal (static) variables
std::unordered_set< std::string > _baseNames_
 all base variable names (temporal + atemporal), read from the first trajectory CSV header at construction. Authoritative universe used by the constraint setters to reject names that do not exist.
std::vector< std::string > _missingSymbols_
 symbols in the CSVs to interpret as missing values
bool _ignoreMissingSymbols_ {false}
 whether incomplete rows/instances are dropped (see ignoreMissingSymbols())
bool _induceTypes_
 whether numeric columns are retyped (see KTBNLearner); unused (and forced false) when a schema BN is supplied
std::unique_ptr< BayesNet< GUM_SCALAR > > _prior_bn_
 optional variable-schema BN (set by the BN constructor): when present, each per-k KTBNLearner is built from it so the variable domains are fixed explicitly instead of inferred from trajectory 1. Null in CSV mode.
IBNLearner::ScoreType _score_ {IBNLearner::ScoreType::BDeu}
 recorded per-k structure score (the inner score, replayed on each candidate)
OrderScoreType _orderScore_ {OrderScoreType::BIC}
 recorded cross-k order-selection criterion (the outer score used by learnKTBN() to pick the best k; independent of score)
IBNLearner::AlgoType _algo_ {IBNLearner::AlgoType::MIIC}
 recorded structure-learning algorithm
Size _tabuSize_ {100}
 tabu-list parameters (meaningful when algo is LOCAL_SEARCH_WITH_TABU_LIST)
Size _nbDecrease_ {2}
CorrectedMutualInformation::KModeTypes _correction_
 recorded MIIC correction
IBNLearner::BNLearnerPriorType _prior_ {IBNLearner::BNLearnerPriorType::NO_prior}
 recorded prior and its weight
double _priorWeight_ {1.0}
bool _allowAdditions_ {true}
 recorded graph-change permissions / indegree cap
bool _allowDeletions_ {true}
bool _allowReversals_ {true}
Size _maxIndegree_ {std::numeric_limits< Size >::max()}
std::set< std::pair< std::string, std::string > > _forbiddenArcs_
 forbidden arcs, as (tail, head) engine-name pairs
std::set< std::pair< std::string, std::string > > _mandatoryArcs_
 mandatory arcs, as (tail, head) engine-name pairs
std::set< std::pair< std::string, std::string > > _possibleEdges_
 MIIC candidate edges, as (tail, head) engine-name pairs.
std::set< std::pair< std::string, std::string > > _forbiddenIntraSliceArcs_
 forbidden intra-slice arcs, as (tailBase, headBase) pairs
std::set< std::pair< std::string, std::string > > _forbiddenArcsAllSlices_
 forbidden all-slices arcs, as (tailBase, headBase) pairs
std::set< std::tuple< std::string, std::string, int > > _forbiddenKernelArcs_
 forbidden kernel-relative arcs, as (tailBase, headBase, lag) triples: tailBase at slice k-1-lag -> headBase at the kernel slice k-1. Kept separate from forbiddenArcs (which stores resolved engine names) since the slice here is only known once a candidate k is fixed.
std::set< std::tuple< std::string, std::string, int > > _mandatoryKernelArcs_
 mandatory kernel-relative arcs, same shape as forbiddenKernelArcs
std::set< std::string > _noParentNodes_
 root nodes (no parents), as engine names
std::set< std::string > _noChildrenNodes_
 leaf nodes (no children), as engine names
Size _bestK_ {0}
 k selected by the last learnKTBN() call, or 0 as a sentinel while no learning has happened yet. 0 can never be a valid order (candidates are 2..kMax), so bestK() reads it to decide whether learnKTBN() has run.
std::vector< std::pair< std::string, std::string > > _bestLatentVariables_
 latent-variable arcs (engine-name pairs) reported by the winning candidate's MIIC run, captured by learnKTBN(); empty when the selected algorithm is not MIIC. Exposed by latentVariables().
std::vector< std::pair< Size, double > > _scorePerCandidateK_
 per-candidate (k, order-score) pairs from the last learnKTBN() run, in ascending k. One entry appended per candidate; read by scorePerCandidateK(). Cleared at the start of each learnKTBN() (empty while bestK == 0).
VariableLog2ParamComplexity _ctable_
 cache of log2 of the multinomial parametric complexity C^r_n, used by the fNML order penalty. Mutable because log2Cnr() memoizes; the const order-score helpers may therefore call it. Only touched under fNML.

Order selection (cross-k model selection)

enum class  OrderScoreType { BIC , AIC , fNML }
 The criterion learnKTBN() uses to pick the best \(k\) among the candidates — the outer score, distinct from the per-k structure score set by useScoreX(). Only criteria that are comparable across \(k\) belong here (raw score types are not). Extended as more are added. More...
log_2 C {r_i}_{N_{ij}}@f$
 Select k by fNML (factorized Normalized Maximum Likelihood): keep the k whose learned model maximises .
KTBNAdaptiveLearner< GUM_SCALAR > & useOrderScoreBIC ()
 Select k by BIC (the default): keep the k whose learned model maximises \(\log_2 L - \tfrac{1}{2}\,d\,\log_2 N\).
KTBNAdaptiveLearner< GUM_SCALAR > & useOrderScoreAIC ()
 Select k by AIC: keep the k whose learned model maximises \(\log_2 L - d\) (a lighter, sample-size-independent complexity penalty than BIC).
log_2 where the penalty replaces BIC s KTBNAdaptiveLearner< GUM_SCALAR > & useOrderScorefNML ()
 \(\tfrac{1}{2}\,d\,\log_2 N\) by a sum of per-node, per-parent-configuration multinomial parametric complexities (regret) – data-dependent, unlike BIC/AIC, matching aGrUM's ScorefNML.

Name encoding: (base, slice) <-> engine name

std::string _encode_ (std::string_view base, int slice) const
 (base, slice) -> engine name ("A[1]" / atemporal engine name). Pure function, shared by every learner.
std::pair< std::string, int > _determineNode_ (const std::string &name) const
 engine name -> (base, slice); atemporal names map to KTBN::ATEMPORAL. Shared by every learner; only the atemporal test varies (via atemporalVarNames()).
void _checkArcTemporallyFeasible_ (std::string_view tail, std::string_view head, std::string_view action) const
 Reject an arc the k-TBN definition can never contain, so eraseForbiddenArc and addMandatoryArc both fail early (before any internal learner is touched) with a uniform message. action is the verb phrase completing "cannot <action> <tail> -> <head>: ..." (e.g. "force the mandatory arc", "un-forbid the arc"). Two arcs are refused: a temporal -> atemporal arc (a time-varying variable can never parent a static one) and a backward-in-time arc (head strictly before tail).
void _checkBaseIsTemporal_ (std::string_view base, std::string_view context) const
 Throw InvalidArgument unless base is a known temporal base. context completes "cannot appear in <context>" (e.g. "an intra-slice constraint", "a kernel-relative arc"): every caller rejects an atemporal base for the same underlying reason – it has no per-slice instance – so they share the sentence and vary the setting.
static void _checkMinimalOrder_ (Size order, std::string_view label)
 Throw InvalidArgument unless order is at least 2, label naming the offending parameter ("k" for the fixed-k learner, "kMax" for the adaptive one).
static std::unordered_set< std::string > _scanConstantColumns_ (std::string_view dirPath, std::string_view csvBaseName, Size nbSamples, const std::vector< std::string > &missingSymbols)
 Scans every trajectory and returns the base names classified atemporal: those whose value never changes across the rows of a single trajectory (checked independently per trajectory, so the value may still differ between trajectories). Shared by every atemporal-inferring CSV constructor (KTBNLearner, KTBNAdaptiveLearner): identical scanning logic regardless of which subclass calls it, so duplicating it per subclass would only invite the two copies to drift. Callers are responsible for validating their own arguments (e.g. k/kMax >= 2) before calling this — it does no such check itself, only opens files, so a bad argument would otherwise only be caught after a wasted scan.

Detailed Description

template<GUM_Numeric GUM_SCALAR>
class gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >

Learns a k-TBN (order k + structure + parameters) from trajectory CSVs.

See also
gum::learning::IKTBNLearner for the configuration interface, gum::learning::KTBNLearner for the fixed-k learner this class builds and drives once per candidate k.

Definition at line 104 of file KTBNAdaptiveLearner.h.

Member Enumeration Documentation

◆ OrderScoreType

template<GUM_Numeric GUM_SCALAR>
enum class gum::learning::KTBNAdaptiveLearner::OrderScoreType
strong

The criterion learnKTBN() uses to pick the best \(k\) among the candidates — the outer score, distinct from the per-k structure score set by useScoreX(). Only criteria that are comparable across \(k\) belong here (raw score types are not). Extended as more are added.

Enumerator
BIC 
AIC 
fNML 

Definition at line 266 of file KTBNAdaptiveLearner.h.

266{ BIC, AIC, fNML };

Constructor & Destructor Documentation

◆ KTBNAdaptiveLearner() [1/5]

template<GUM_Numeric GUM_SCALAR>
gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::KTBNAdaptiveLearner ( std::string_view dirPath,
std::string_view csvBaseName,
Size nbSamples,
Size kMax,
const std::unordered_set< std::string > & atemporalVars,
const std::vector< std::string > & missingSymbols = {"?"},
bool induceTypes = true )

Constructor — the candidate orders are kMin..kMax.

Mirrors the CSV constructor of gum::learning::KTBNLearner, except that no single order k is given: the learner explores every \(k \in [k_{min}, kMax]\) at learn time. \(k_{min}\) starts at 2 (k = 1 is a static BN; use BNLearner) and is raised by the structural-constraint setters — see the class doc.

Parameters
dirPathDirectory holding the trajectory CSV files.
csvBaseNameStem of each file name (1-based index and .csv appended, e.g. "traj" -> "traj1.csv", "traj2.csv", ...).
nbSamplesNumber of CSV files to read.
kMaxLargest order to explore. Must be \(\geq 2\).
atemporalVarsBase names of the atemporal (static) variables. Pass an empty set for "every variable is temporal"; it has no default, since omitting it selects the inferring overload below.
missingSymbolsSymbols in the CSVs to interpret as missing values.
induceTypesWhen true (default), columns whose values are all numeric are retyped (integer/range/continuous) instead of being treated as plain labels — same semantics as KTBNLearner.
Warning
A braced literal is ambiguous between this overload and the inferring one, since it could equally initialize either's fifth parameter. Name the type — std::unordered_set<std::string>{"C","D"} — or pass a named variable.

Definition at line 78 of file KTBNAdaptiveLearner_tpl.h.

85 :
88 // cheap argument checks first, so bad calls fail before touching the disk
90 if (nbSamples < 1) GUM_ERROR(InvalidArgument, "KTBNAdaptiveLearner requires nbSamples >= 1")
91
92 // Load the base-variable names (the CSV columns) so the constraint setters can
93 // reject unknown names eagerly. Only the header row is needed, so we parse a
94 // single line instead of loading and typing the whole file. The column order
95 // matches what every per-k KTBNLearner reads from the same header at
96 // learnKTBN() time.
100 if (!is.is_open()) GUM_ERROR(IOError, "Cannot open " << firstCSV.string())
101
102 CSVParser parser(is, firstCSV.string());
103 if (!parser.next())
104 GUM_ERROR(IOError, "Empty trajectory file (no header row): " << firstCSV.string())
105 const std::vector< std::string >& header = parser.current();
107
108 // every declared atemporal variable must actually be one of those columns
109 for (const std::string& aname: _atemporalVars_)
112 "atemporal variable '" << aname << "' not found in the CSV header")
113
115 }
static void _checkMinimalOrder_(Size order, std::string_view label)
Throw InvalidArgument unless order is at least 2, label naming the offending parameter ("k" for the f...
Learns a k-TBN (order k + structure + parameters) from trajectory CSVs.
bool _induceTypes_
whether numeric columns are retyped (see KTBNLearner); unused (and forced false) when a schema BN is ...
std::vector< std::string > _missingSymbols_
symbols in the CSVs to interpret as missing values
std::unordered_set< std::string > _atemporalVars_
base names of the atemporal (static) variables
std::string _dirPath_
directory holding the trajectory CSV files
Size _kMax_
largest order to explore (candidates are kMin..kMax)
Size kMax() const
Largest order explored (the kMax argument of the constructor).
KTBNAdaptiveLearner(std::string_view dirPath, std::string_view csvBaseName, Size nbSamples, Size kMax, const std::unordered_set< std::string > &atemporalVars, const std::vector< std::string > &missingSymbols={"?"}, bool induceTypes=true)
Constructor — the candidate orders are kMin..kMax.
Size _nbSamples_
number of CSV files to read
std::unordered_set< std::string > _baseNames_
all base variable names (temporal + atemporal), read from the first trajectory CSV header at construc...
std::string _csvBaseName_
stem of each trajectory file name

References KTBNAdaptiveLearner(), _atemporalVars_, _baseNames_, gum::learning::IKTBNLearner< GUM_SCALAR >::_checkMinimalOrder_(), _csvBaseName_, _dirPath_, _induceTypes_, _kMax_, _missingSymbols_, _nbSamples_, gum::learning::CSVParser::current(), GUM_ERROR, kMax(), and gum::learning::CSVParser::next().

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), ~KTBNAdaptiveLearner(), operator=(), operator=(), useGreedyHillClimbing(), useMDLCorrection(), useMIIC(), useNMLCorrection(), useNoCorrection(), useOrderScoreAIC(), useOrderScoreBIC(), useOrderScorefNML(), useScoreAIC(), useScoreBD(), useScoreBDeu(), useScoreBIC(), useScoreLog2Likelihood(), and useScoreMDL().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ KTBNAdaptiveLearner() [2/5]

template<GUM_Numeric GUM_SCALAR>
gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::KTBNAdaptiveLearner ( std::string_view dirPath,
std::string_view csvBaseName,
Size nbSamples,
Size kMax,
const std::vector< std::string > & missingSymbols = {"?"},
bool induceTypes = true )

Structure-learning constructor — atemporal variables inferred from the CSVs.

Same as the explicit-atemporalVars constructor, except a base variable is classified atemporal iff its value never changes within a single trajectory (it may still differ between trajectories, e.g. a per-individual covariate such as age). A column with too few non-missing values to ever witness a change is classified atemporal optimistically.

This is a heuristic: a genuinely temporal variable that happens to hold one value throughout every sampled trajectory (short horizon, near-deterministic process) will be misclassified. Prefer the explicit-atemporalVars constructor when the classification is already known.

Warning
Domains are still discovered from trajectory 1 alone. An inferred atemporal variable, by construction, may vary between trajectories — exactly the case most likely to reveal only one of several modalities in trajectory 1 and later throw UnknownLabelInDatabase at learnKTBN() time. Use the BN-schema constructor if the full domain isn't guaranteed present in trajectory 1.
Unlike every other constructor, this one is not fully lazy: it keeps opening trajectories until every column has been falsified as a constancy candidate, so a missing/malformed file is usually (not always — an early-falsifying column set can stop the scan first) caught here rather than at learnKTBN().
Parameters
dirPathDirectory holding the trajectory CSV files.
csvBaseNameStem of each file name (1-based index and .csv appended, e.g. "traj" -> "traj1.csv", "traj2.csv", ...).
nbSamplesNumber of CSV files to read.
kMaxLargest order to explore. Must be \(\geq 2\).
missingSymbolsSymbols in the CSVs to interpret as missing values.
induceTypesWhen true (default), columns whose values are all numeric are retyped (integer/range/continuous) instead of being treated as plain labels.

Definition at line 118 of file KTBNAdaptiveLearner_tpl.h.

124 :
125 // _inferAtemporalVars_ checks kMax>=2 and nbSamples>=1 itself, before
126 // opening anything (see its declaration) — this initialiser-list call
127 // runs before the delegated-to constructor's own body, so those checks
128 // cannot be left to that body the way the explicit constructor does.
129 // Delegates to the explicit-atemporalVars constructor for the rest
130 // (header read); _inferAtemporalVars_ needs nbSamples, unlike the
131 // header-only read above, since one trajectory alone cannot show that a
132 // value stays constant.
134 dirPath,
136 nbSamples,
137 kMax,
140 induceTypes) {}
static std::unordered_set< std::string > _inferAtemporalVars_(std::string_view dirPath, std::string_view csvBaseName, Size nbSamples, Size kMax, const std::vector< std::string > &missingSymbols)
checks kMax >= 2 and nbSamples >= 1, then delegates to the shared IKTBNLearner::scanConstantColumns()...

References KTBNAdaptiveLearner(), _inferAtemporalVars_(), and kMax().

Here is the call graph for this function:

◆ KTBNAdaptiveLearner() [3/5]

template<GUM_Numeric GUM_SCALAR>
gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::KTBNAdaptiveLearner ( std::string_view dirPath,
std::string_view csvBaseName,
Size nbSamples,
Size kMax,
const BayesNet< GUM_SCALAR > & bn,
const std::unordered_set< std::string > & atemporalVars = {},
const std::vector< std::string > & missingSymbols = {"?"} )

Variable-schema constructor — types and domains supplied via a BN.

The adaptive counterpart of gum::learning::KTBNLearner's BN constructor. Use it when a variable's full domain is not guaranteed to appear in the first trajectory — most notably atemporal variables, which are constant within a trajectory and so only ever reveal one value per file, and the CSV constructor would then infer an incomplete domain and later throw gum::UnknownLabelInDatabase. Each per-k KTBNLearner is built from bn so every variable's type and domain is fixed up front; induceTypes and the trajectory-1 domain inference are bypassed entirely.

Parameters
dirPathDirectory holding the trajectory CSV files.
csvBaseNameStem of each file name (index and .csv appended).
nbSamplesNumber of CSV files to read.
kMaxLargest order to explore. Must be \(\geq 2\).
bnA BayesNet with one node per base variable providing the variable types and domains. Arcs in bn are ignored.
atemporalVarsBase names of the atemporal (static) variables present in bn.
missingSymbolsSymbols in the CSVs to interpret as missing values.

Definition at line 158 of file KTBNAdaptiveLearner_tpl.h.

165 :
170 if (nbSamples < 1) GUM_ERROR(InvalidArgument, "KTBNAdaptiveLearner requires nbSamples >= 1")
171
172 // the schema BN is the authoritative variable universe here (not the CSV
173 // header): take the base names from it, so the constraint setters validate
174 // against the same variables every per-k KTBNLearner will use. The CSV is
175 // read only later, at learnKTBN() time.
178
179 // every declared atemporal variable must be a node of the schema BN
180 for (const std::string& aname: _atemporalVars_)
183 "atemporal variable '" << aname << "' not found in the schema BN")
184
186 }
std::unique_ptr< BayesNet< GUM_SCALAR > > _prior_bn_
optional variable-schema BN (set by the BN constructor): when present, each per-k KTBNLearner is buil...

References KTBNAdaptiveLearner(), _atemporalVars_, _baseNames_, gum::learning::IKTBNLearner< GUM_SCALAR >::_checkMinimalOrder_(), _csvBaseName_, _dirPath_, _induceTypes_, _kMax_, _missingSymbols_, _nbSamples_, _prior_bn_, GUM_ERROR, and kMax().

Here is the call graph for this function:

◆ ~KTBNAdaptiveLearner()

template<GUM_Numeric GUM_SCALAR>
gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::~KTBNAdaptiveLearner ( )

Constructor — the candidate orders are kMin..kMax.

Mirrors the CSV constructor of gum::learning::KTBNLearner, except that no single order k is given: the learner explores every \(k \in [k_{min}, kMax]\) at learn time. \(k_{min}\) starts at 2 (k = 1 is a static BN; use BNLearner) and is raised by the structural-constraint setters — see the class doc.

Parameters
dirPathDirectory holding the trajectory CSV files.
csvBaseNameStem of each file name (1-based index and .csv appended, e.g. "traj" -> "traj1.csv", "traj2.csv", ...).
nbSamplesNumber of CSV files to read.
kMaxLargest order to explore. Must be \(\geq 2\).
atemporalVarsBase names of the atemporal (static) variables. Pass an empty set for "every variable is temporal"; it has no default, since omitting it selects the inferring overload below.
missingSymbolsSymbols in the CSVs to interpret as missing values.
induceTypesWhen true (default), columns whose values are all numeric are retyped (integer/range/continuous) instead of being treated as plain labels — same semantics as KTBNLearner.
Warning
A braced literal is ambiguous between this overload and the inferring one, since it could equally initialize either's fifth parameter. Name the type — std::unordered_set<std::string>{"C","D"} — or pass a named variable.

Definition at line 189 of file KTBNAdaptiveLearner_tpl.h.

References KTBNAdaptiveLearner().

Here is the call graph for this function:

◆ KTBNAdaptiveLearner() [4/5]

template<GUM_Numeric GUM_SCALAR>
gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::KTBNAdaptiveLearner ( const KTBNAdaptiveLearner< GUM_SCALAR > & )
privatedelete

References KTBNAdaptiveLearner().

Here is the call graph for this function:

◆ KTBNAdaptiveLearner() [5/5]

template<GUM_Numeric GUM_SCALAR>
gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::KTBNAdaptiveLearner ( KTBNAdaptiveLearner< GUM_SCALAR > && )
privatedelete

References KTBNAdaptiveLearner().

Here is the call graph for this function:

Member Function Documentation

◆ _applyConfig_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_applyConfig_ ( KTBNLearner< GUM_SCALAR > & learner) const
private

Apply the recorded score / algorithm / correction / prior onto a freshly-built learner. Only knobs that differ from their default are touched, and only those the chosen algorithm actually consumes (a score-based algo takes a score; MIIC takes a correction) — so an unconfigured learner is left at its defaults and no irrelevant setting can trip checkScorePriorCompatibility().

Definition at line 1151 of file KTBNAdaptiveLearner_tpl.h.

1151 {
1152 // A fresh KTBNLearner already starts at the mirrored defaults (MIIC / BDeu /
1153 // MDL / NO_prior), so we only touch a knob when it differs from its default,
1154 // and only the knobs the chosen algorithm actually consumes.
1155 bool scoreBased = false;
1156 switch (_algo_) {
1158 // MIIC is the default algo — nothing to set on a fresh learner. It uses a
1159 // correction (not a score); apply it only when it is not the default MDL.
1160 switch (_correction_) {
1163 case CorrectedMutualInformation::KModeTypes::MDL : break; // default
1164 }
1165 break;
1168 scoreBased = true;
1169 break;
1172 scoreBased = true;
1173 break;
1176 scoreBased = true;
1177 break;
1178 default : break; // K2 / PC are never recorded by our setters
1179 }
1180
1181 // score-based algos consume a score; apply it only when it is not the default BDeu
1183 switch (_score_) {
1190 default : break; // BDeu (guarded out) and K2 (never recorded)
1191 }
1192 }
1193
1194 // the prior feeds parameter estimation whatever the algorithm, so it is applied
1195 // independently of the score/correction split, again only when non-default
1198 }
KTBNAdaptiveLearner< GUM_SCALAR > & useNMLCorrection() override
IBNLearner::BNLearnerPriorType _prior_
recorded prior and its weight
KTBNAdaptiveLearner< GUM_SCALAR > & useGreedyHillClimbing() override
IBNLearner::AlgoType _algo_
recorded structure-learning algorithm
KTBNAdaptiveLearner< GUM_SCALAR > & useSmoothingPrior(double weight=1.0) override
IBNLearner::ScoreType _score_
recorded per-k structure score (the inner score, replayed on each candidate)
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreMDL() override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreAIC() override
KTBNAdaptiveLearner< GUM_SCALAR > & useExtendedGreedyHillClimbing() override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreLog2Likelihood() override
Size _tabuSize_
tabu-list parameters (meaningful when algo is LOCAL_SEARCH_WITH_TABU_LIST)
KTBNAdaptiveLearner< GUM_SCALAR > & useLocalSearchWithTabuList(Size tabu_size=100, Size nb_decrease=2) override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreBD() override
KTBNAdaptiveLearner< GUM_SCALAR > & useScoreBIC() override
CorrectedMutualInformation::KModeTypes _correction_
recorded MIIC correction
KTBNAdaptiveLearner< GUM_SCALAR > & useNoCorrection() override

References _algo_, _correction_, _nbDecrease_, _prior_, _priorWeight_, _score_, _tabuSize_, gum::learning::IBNLearner::AIC, gum::learning::IBNLearner::BD, gum::learning::IBNLearner::BDeu, gum::learning::IBNLearner::BIC, gum::learning::IBNLearner::EXTENDED_GREEDY_HILL_CLIMBING, gum::learning::IBNLearner::fNML, gum::learning::IBNLearner::GREEDY_HILL_CLIMBING, gum::learning::IBNLearner::LOCAL_SEARCH_WITH_TABU_LIST, gum::learning::IBNLearner::LOG2LIKELIHOOD, gum::learning::CorrectedMutualInformation::MDL, gum::learning::IBNLearner::MDL, gum::learning::IBNLearner::MIIC, gum::learning::CorrectedMutualInformation::NML, gum::learning::IBNLearner::NO_prior, gum::learning::CorrectedMutualInformation::NoCorr, gum::learning::KTBNLearner< GUM_SCALAR >::useExtendedGreedyHillClimbing(), gum::learning::KTBNLearner< GUM_SCALAR >::useGreedyHillClimbing(), gum::learning::KTBNLearner< GUM_SCALAR >::useLocalSearchWithTabuList(), gum::learning::KTBNLearner< GUM_SCALAR >::useNMLCorrection(), gum::learning::KTBNLearner< GUM_SCALAR >::useNoCorrection(), gum::learning::KTBNLearner< GUM_SCALAR >::useScoreAIC(), gum::learning::KTBNLearner< GUM_SCALAR >::useScoreBD(), gum::learning::KTBNLearner< GUM_SCALAR >::useScoreBIC(), gum::learning::KTBNLearner< GUM_SCALAR >::useScorefNML(), gum::learning::KTBNLearner< GUM_SCALAR >::useScoreLog2Likelihood(), gum::learning::KTBNLearner< GUM_SCALAR >::useScoreMDL(), and gum::learning::KTBNLearner< GUM_SCALAR >::useSmoothingPrior().

Referenced by learnKTBN().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _applyConstraints_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_applyConstraints_ ( KTBNLearner< GUM_SCALAR > & learner,
Size k ) const
private

Replay the recorded structural constraints onto learner (built for order k). Engine-name constraints whose slice does not fit k (slice >= k) are skipped for this candidate; the base-only intra-slice / all-slices constraints are handed to learner, which expands them for its own k. The allow-* flags and max-indegree are applied when non-default.

Definition at line 1201 of file KTBNAdaptiveLearner_tpl.h.

1202 {
1203 const int ik = static_cast< int >(k);
1204 // an engine-name endpoint fits candidate k iff its slice is < k (ATEMPORAL == -1
1205 // always fits); a constraint touching a slice this candidate does not have is
1206 // skipped for this k only.
1207 auto fits = [&](const std::string& node) { return _determineNode_(node).second < ik; };
1208
1209 for (const auto& [tail, head]: _forbiddenArcs_)
1211 for (const auto& [tail, head]: _mandatoryArcs_)
1213 for (const auto& [tail, head]: _possibleEdges_)
1215 for (const auto& node: _noParentNodes_)
1217 for (const auto& node: _noChildrenNodes_)
1219
1220 // kernel-relative arcs: resolve the lag against this candidate's kernel
1221 // slice (k-1) into an explicit (base, slice) arc. Always fits once k >=
1222 // _kMin_ (guaranteed by _raiseKMinForSlice_/_recomputeKMin_ above), but the
1223 // guard mirrors fits()'s defensive style above rather than assuming it.
1224 for (const auto& [tailBase, headBase, lag]: _forbiddenKernelArcs_) {
1225 const int tailSlice = ik - 1 - lag;
1227 }
1228 for (const auto& [tailBase, headBase, lag]: _mandatoryKernelArcs_) {
1229 const int tailSlice = ik - 1 - lag;
1231 }
1232
1233 // base-only constraints: hand them to the fixed-k learner, which expands them
1234 // over its own slices (no manual expansion / no slice filtering needed here).
1235 for (const auto& [tailBase, headBase]: _forbiddenIntraSliceArcs_)
1237 for (const auto& [tailBase, headBase]: _forbiddenArcsAllSlices_)
1239
1240 // structural-search knobs, applied only when the user changed them from default
1245 }
std::pair< std::string, int > _determineNode_(const std::string &name) const
engine name -> (base, slice); atemporal names map to KTBN::ATEMPORAL. Shared by every learner; only t...
KTBNAdaptiveLearner< GUM_SCALAR > & addForbiddenArcAllSlices(std::string_view tailBase, std::string_view headBase) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
std::set< std::string > _noParentNodes_
root nodes (no parents), as engine names
KTBNAdaptiveLearner< GUM_SCALAR > & allowArcAdditions(bool allow=true) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
bool _allowAdditions_
recorded graph-change permissions / indegree cap
KTBNAdaptiveLearner< GUM_SCALAR > & addMandatoryArc(std::string_view tailNode, std::string_view headNode) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
std::set< std::string > _noChildrenNodes_
leaf nodes (no children), as engine names
KTBNAdaptiveLearner< GUM_SCALAR > & allowArcDeletions(bool allow=true) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
KTBNAdaptiveLearner< GUM_SCALAR > & addNoChildrenNode(std::string_view base, int slice) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
KTBNAdaptiveLearner< GUM_SCALAR > & addPossibleEdge(std::string_view tailBase, int tailSlice, std::string_view headBase, int headSlice) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
std::set< std::pair< std::string, std::string > > _forbiddenArcsAllSlices_
forbidden all-slices arcs, as (tailBase, headBase) pairs
KTBNAdaptiveLearner< GUM_SCALAR > & addForbiddenIntraSliceArc(std::string_view tailBase, std::string_view headBase) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
std::set< std::pair< std::string, std::string > > _mandatoryArcs_
mandatory arcs, as (tail, head) engine-name pairs
std::set< std::pair< std::string, std::string > > _possibleEdges_
MIIC candidate edges, as (tail, head) engine-name pairs.
std::set< std::pair< std::string, std::string > > _forbiddenArcs_
forbidden arcs, as (tail, head) engine-name pairs
std::set< std::pair< std::string, std::string > > _forbiddenIntraSliceArcs_
forbidden intra-slice arcs, as (tailBase, headBase) pairs
KTBNAdaptiveLearner< GUM_SCALAR > & addForbiddenArc(std::string_view tailNode, std::string_view headNode) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
std::set< std::tuple< std::string, std::string, int > > _mandatoryKernelArcs_
mandatory kernel-relative arcs, same shape as forbiddenKernelArcs
KTBNAdaptiveLearner< GUM_SCALAR > & allowArcReversals(bool allow=true) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
KTBNAdaptiveLearner< GUM_SCALAR > & setMaxIndegree(Size max_indegree) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
KTBNAdaptiveLearner< GUM_SCALAR > & addNoParentNode(std::string_view base, int slice) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...
std::set< std::tuple< std::string, std::string, int > > _forbiddenKernelArcs_
forbidden kernel-relative arcs, as (tailBase, headBase, lag) triples: tailBase at slice k-1-lag -> he...

References _allowAdditions_, _allowDeletions_, _allowReversals_, gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _forbiddenArcs_, _forbiddenArcsAllSlices_, _forbiddenIntraSliceArcs_, _forbiddenKernelArcs_, _mandatoryArcs_, _mandatoryKernelArcs_, _maxIndegree_, _noChildrenNodes_, _noParentNodes_, _possibleEdges_, gum::learning::KTBNLearner< GUM_SCALAR >::addForbiddenArc(), gum::learning::KTBNLearner< GUM_SCALAR >::addForbiddenArcAllSlices(), gum::learning::KTBNLearner< GUM_SCALAR >::addForbiddenIntraSliceArc(), gum::learning::KTBNLearner< GUM_SCALAR >::addMandatoryArc(), gum::learning::KTBNLearner< GUM_SCALAR >::addNoChildrenNode(), gum::learning::KTBNLearner< GUM_SCALAR >::addNoParentNode(), gum::learning::KTBNLearner< GUM_SCALAR >::addPossibleEdge(), gum::learning::KTBNLearner< GUM_SCALAR >::allowArcAdditions(), gum::learning::KTBNLearner< GUM_SCALAR >::allowArcDeletions(), gum::learning::KTBNLearner< GUM_SCALAR >::allowArcReversals(), and gum::learning::KTBNLearner< GUM_SCALAR >::setMaxIndegree().

Referenced by learnKTBN().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _atemporalVarNames_()

template<GUM_Numeric GUM_SCALAR>
const std::unordered_set< std::string > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_atemporalVarNames_ ( ) const
overrideprivatevirtual

atemporal base names for IKTBNLearner's shared encode/_determineNode_; the set recorded at construction.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 1040 of file KTBNAdaptiveLearner_tpl.h.

1040 {
1041 return _atemporalVars_;
1042 }

References _atemporalVars_.

◆ _checkArcTemporallyFeasible_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::IKTBNLearner< GUM_SCALAR >::_checkArcTemporallyFeasible_ ( std::string_view tail,
std::string_view head,
std::string_view action ) const
protectedinherited

Reject an arc the k-TBN definition can never contain, so eraseForbiddenArc and addMandatoryArc both fail early (before any internal learner is touched) with a uniform message. action is the verb phrase completing "cannot <action> <tail> -> <head>: ..." (e.g. "force the mandatory arc", "un-forbid the arc"). Two arcs are refused: a temporal -> atemporal arc (a time-varying variable can never parent a static one) and a backward-in-time arc (head strictly before tail).

Definition at line 95 of file IKTBNLearner_tpl.h.

97 {
102 "cannot " << action << " " << tail << " -> " << head
103 << ": a temporal variable can never be a parent of an atemporal one; "
104 "this constraint is part of the k-TBN definition")
107 "cannot " << action << " " << tail << " -> " << head
108 << ": its head is at an earlier time slice than its tail, which "
109 "violates temporal causality")
110 }
Pure-virtual configuration interface shared by all k-TBN learners.

References _determineNode_(), gum::KTBN< GUM_SCALAR >::ATEMPORAL, and GUM_ERROR.

Referenced by _isKnownBase_(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addMandatoryArc(), gum::learning::KTBNLearner< GUM_SCALAR >::addMandatoryArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenArc(), and gum::learning::KTBNLearner< GUM_SCALAR >::eraseForbiddenArc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _checkBaseIsTemporal_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::IKTBNLearner< GUM_SCALAR >::_checkBaseIsTemporal_ ( std::string_view base,
std::string_view context ) const
protectedinherited

Throw InvalidArgument unless base is a known temporal base. context completes "cannot appear in <context>" (e.g. "an intra-slice constraint", "a kernel-relative arc"): every caller rejects an atemporal base for the same underlying reason – it has no per-slice instance – so they share the sentence and vary the setting.

Definition at line 196 of file IKTBNLearner_tpl.h.

197 {
198 const std::string b{base};
199 if (!_isKnownBase_(b))
201 "unknown base variable '" << base
202 << "': it is not one of this learner's variables")
205 "atemporal variable '" << base << "' cannot appear in " << context
206 << ": it has no per-slice instance")
207 }
virtual bool _isKnownBase_(std::string_view base) const =0
Whether base is one of this learner's variables, temporal or atemporal. The second subclass-specific ...
virtual const std::unordered_set< std::string > & _atemporalVarNames_() const =0
The base names of the atemporal (static) variables. The only subclass-specific input to determineNode...

References _atemporalVarNames_(), _isKnownBase_(), gum::contains(), and GUM_ERROR.

Referenced by _isKnownBase_(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_verifyKernelArc_(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addForbiddenIntraSliceArc(), gum::learning::KTBNLearner< GUM_SCALAR >::addForbiddenIntraSliceArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenIntraSliceArc(), and gum::learning::KTBNLearner< GUM_SCALAR >::eraseForbiddenIntraSliceArc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _checkMinimalOrder_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::IKTBNLearner< GUM_SCALAR >::_checkMinimalOrder_ ( Size order,
std::string_view label )
staticprotectedinherited

Throw InvalidArgument unless order is at least 2, label naming the offending parameter ("k" for the fixed-k learner, "kMax" for the adaptive one).

This is a learner constraint, not a model one – gum::KTBN, gum::KTBNGenerator and gum::KTBNInference all accept k = 1 – which is why it lives here rather than on the model. Static because four of its call sites are themselves static helpers invoked from member-initialiser lists, before any object exists.

Definition at line 210 of file IKTBNLearner_tpl.h.

210 {
211 if (order < 2)
213 "a k-TBN learner requires "
214 << label << " >= 2: k=1 is a static Bayesian network, use BNLearner instead")
215 }

References GUM_ERROR.

Referenced by gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::KTBNAdaptiveLearner(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::KTBNAdaptiveLearner(), gum::learning::KTBNLearner< GUM_SCALAR >::_buildPriorFromBN_(), gum::learning::KTBNLearner< GUM_SCALAR >::_buildPriorFromCSV_(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_inferAtemporalVars_(), gum::learning::KTBNLearner< GUM_SCALAR >::_inferAtemporalVars_(), and _isKnownBase_().

Here is the caller graph for this function:

◆ _countParameters_()

template<GUM_Numeric GUM_SCALAR>
double gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_countParameters_ ( const KTBN< GUM_SCALAR > & net) const
private

Number of free parameters of net's template: summed over every template node (all initial slices, the kernel slice and the atemporal nodes), \((|X|-1)\prod_{P\in pa(X)}|P|\). This is the model-complexity term of the cross-k BIC and AIC scores used by learnKTBN(): it grows with \(k\) (a higher order adds initial-slice CPTs and can widen the kernel), which is what offsets the monotonic likelihood gain and prevents always picking the largest \(k\).

Definition at line 1470 of file KTBNAdaptiveLearner_tpl.h.

1470 {
1471 // Free parameters of the template: for each node, (|node| - 1) independent
1472 // entries per joint parent configuration. Summed over every template node
1473 // (initial slices, kernel slice, atemporal nodes), this is the k-TBN's total
1474 // parameter count — it rises with k, which is what the BIC penalty needs.
1475 double df = 0.0;
1476 for (const auto& [base, slice]: net.nodes()) {
1477 double cell = net.variable(base, slice).domainSize() - 1.0;
1478 for (const auto& [pbase, pslice]: net.parents(base, slice))
1479 cell *= net.variable(pbase, pslice).domainSize();
1480 df += cell;
1481 }
1482 return df;
1483 }

Referenced by _orderSelectionScore_().

Here is the caller graph for this function:

◆ _determineNode_()

template<GUM_Numeric GUM_SCALAR>
std::pair< std::string, int > gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_ ( const std::string & name) const
protectedinherited

engine name -> (base, slice); atemporal names map to KTBN::ATEMPORAL. Shared by every learner; only the atemporal test varies (via atemporalVarNames()).

Definition at line 64 of file IKTBNLearner_tpl.h.

64 {
65 // check atemporal set first: a name registered as atemporal always maps
66 // to ATEMPORAL, even if it syntactically looks like "base[t]"
68
69 // syntactic parse: look for a trailing "[digits]" suffix
70 const std::size_t bracketPos = name.rfind('[');
72
74 name.size() - bracketPos - 1};
75 if (bracketContent.empty() || bracketContent.back() != ']')
77
78 const std::string_view digits = bracketContent.substr(0, bracketContent.size() - 1);
79 if (digits.empty()) return {name, KTBN< GUM_SCALAR >::ATEMPORAL};
80 for (const char c: digits)
81 if (std::isdigit(static_cast< unsigned char >(c)) == 0)
83
84 int slice{};
85 try {
87 } catch (const std::out_of_range&) {
89 "Node name '" << name << "' has a slice index too large to represent as int.")
90 }
91 return {name.substr(0, bracketPos), slice};
92 }

References _atemporalVarNames_(), gum::KTBN< GUM_SCALAR >::ATEMPORAL, gum::contains(), and GUM_ERROR.

Referenced by gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_applyConstraints_(), _checkArcTemporallyFeasible_(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_forEachScoredNode_(), gum::learning::KTBNLearner< GUM_SCALAR >::_forOwningLearner_(), _isKnownBase_(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_recomputeKMin_(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addForbiddenArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addMandatoryArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addNoChildrenNode(), gum::learning::KTBNLearner< GUM_SCALAR >::addNoChildrenNode(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addNoParentNode(), gum::learning::KTBNLearner< GUM_SCALAR >::addNoParentNode(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addPossibleEdge(), gum::learning::KTBNLearner< GUM_SCALAR >::addPossibleEdge(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseMandatoryArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseNoChildrenNode(), gum::learning::KTBNLearner< GUM_SCALAR >::eraseNoChildrenNode(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseNoParentNode(), gum::learning::KTBNLearner< GUM_SCALAR >::eraseNoParentNode(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::erasePossibleEdge(), gum::learning::KTBNLearner< GUM_SCALAR >::erasePossibleEdge(), and gum::learning::KTBNLearner< GUM_SCALAR >::names().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _encode_()

template<GUM_Numeric GUM_SCALAR>
std::string gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_ ( std::string_view base,
int slice ) const
protectedinherited

(base, slice) -> engine name ("A[1]" / atemporal engine name). Pure function, shared by every learner.

Definition at line 57 of file IKTBNLearner_tpl.h.

57 {
59 return std::string{base} + '[' + std::to_string(slice) + ']';
60 }

References gum::KTBN< GUM_SCALAR >::ATEMPORAL.

Referenced by gum::learning::KTBNLearner< GUM_SCALAR >::_assemble_(), gum::learning::KTBNLearner< GUM_SCALAR >::_build_(), _isKnownBase_(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addForbiddenArc(), gum::learning::KTBNLearner< GUM_SCALAR >::addForbiddenArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addMandatoryArc(), gum::learning::KTBNLearner< GUM_SCALAR >::addMandatoryArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addNoChildrenNode(), gum::learning::KTBNLearner< GUM_SCALAR >::addNoChildrenNode(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addNoParentNode(), gum::learning::KTBNLearner< GUM_SCALAR >::addNoParentNode(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addPossibleEdge(), gum::learning::KTBNLearner< GUM_SCALAR >::addPossibleEdge(), gum::learning::KTBNLearner< GUM_SCALAR >::domainSize(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenArc(), gum::learning::KTBNLearner< GUM_SCALAR >::eraseForbiddenArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseMandatoryArc(), gum::learning::KTBNLearner< GUM_SCALAR >::eraseMandatoryArc(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseNoChildrenNode(), gum::learning::KTBNLearner< GUM_SCALAR >::eraseNoChildrenNode(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseNoParentNode(), gum::learning::KTBNLearner< GUM_SCALAR >::eraseNoParentNode(), gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::erasePossibleEdge(), gum::learning::KTBNLearner< GUM_SCALAR >::erasePossibleEdge(), and gum::learning::KTBNLearner< GUM_SCALAR >::learnParameters().

Here is the caller graph for this function:

◆ _fNMLScore_()

template<GUM_Numeric GUM_SCALAR>
double gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_fNMLScore_ ( const KTBN< GUM_SCALAR > & net) const
private

fNML order score of net over the recorded trajectories: \(\log_2 L - \sum_i \sum_j \log_2 C^{r_i}_{N_{ij}}\), with \(r_i\) the node's domain size and \(N_{ij}\) the count for parent configuration \(j\). Unlike BIC/AIC the penalty is data-dependent, so the regret needs the same per-instance walk as the likelihood — both are accumulated in one forEachScoredNode pass. Mirrors aGrUM's ScorefNML.

Definition at line 1444 of file KTBNAdaptiveLearner_tpl.h.

1444 {
1445 // one data walk: per instance, accumulate log2L AND bucket the observation by
1446 // its parent configuration; per node, close over the buckets with the
1447 // multinomial parametric complexity log2Cnr, exactly the per-node regret term
1448 // aGrUM's ScorefNML subtracts. Fused (rather than a separate _log2Likelihood_
1449 // call plus a separate penalty pass) so fNML order-selection reads every
1450 // trajectory once per candidate k, not twice.
1451 double logL = 0.0, penalty = 0.0;
1453 net,
1454 [&logL](auto& e) {
1455 logL += std::log2((*e.cpt)[e.inst]);
1456 // linear index over the parent dims (1..nbrDim-1); the node is dim 0
1457 Size idx = 0;
1458 for (Idx d = 1; d < e.cpt->nbrDim(); ++d)
1459 idx = idx * e.cpt->variable(d).domainSize() + e.inst.val(e.cpt->variable(d));
1460 e.counts[idx] += 1.0;
1461 },
1462 [this, &penalty](auto& e) {
1463 for (const auto& [cfg, n]: e.counts)
1464 penalty += _ctable_.log2Cnr(e.selfDom, n);
1465 });
1466 return logL - penalty;
1467 }
void _forEachScoredNode_(const KTBN< GUM_SCALAR > &net, PerInstance perInstance, PerNodeFinal perNodeFinal) const
Stream every scored template-node instance of net over the recorded trajectories, driving both the li...
VariableLog2ParamComplexity _ctable_
cache of log2 of the multinomial parametric complexity C^r_n, used by the fNML order penalty....

References _ctable_, and _forEachScoredNode_().

Referenced by _orderSelectionScore_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _forEachScoredNode_()

template<GUM_Numeric GUM_SCALAR>
template<typename PerInstance, typename PerNodeFinal>
void gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_forEachScoredNode_ ( const KTBN< GUM_SCALAR > & net,
PerInstance perInstance,
PerNodeFinal perNodeFinal ) const
private

Stream every scored template-node instance of net over the recorded trajectories, driving both the likelihood and the fNML penalty off one data walk, so the width-k window logic lives in one place.

Each trajectory is streamed row by row through a width-k circular buffer (absolute time t at slot t % k): every temporal node X[t] is visited against net's template CPT for slice min(t, k-1), reading each parent from row t - lag; atemporal nodes are visited once per trajectory. perInstance runs once per instance with the observed labels loaded into e.inst; perNodeFinal runs once per template node after the stream, for criteria reducing accumulated per-node state (e.g. fNML's regret).

Definition at line 1253 of file KTBNAdaptiveLearner_tpl.h.

1255 {
1256 namespace fs = std::filesystem;
1257 const int k = static_cast< int >(net.k());
1258
1259 // Precomputed scorer for one template node, reused across every row of
1260 // every trajectory so the inner loop never rebuilds an Instantiation
1261 // (~3.7x the cost of one chgVal) or re-decodes a variable name. selfDom /
1262 // counts carry the accumulator a reduction criterion (fNML) closes over
1263 // in perNodeFinal; likelihood-style reductions ignore them.
1264 struct NodeEval {
1266 Instantiation inst; // slaved to *cpt
1267 std::vector< std::string > dimName; // cpt.variable(d).name()
1268 std::vector< std::pair< std::string, int > > dimNode; // _determineNode_(name)
1269 Size selfDom; // |node| (CPT dim 0 is the node)
1270 std::unordered_map< Size, double > counts; // parent-config index -> #obs
1271 };
1272
1273 auto makeEval = [&](const Tensor< GUM_SCALAR >& cpt) {
1274 NodeEval e;
1275 e.cpt = &cpt;
1276 e.inst = Instantiation(cpt);
1277 e.selfDom = cpt.variable(0).domainSize(); // the node varies fastest (dim 0)
1278 e.dimName.reserve(cpt.nbrDim());
1279 e.dimNode.reserve(cpt.nbrDim());
1280 for (Idx d = 0; d < cpt.nbrDim(); ++d) {
1281 std::string name = cpt.variable(d).name();
1282 e.dimNode.push_back(_determineNode_(name));
1283 e.dimName.push_back(std::move(name));
1284 }
1285 return e;
1286 };
1287
1288 // one evaluator per (temporal base, slice), indexed by slice in 0..k-1: the
1289 // node scored at absolute time t uses slice min(t, k-1) (see childSlice below)
1290 const auto& temporalBases = net.temporalVarNames();
1292 for (int slice = 0; slice < k; ++slice) {
1293 temporalEvals[slice].reserve(temporalBases.size());
1294 for (const auto& base: temporalBases)
1295 temporalEvals[slice].push_back(makeEval(net.cpt(base, slice)));
1296 }
1297
1298 // one evaluator per atemporal node (scored once per trajectory)
1300 atemporalEvals.reserve(net.atemporalVarNames().size());
1301 for (const auto& base: net.atemporalVarNames())
1303
1304 // one circular buffer of k rows, reused across trajectories: the row for
1305 // absolute time t lives at slot (t % k), so the k live rows never move —
1306 // reading a new row overwrites the stalest slot (which held time t-k).
1308
1309 // missing-value markers, as a set for O(1) tests in the inner loop
1311 _missingSymbols_.end());
1312
1313 for (Size s = 0; s < _nbSamples_; ++s) {
1314 const fs::path file = fs::path{_dirPath_} / (_csvBaseName_ + std::to_string(s + 1) + ".csv");
1315
1316 // ---- pre-pass: column index, and the atemporal values of this trajectory ----
1317 // An atemporal variable is constant down the file, but the row that
1318 // happens to carry a missing marker teaches nothing, so its value is the
1319 // first *informative* one rather than row 0's. The scan stops as soon as
1320 // every atemporal column is resolved (row 0 in the usual case), so it
1321 // costs one row unless the data actually has holes. It cannot be folded
1322 // into the main pass: a value resolved at row 12 must already be known
1323 // when row 0 is scored, and buffering the rows instead would defeat the
1324 // width-k window that bounds this function's memory.
1327 {
1329 if (!pis.is_open()) GUM_ERROR(IOError, "Cannot open " << file.string())
1330 CSVParser pre(pis, file.string());
1331 if (!pre.next()) GUM_ERROR(IOError, "empty trajectory file '" << file.string() << "'") {
1332 const auto& header = pre.current();
1333 for (std::size_t c = 0; c < header.size(); ++c)
1334 colOf[header[c]] = c;
1335 }
1336 const std::size_t nbAtemp = net.atemporalVarNames().size();
1337 while (atempVal.size() < nbAtemp && pre.next()) {
1338 const auto& row = pre.current();
1339 for (const auto& c: net.atemporalVarNames()) {
1340 if (atempVal.contains(c)) continue;
1341 const std::string& tok = row[colOf.at(c)];
1342 if (!missing.contains(tok)) atempVal[c] = tok;
1343 }
1344 }
1345 }
1346
1348 if (!is.is_open()) GUM_ERROR(IOError, "Cannot open " << file.string())
1349 CSVParser parser(is, file.string());
1350 parser.next(); // skip the header, already consumed by the pre-pass
1351
1352 // Label observed in the data for one CPT dimension (varBase, varSlice) —
1353 // the scored node itself or one of its parents — while scoring the node
1354 // whose template slice is scoredSlice at absolute time scoredTime.
1355 // Returns nullptr when the value is missing (or, for an atemporal
1356 // variable, never observed in this trajectory); the caller then drops the
1357 // whole instance. A pointer rather than a value: both sources are stable
1358 // strings, and this is the innermost loop of the order selection.
1359 auto labelOf = [&](const std::string& varBase,
1360 int varSlice,
1361 int scoredTime,
1362 int scoredSlice) -> const std::string* {
1363 // atemporal variable: constant down the trajectory, read the captured value
1365 const auto it = atempVal.find(varBase);
1366 return (it == atempVal.end()) ? nullptr : &it->second;
1367 }
1368 // temporal variable: it lags (scoredSlice - varSlice) steps behind the
1369 // scored node, so its value was observed at that earlier absolute time
1370 const int varTime = scoredTime - (scoredSlice - varSlice);
1371 // fetch that row from the circular buffer (slot = time modulo k)
1372 const std::string& tok = window[varTime % k][colOf.at(varBase)];
1373 return missing.contains(tok) ? nullptr : &tok;
1374 };
1375
1376 int t = 0; // absolute time == data-row index
1377 while (parser.next()) {
1378 const auto& cur = parser.current();
1379 window[t % k].assign(cur.begin(), cur.end());
1380
1381 // first k-1 slices use their own initial CPT; from slice k-1 on the
1382 // transition kernel (template slice k-1) is reused for every step
1383 const int childSlice = (t < k - 1) ? t : (k - 1);
1384 for (NodeEval& e: temporalEvals[childSlice]) {
1385 // an instance counts only if its WHOLE family is observed: the node
1386 // and every parent, each read at its own lag. One missing value drops
1387 // this instance alone — the other nodes of the same row are unaffected.
1388 bool complete = true;
1389 for (std::size_t d = 0; d < e.dimName.size(); ++d) {
1390 const auto& [vbase, vslice] = e.dimNode[d];
1391 const std::string* lbl = labelOf(vbase, vslice, t, childSlice);
1392 if (lbl == nullptr) {
1393 complete = false;
1394 break;
1395 }
1396 e.inst.chgVal(e.dimName[d], *lbl);
1397 }
1398 if (complete) perInstance(e);
1399 }
1400 ++t;
1401 }
1402
1403 // atemporal nodes: scored once per trajectory (parents are atemporal too).
1404 // An atemporal column left unresolved by the pre-pass drops every instance
1405 // that reads it, here and in the temporal loop above — for THIS trajectory
1406 // only, the others still scoring normally.
1407 if (t > 0)
1408 for (NodeEval& e: atemporalEvals) {
1409 bool complete = true;
1410 for (std::size_t d = 0; d < e.dimName.size(); ++d) {
1411 const auto it = atempVal.find(e.dimNode[d].first);
1412 if (it == atempVal.end()) {
1413 complete = false;
1414 break;
1415 }
1416 e.inst.chgVal(e.dimName[d], it->second);
1417 }
1418 if (complete) perInstance(e);
1419 }
1420 }
1421
1422 // per-node closing pass over every evaluator (all slices + atemporal), for
1423 // criteria that reduce the accumulated per-node state after the whole walk
1424 for (auto& slice: temporalEvals)
1425 for (NodeEval& e: slice)
1426 perNodeFinal(e);
1427 for (NodeEval& e: atemporalEvals)
1428 perNodeFinal(e);
1429 }
Instantiation()
Default constructor: creates an empty tuple.

References gum::Instantiation::Instantiation(), _csvBaseName_, gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _dirPath_, _missingSymbols_, _nbSamples_, gum::KTBN< GUM_SCALAR >::ATEMPORAL, gum::learning::CSVParser::current(), GUM_ERROR, and gum::learning::CSVParser::next().

Referenced by _fNMLScore_(), and _log2Likelihood_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _inferAtemporalVars_()

template<GUM_Numeric GUM_SCALAR>
std::unordered_set< std::string > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_inferAtemporalVars_ ( std::string_view dirPath,
std::string_view csvBaseName,
Size nbSamples,
Size kMax,
const std::vector< std::string > & missingSymbols )
staticprivate

checks kMax >= 2 and nbSamples >= 1, then delegates to the shared IKTBNLearner::scanConstantColumns(). Called from the atemporal-inferring constructor's member-initialiser list, before this object exists, so the checks live here rather than in the body — otherwise a bad argument would only surface after a wasted scan.

Definition at line 143 of file KTBNAdaptiveLearner_tpl.h.

148 {
150 if (nbSamples < 1) GUM_ERROR(InvalidArgument, "KTBNAdaptiveLearner requires nbSamples >= 1")
153 nbSamples,
155 }
static std::unordered_set< std::string > _scanConstantColumns_(std::string_view dirPath, std::string_view csvBaseName, Size nbSamples, const std::vector< std::string > &missingSymbols)
Scans every trajectory and returns the base names classified atemporal: those whose value never chang...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_checkMinimalOrder_(), gum::learning::IKTBNLearner< GUM_SCALAR >::_scanConstantColumns_(), GUM_ERROR, and kMax().

Referenced by KTBNAdaptiveLearner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _isKnownBase_()

template<GUM_Numeric GUM_SCALAR>
bool gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_isKnownBase_ ( std::string_view base) const
overrideprivatevirtual

whether base is one of this learner's variables; the base names read at construction, from the CSV header or the schema BN.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 1045 of file KTBNAdaptiveLearner_tpl.h.

1045 {
1046 return _baseNames_.contains(std::string{base});
1047 }

References _baseNames_.

◆ _log2Likelihood_()

template<GUM_Numeric GUM_SCALAR>
double gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_log2Likelihood_ ( const KTBN< GUM_SCALAR > & net) const
private

Factorized log2-likelihood of net over the recorded trajectories, comparable across candidate k (the raw score types are not: their flattened tables differ from one k to another). The data is complete, so this is a closed-form sum of CPT lookups — no inference. A thin reduction over forEachScoredNode that sums log2 of the CPT entry over every visited node instance.

Definition at line 1432 of file KTBNAdaptiveLearner_tpl.h.

1432 {
1433 // sum log2 of the CPT entry over every visited node instance; no per-node
1434 // closing reduction is needed (the likelihood is fully additive per instance)
1435 double logL = 0.0;
1437 net,
1438 [&logL](auto& e) { logL += std::log2((*e.cpt)[e.inst]); },
1439 [](auto&) {});
1440 return logL;
1441 }

References _forEachScoredNode_().

Referenced by _orderSelectionScore_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _orderSelectionScore_()

template<GUM_Numeric GUM_SCALAR>
double gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_orderSelectionScore_ ( const KTBN< GUM_SCALAR > & net,
double logN ) const
private

The cross-k order-selection score of net under the recorded orderScore criterion, given logN = log2 of the sample size. The single dispatch point learnKTBN() uses to compare candidates; add a branch here for each new OrderScoreType.

Definition at line 1486 of file KTBNAdaptiveLearner_tpl.h.

1487 {
1488 // BIC/AIC share a log2-likelihood term plus a data-free parameter-count
1489 // penalty, so both read the trajectories once via _log2Likelihood_. fNML
1490 // needs the likelihood too, but paired with a data-dependent per-node regret
1491 // over the very same walk, so it is fused into a single _forEachScoredNode_
1492 // pass (_fNMLScore_) instead of calling _log2Likelihood_ a second time.
1493 switch (_orderScore_) {
1494 case OrderScoreType::BIC :
1495 // reward fit, penalise complexity: log2L − ½·df·log2(N)
1496 return _log2Likelihood_(net) - 0.5 * _countParameters_(net) * logN;
1497 case OrderScoreType::AIC :
1498 // lighter, sample-size-independent penalty: log2L − df
1501 // per-node multinomial parametric complexity (regret): log2L − Σ log2Cnr
1502 return _fNMLScore_(net);
1503 }
1504 // every criterion returns above; unreachable while OrderScoreType is exhausted
1505 return _log2Likelihood_(net) - 0.5 * _countParameters_(net) * logN;
1506 }
double _fNMLScore_(const KTBN< GUM_SCALAR > &net) const
fNML order score of net over the recorded trajectories: , with the node's domain size and the count...
OrderScoreType _orderScore_
recorded cross-k order-selection criterion (the outer score used by learnKTBN() to pick the best k; i...
double _log2Likelihood_(const KTBN< GUM_SCALAR > &net) const
Factorized log2-likelihood of net over the recorded trajectories, comparable across candidate k (the ...
double _countParameters_(const KTBN< GUM_SCALAR > &net) const
Number of free parameters of net's template: summed over every template node (all initial slices,...

References _countParameters_(), _fNMLScore_(), _log2Likelihood_(), _orderScore_, AIC, BIC, and fNML.

Referenced by learnKTBN().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _raiseKMinForSlice_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_raiseKMinForSlice_ ( int slice)
private

Raise kMin, if needed, so that kMin > slice: a smaller candidate would silently drop a constraint naming that slice (the "slice < k" rule applyConstraints's fits() filter uses). O(1), since adding a constraint can only push kMin up. No-op for KTBN::ATEMPORAL.

Definition at line 1106 of file KTBNAdaptiveLearner_tpl.h.

1106 {
1108 _kMin_ = std::max(_kMin_, static_cast< Size >(slice) + 1);
1109 }
Size _kMin_
smallest order worth exploring (candidates are kMin..kMax). Starts at 2 and is recomputed by recomput...

References _kMin_, and gum::KTBN< GUM_SCALAR >::ATEMPORAL.

Referenced by _recomputeKMin_(), addForbiddenArc(), addForbiddenKernelArc(), addMandatoryArc(), addMandatoryKernelArc(), addNoChildrenNode(), addNoParentNode(), and addPossibleEdge().

Here is the caller graph for this function:

◆ _recomputeKMin_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_recomputeKMin_ ( )
private

Recompute kMin from scratch: max(2, 1 + the largest concrete slice named by any recorded forbidden/mandatory arc, possible edge, or no-parent/no-children node (the kinds fits() can drop). Intra-slice / all-slices constraints carry no slice and are excluded. Unlike raiseKMinForSlice, an erase can lower kMin with no O(1) way to tell, so every erase* setter runs this full rescan instead.

Definition at line 1112 of file KTBNAdaptiveLearner_tpl.h.

1112 {
1113 // kMin = 1 + the largest recorded slice (fits()'s "slice < k" rule means a
1114 // smaller k would drop that constraint). An erase can lower kMin, unlike a
1115 // single _raiseKMinForSlice_ call, so this rebuilds from scratch rather
1116 // than adjusting in place.
1117 _kMin_ = 2;
1118 for (const auto& [tail, head]: _forbiddenArcs_) {
1121 }
1122 for (const auto& [tail, head]: _mandatoryArcs_) {
1125 }
1126 for (const auto& [tail, head]: _possibleEdges_) {
1129 }
1130 for (const auto& node: _noParentNodes_)
1132 for (const auto& node: _noChildrenNodes_)
1134 // kernel-relative arcs: the lag itself is what must fit (the head's slice is
1135 // always the kernel k-1, which trivially fits any k), so raise on the lag
1136 // directly rather than decoding an engine name that doesn't exist yet.
1137 for (const auto& t: _forbiddenKernelArcs_)
1139 for (const auto& t: _mandatoryKernelArcs_)
1141 // _forbiddenIntraSliceArcs_ / _forbiddenArcsAllSlices_ carry no slice (they
1142 // are base-name pairs, expanded per-k by the fixed-k learner) and so are
1143 // left out: they never make a candidate drop anything, whatever k is.
1144 }
void _raiseKMinForSlice_(int slice)
Raise kMin, if needed, so that kMin > slice: a smaller candidate would silently drop a constraint nam...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _forbiddenArcs_, _forbiddenKernelArcs_, _kMin_, _mandatoryArcs_, _mandatoryKernelArcs_, _noChildrenNodes_, _noParentNodes_, _possibleEdges_, and _raiseKMinForSlice_().

Referenced by eraseForbiddenArc(), eraseForbiddenKernelArc(), eraseMandatoryArc(), eraseMandatoryKernelArc(), eraseNoChildrenNode(), eraseNoParentNode(), and erasePossibleEdge().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _scanConstantColumns_()

template<GUM_Numeric GUM_SCALAR>
std::unordered_set< std::string > gum::learning::IKTBNLearner< GUM_SCALAR >::_scanConstantColumns_ ( std::string_view dirPath,
std::string_view csvBaseName,
Size nbSamples,
const std::vector< std::string > & missingSymbols )
staticprotectedinherited

Scans every trajectory and returns the base names classified atemporal: those whose value never changes across the rows of a single trajectory (checked independently per trajectory, so the value may still differ between trajectories). Shared by every atemporal-inferring CSV constructor (KTBNLearner, KTBNAdaptiveLearner): identical scanning logic regardless of which subclass calls it, so duplicating it per subclass would only invite the two copies to drift. Callers are responsible for validating their own arguments (e.g. k/kMax >= 2) before calling this — it does no such check itself, only opens files, so a bad argument would otherwise only be caught after a wasted scan.

Column indices still "live" (not yet proven non-constant) are tracked as a shrinking list rather than rescanned from scratch, and scanning stops opening further trajectories once that list is empty — falsification is one-way, so nothing left to test can ever become atemporal again.

Definition at line 113 of file IKTBNLearner_tpl.h.

117 {
118 namespace fs = std::filesystem;
119 const fs::path dir{dirPath};
122
123 std::vector< std::string > header; // captured from trajectory 1
124 std::vector< std::size_t > candidates; // column indices not yet falsified; shrinks only
125 std::vector< std::string > firstSeen; // per column: first non-missing value THIS trajectory
127 haveFirstSeen; // per column: whether firstSeen[c] is set THIS trajectory
128
129 for (Size i = 0; i < nbSamples; ++i) {
130 // once every column has been falsified, nothing left to test can
131 // ever become atemporal again, so remaining trajectories are never
132 // even opened. Not part of the for-condition: `candidates` does not
133 // exist yet before trajectory 1 populates it.
134 if (i > 0 && candidates.empty()) break;
135
136 const fs::path file = dir / (stem + std::to_string(i + 1) + ".csv");
138 if (!is.is_open()) GUM_ERROR(IOError, "Cannot open " << file.string());
139
140 CSVParser parser(is, file.string());
141 parser.next();
142 const auto& raw = parser.current();
143
144 if (i == 0) {
145 header.assign(raw.begin(), raw.end());
146 candidates.resize(header.size());
147 std::iota(candidates.begin(), candidates.end(), std::size_t{0});
148 } else {
149 bool same = (raw.size() == header.size());
150 for (std::size_t c = 0; same && c < header.size(); ++c)
151 same = (raw[c] == header[c]);
152 if (!same)
154 "Header of " << file.string() << " differs from trajectory 1");
155 }
156
157 haveFirstSeen.assign(header.size(), false);
158 firstSeen.assign(header.size(), {});
159
160 while (parser.next()) {
161 const auto& tokens = parser.current();
162 if (tokens.size() != header.size())
164 "Trajectory " << (i + 1) << ", row " << parser.nbLine() << ": expected "
165 << header.size() << " columns, got " << tokens.size());
166 // iterate only the still-live candidates, swap-erasing any just
167 // falsified so later rows (and later trajectories) never revisit it
168 for (std::size_t idx = 0; idx < candidates.size();) {
169 const std::size_t c = candidates[idx];
170 if (missing.contains(tokens[c])) {
171 ++idx; // uninformative row for this column, still a candidate
172 continue;
173 }
174 if (!haveFirstSeen[c]) {
175 firstSeen[c] = tokens[c];
176 haveFirstSeen[c] = true;
177 ++idx;
178 } else if (tokens[c] != firstSeen[c]) {
179 candidates[idx] = candidates.back(); // falsified: drop, O(1)
180 candidates.pop_back();
181 } else {
182 ++idx;
183 }
184 }
185 if (candidates.empty()) break; // nothing left to test in this file either
186 }
187 }
188
190 for (const std::size_t c: candidates)
191 atemporalVars.insert(header[c]);
192 return atemporalVars;
193 }

References gum::learning::CSVParser::current(), GUM_ERROR, gum::learning::CSVParser::nbLine(), and gum::learning::CSVParser::next().

Referenced by gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_inferAtemporalVars_(), gum::learning::KTBNLearner< GUM_SCALAR >::_inferAtemporalVars_(), and _isKnownBase_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _verifyBase_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_verifyBase_ ( std::string_view base,
int slice ) const
private

Throw InvalidArgument unless base is a known base variable and slice is valid for it: base must be in baseNames; an atemporal base requires slice == KTBN::ATEMPORAL, a temporal one requires slice in [0, kMax). Used by the constraint setters to reject unknown names / out-of-range slices eagerly.

Definition at line 1054 of file KTBNAdaptiveLearner_tpl.h.

1054 {
1055 if (!_baseNames_.contains(std::string{base}))
1057 "unknown base variable '" << base << "': it is not one of the data columns")
1058 // an atemporal variable's only valid slice is ATEMPORAL; reject eagerly
1059 // rather than recording e.g. "C[1]" and failing later at learnKTBN() time
1060 if (_atemporalVars_.contains(std::string{base})) {
1063 "atemporal variable '" << base << "' cannot be given a time slice (got " << slice
1064 << "): use KTBN::ATEMPORAL")
1065 return;
1066 }
1067 // temporal: valid slices are [0, kMax). A negative value other than
1068 // ATEMPORAL must be caught here -- _encode_ would turn it into "X[-5]",
1069 // which reads back as atemporal and slips past the slice-fit rule.
1070 if (slice != KTBN< GUM_SCALAR >::ATEMPORAL && slice < 0)
1072 "negative time slice " << slice << " for '" << base
1073 << "': slices start at 0 (use KTBN::ATEMPORAL to address an "
1074 "atemporal variable)")
1075 if (slice >= static_cast< int >(_kMax_))
1077 "time slice " << slice << " for '" << base
1078 << "' is out of range: it must be < kMax (" << _kMax_ << ")")
1079 }

References _atemporalVars_, _baseNames_, _kMax_, gum::KTBN< GUM_SCALAR >::ATEMPORAL, and GUM_ERROR.

Referenced by addForbiddenArc(), addForbiddenArc(), addForbiddenArcAllSlices(), addMandatoryArc(), addMandatoryArc(), addNoChildrenNode(), addNoChildrenNode(), addNoParentNode(), addNoParentNode(), addPossibleEdge(), addPossibleEdge(), eraseForbiddenArc(), eraseForbiddenArc(), eraseForbiddenArcAllSlices(), eraseMandatoryArc(), eraseMandatoryArc(), eraseNoChildrenNode(), eraseNoChildrenNode(), eraseNoParentNode(), eraseNoParentNode(), erasePossibleEdge(), and erasePossibleEdge().

Here is the caller graph for this function:

◆ _verifyKernelArc_()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_verifyKernelArc_ ( std::string_view tailBase,
std::string_view headBase,
int lag ) const
private

Throw InvalidArgument unless tailBase and headBase are known, temporal base variables (a kernel-relative arc has no meaning for an atemporal one: it has no kernel-slice instance) and lag is in [0, kMax) — so some candidate k in [2,kMax] can place tailBase at slice k-1-lag >= 0 and headBase at the kernel slice k-1. Used by the four kernel-arc setters (add/eraseForbiddenKernelArc, add/eraseMandatoryKernelArc) to reject bad calls eagerly.

Definition at line 1082 of file KTBNAdaptiveLearner_tpl.h.

1084 {
1085 // an atemporal variable has a single instance, not a per-slice one, so it
1086 // has no kernel slice to anchor a lag against: same rule as the intra-slice
1087 // setters, hence the same shared check
1088 for (const std::string_view base: {tailBase, headBase})
1089 _checkBaseIsTemporal_(base, "a kernel-relative arc");
1090 // lag < 0 would place the tail AFTER the kernel slice (the last slice by
1091 // definition), which can never happen
1092 if (lag < 0) GUM_ERROR(InvalidArgument, "negative kernel lag " << lag << ": lag must be >= 0")
1093 // some candidate k in [2,kMax] must be able to place the tail at slice
1094 // k-1-lag >= 0, i.e. lag <= k-1 <= kMax-1
1095 if (lag >= static_cast< int >(_kMax_))
1097 "kernel lag " << lag << " is out of range: it must be < kMax (" << _kMax_
1098 << "), so some candidate k can place the tail at slice k-1-lag >= 0")
1099 }
void _checkBaseIsTemporal_(std::string_view base, std::string_view context) const
Throw InvalidArgument unless base is a known temporal base. context completes "cannot appear in <cont...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_checkBaseIsTemporal_(), _kMax_, and GUM_ERROR.

Referenced by addForbiddenKernelArc(), addMandatoryKernelArc(), eraseForbiddenKernelArc(), and eraseMandatoryKernelArc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addForbiddenArc() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addForbiddenArc ( std::string_view tailBase,
int tailSlice,
std::string_view headBase,
int headSlice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 673 of file KTBNAdaptiveLearner_tpl.h.

676 {
677 // validate before _encode_ flattens the slice (a negative one would
678 // silently read back as atemporal, losing the real error)
682 }
std::string _encode_(std::string_view base, int slice) const
(base, slice) -> engine name ("A[1]" / atemporal engine name). Pure function, shared by every learner...
void _verifyBase_(std::string_view base, int slice) const
Throw InvalidArgument unless base is a known base variable and slice is valid for it: base must be in...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and addForbiddenArc().

Here is the call graph for this function:

◆ addForbiddenArc() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addForbiddenArc ( std::string_view tailNode,
std::string_view headNode )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 656 of file KTBNAdaptiveLearner_tpl.h.

657 {
663 // no _checkArcTemporallyFeasible_ call on this path (forbidding an
664 // already-impossible backward arc is a harmless no-op), so head is not
665 // guaranteed >= tail here: both slices must be checked.
668 return *this;
669 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _forbiddenArcs_, _raiseKMinForSlice_(), and _verifyBase_().

Referenced by addForbiddenArc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addForbiddenArcAllSlices()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addForbiddenArcAllSlices ( std::string_view tailBase,
std::string_view headBase )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 850 of file KTBNAdaptiveLearner_tpl.h.

851 {
854 // record the base pair; learnKTBN() expands it over every causally-possible
855 // slice pair for each candidate k (k is not fixed here)
857 return *this;
858 }

References _forbiddenArcsAllSlices_, _verifyBase_(), and gum::KTBN< GUM_SCALAR >::ATEMPORAL.

Here is the call graph for this function:

◆ addForbiddenIntraSliceArc()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addForbiddenIntraSliceArc ( std::string_view tailBase,
std::string_view headBase )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 823 of file KTBNAdaptiveLearner_tpl.h.

824 {
825 // these constraints carry no single slice, so no slice range is checked;
826 // an atemporal base has no intra-slice position and is rejected eagerly
827 // here, where KTBNLearner would throw at its own setter (expanding to "C[t]")
828 _checkBaseIsTemporal_(tailBase, "an intra-slice constraint");
829 _checkBaseIsTemporal_(headBase, "an intra-slice constraint");
830 // record the base pair; unlike KTBNLearner it cannot be expanded per-slice
831 // now (k is not fixed) — learnKTBN() expands it for each candidate k
833 return *this;
834 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_checkBaseIsTemporal_(), and _forbiddenIntraSliceArcs_.

Here is the call graph for this function:

◆ addForbiddenKernelArc()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addForbiddenKernelArc ( std::string_view tailBase,
int lag,
std::string_view headBase )

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Definition at line 776 of file KTBNAdaptiveLearner_tpl.h.

778 {
782 return *this;
783 }
void _verifyKernelArc_(std::string_view tailBase, std::string_view headBase, int lag) const
Throw InvalidArgument unless tailBase and headBase are known, temporal base variables (a kernel-relat...

References _forbiddenKernelArcs_, _raiseKMinForSlice_(), and _verifyKernelArc_().

Here is the call graph for this function:

◆ addMandatoryArc() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addMandatoryArc ( std::string_view tailBase,
int tailSlice,
std::string_view headBase,
int headSlice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 731 of file KTBNAdaptiveLearner_tpl.h.

734 {
735 // validate before _encode_ flattens the slice (a negative one would
736 // silently read back as atemporal, losing the real error)
740 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and addMandatoryArc().

Here is the call graph for this function:

◆ addMandatoryArc() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addMandatoryArc ( std::string_view tailNode,
std::string_view headNode )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 713 of file KTBNAdaptiveLearner_tpl.h.

714 {
719 // a mandatory arc must be feasible: reject up front the arcs the k-TBN can
720 // never contain (same check KTBNLearner::addMandatoryArc runs)
721 this->_checkArcTemporallyFeasible_(tailNode, headNode, "force the mandatory arc");
723 // the feasibility check above just rejected headSlice < tailSlice, so
724 // headSlice >= tailSlice is guaranteed here: it alone determines _kMin_.
726 return *this;
727 }
void _checkArcTemporallyFeasible_(std::string_view tail, std::string_view head, std::string_view action) const
Reject an arc the k-TBN definition can never contain, so eraseForbiddenArc and addMandatoryArc both f...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_checkArcTemporallyFeasible_(), gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _mandatoryArcs_, _raiseKMinForSlice_(), and _verifyBase_().

Referenced by addMandatoryArc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addMandatoryKernelArc()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addMandatoryKernelArc ( std::string_view tailBase,
int lag,
std::string_view headBase )

Force an arc from tailBase, lag slices before the kernel, to headBase in the kernel. See addForbiddenKernelArc for the (base, slice) vs. kernel-relative distinction; the validity constraints (lag range, temporal bases, kMin effect) are the same. Always temporally feasible by construction (lag >= 0 guarantees headSlice = k-1 >= k-1-lag = tailSlice), so unlike the plain addMandatoryArc there is no separate feasibility check to run.

Definition at line 798 of file KTBNAdaptiveLearner_tpl.h.

800 {
802 // no separate feasibility check: lag >= 0 (just verified) already guarantees
803 // headSlice = k-1 >= k-1-lag = tailSlice for every candidate, so this can
804 // never be a backward-in-time arc (see addMandatoryKernelArc's doc comment)
807 return *this;
808 }

References _mandatoryKernelArcs_, _raiseKMinForSlice_(), and _verifyKernelArc_().

Here is the call graph for this function:

◆ addNoChildrenNode() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addNoChildrenNode ( std::string_view base,
int slice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 908 of file KTBNAdaptiveLearner_tpl.h.

908 {
909 // validate before _encode_ flattens the slice (see the arc overloads above)
912 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and addNoChildrenNode().

Referenced by addNoChildrenNode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addNoChildrenNode() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addNoChildrenNode ( std::string_view name)
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 916 of file KTBNAdaptiveLearner_tpl.h.

916 {
917 const auto [base, slice] = _determineNode_(std::string{name});
921 return *this;
922 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _noChildrenNodes_, _raiseKMinForSlice_(), and _verifyBase_().

Here is the call graph for this function:

◆ addNoParentNode() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addNoParentNode ( std::string_view base,
int slice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 872 of file KTBNAdaptiveLearner_tpl.h.

872 {
873 // validate before _encode_ flattens the slice (see the arc overloads above)
876 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and addNoParentNode().

Referenced by addNoParentNode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addNoParentNode() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addNoParentNode ( std::string_view name)
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 880 of file KTBNAdaptiveLearner_tpl.h.

880 {
881 const auto [base, slice] = _determineNode_(std::string{name});
885 return *this;
886 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _noParentNodes_, _raiseKMinForSlice_(), and _verifyBase_().

Here is the call graph for this function:

◆ addPossibleEdge() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addPossibleEdge ( std::string_view tail,
std::string_view head )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 957 of file KTBNAdaptiveLearner_tpl.h.

958 {
963 // an edge is undirected (BNLearner stores it as a gum::Edge), so the pair is
964 // normalized alphabetically: (A,B) and (B,A) are one and the same record
968 // an edge is undirected and unchecked, so neither slice dominates: both
969 // must be checked (tailSlice/headSlice, decoded above the swap, are
970 // unaffected by it).
973 return *this;
974 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _possibleEdges_, _raiseKMinForSlice_(), and _verifyBase_().

Here is the call graph for this function:

◆ addPossibleEdge() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::addPossibleEdge ( std::string_view tailBase,
int tailSlice,
std::string_view headBase,
int headSlice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 944 of file KTBNAdaptiveLearner_tpl.h.

947 {
948 // validate before _encode_ flattens the slice (a negative one would
949 // silently read back as atemporal, losing the real error)
953 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and addPossibleEdge().

Referenced by addPossibleEdge().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ allowArcAdditions()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::allowArcAdditions ( bool allow = true)
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 1008 of file KTBNAdaptiveLearner_tpl.h.

1008 {
1010 return *this;
1011 }

References _allowAdditions_.

◆ allowArcDeletions()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::allowArcDeletions ( bool allow = true)
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 1015 of file KTBNAdaptiveLearner_tpl.h.

1015 {
1017 return *this;
1018 }

References _allowDeletions_.

◆ allowArcReversals()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::allowArcReversals ( bool allow = true)
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 1022 of file KTBNAdaptiveLearner_tpl.h.

1022 {
1024 return *this;
1025 }

References _allowReversals_.

◆ bestK()

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::bestK ( ) const

Order k selected by the last learnKTBN() call.

Exceptions
OperationNotAllowedif learnKTBN() has not run yet.

Definition at line 299 of file KTBNAdaptiveLearner_tpl.h.

299 {
300 // _bestK_ stays at its sentinel 0 (never a valid order: candidates are >= 2)
301 // until learnKTBN() selects one, so 0 means no learning has run yet.
302 if (_bestK_ == 0)
304 "bestK() is undefined: call learnKTBN() before querying the selected order.")
306 }
Size _bestK_
k selected by the last learnKTBN() call, or 0 as a sentinel while no learning has happened yet....

References _bestK_, and GUM_ERROR.

Referenced by learnKTBN().

Here is the caller graph for this function:

◆ checkScorePriorCompatibility()

template<GUM_Numeric GUM_SCALAR>
std::string gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::checkScorePriorCompatibility ( ) const

Warning string if the recorded score and prior are incompatible, empty otherwise. Data-free: it evaluates the recorded (score, prior) pair exactly as KTBNLearner/BNLearner would, so an incompatible combination can be caught before learnKTBN() reads any trajectory.

Definition at line 338 of file KTBNAdaptiveLearner_tpl.h.

338 {
339 // MIIC is constraint-based: it consumes a correction, not a score, so no
340 // score/prior clash is possible. (Mirrors IBNLearner::isConstraintBased.)
341 if (_algo_ == IBNLearner::AlgoType::MIIC) return "";
342
343 // map the recorded prior to the internal PriorType. The adaptive learner only
344 // ever records NO_prior or SMOOTHING (its sole prior setter is useSmoothingPrior).
348
349 // delegate to the very same per-score static checks BNLearner uses
350 switch (_score_) {
359 default : return ""; // K2 is never recorded by this learner's setters
360 }
361 }
std::string isPriorCompatible() const final
indicates whether the prior is compatible (meaningful) with the score
std::string isPriorCompatible() const final
indicates whether the prior is compatible (meaningful) with the score
std::string isPriorCompatible() const final
indicates whether the prior is compatible (meaningful) with the score
std::string isPriorCompatible() const final
indicates whether the prior is compatible (meaningful) with the score
std::string isPriorCompatible() const final
indicates whether the prior is compatible (meaningful) with the score
std::string isPriorCompatible() const final
indicates whether the prior is compatible (meaningful) with the score

References _algo_, _prior_, _priorWeight_, _score_, gum::learning::IBNLearner::AIC, gum::learning::IBNLearner::BD, gum::learning::IBNLearner::BDeu, gum::learning::IBNLearner::BIC, gum::learning::IBNLearner::fNML, gum::learning::ScoreAIC::isPriorCompatible(), gum::learning::ScoreBD::isPriorCompatible(), gum::learning::ScoreBDeu::isPriorCompatible(), gum::learning::ScoreBIC::isPriorCompatible(), gum::learning::ScorefNML::isPriorCompatible(), gum::learning::ScoreLog2Likelihood::isPriorCompatible(), gum::learning::IBNLearner::LOG2LIKELIHOOD, gum::learning::IBNLearner::MDL, gum::learning::IBNLearner::MIIC, gum::learning::NoPriorType, gum::learning::IBNLearner::SMOOTHING, and gum::learning::SmoothingPriorType.

Referenced by state().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ eraseForbiddenArc() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenArc ( std::string_view tailBase,
int tailSlice,
std::string_view headBase,
int headSlice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 700 of file KTBNAdaptiveLearner_tpl.h.

703 {
704 // validate before _encode_ flattens the slice (a negative one would
705 // silently read back as atemporal, losing the real error)
709 }
KTBNAdaptiveLearner< GUM_SCALAR > & eraseForbiddenArc(std::string_view tailNode, std::string_view headNode) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and eraseForbiddenArc().

Here is the call graph for this function:

◆ eraseForbiddenArc() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenArc ( std::string_view tailNode,
std::string_view headNode )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 686 of file KTBNAdaptiveLearner_tpl.h.

687 {
692 this->_checkArcTemporallyFeasible_(tailNode, headNode, "un-forbid the arc");
695 return *this;
696 }
void _recomputeKMin_()
Recompute kMin from scratch: max(2, 1 + the largest concrete slice named by any recorded forbidden/ma...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_checkArcTemporallyFeasible_(), gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _forbiddenArcs_, _recomputeKMin_(), and _verifyBase_().

Referenced by eraseForbiddenArc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ eraseForbiddenArcAllSlices()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenArcAllSlices ( std::string_view tailBase,
std::string_view headBase )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 862 of file KTBNAdaptiveLearner_tpl.h.

References _forbiddenArcsAllSlices_, _verifyBase_(), and gum::KTBN< GUM_SCALAR >::ATEMPORAL.

Here is the call graph for this function:

◆ eraseForbiddenIntraSliceArc()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenIntraSliceArc ( std::string_view tailBase,
std::string_view headBase )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 838 of file KTBNAdaptiveLearner_tpl.h.

839 {
840 // same eager rejection as addForbiddenIntraSliceArc: such a constraint can
841 // never have been recorded
842 _checkBaseIsTemporal_(tailBase, "an intra-slice constraint");
843 _checkBaseIsTemporal_(headBase, "an intra-slice constraint");
845 return *this;
846 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_checkBaseIsTemporal_(), and _forbiddenIntraSliceArcs_.

Here is the call graph for this function:

◆ eraseForbiddenKernelArc()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseForbiddenKernelArc ( std::string_view tailBase,
int lag,
std::string_view headBase )

Undo a previous addForbiddenKernelArc (same (tailBase, lag, headBase) triple).

Definition at line 787 of file KTBNAdaptiveLearner_tpl.h.

References _forbiddenKernelArcs_, _recomputeKMin_(), and _verifyKernelArc_().

Here is the call graph for this function:

◆ eraseMandatoryArc() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseMandatoryArc ( std::string_view tailBase,
int tailSlice,
std::string_view headBase,
int headSlice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 759 of file KTBNAdaptiveLearner_tpl.h.

762 {
763 // validate before _encode_ flattens the slice (a negative one would
764 // silently read back as atemporal, losing the real error)
768 }
KTBNAdaptiveLearner< GUM_SCALAR > & eraseMandatoryArc(std::string_view tailNode, std::string_view headNode) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and eraseMandatoryArc().

Here is the call graph for this function:

◆ eraseMandatoryArc() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseMandatoryArc ( std::string_view tailNode,
std::string_view headNode )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 744 of file KTBNAdaptiveLearner_tpl.h.

745 {
750 // no feasibility check: erasing a never-forced arc is a harmless no-op
751 // (mirrors KTBNLearner::eraseMandatoryArc)
754 return *this;
755 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _mandatoryArcs_, _recomputeKMin_(), and _verifyBase_().

Referenced by eraseMandatoryArc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ eraseMandatoryKernelArc()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseMandatoryKernelArc ( std::string_view tailBase,
int lag,
std::string_view headBase )

Undo a previous addMandatoryKernelArc (same (tailBase, lag, headBase) triple).

Definition at line 812 of file KTBNAdaptiveLearner_tpl.h.

References _mandatoryKernelArcs_, _recomputeKMin_(), and _verifyKernelArc_().

Here is the call graph for this function:

◆ eraseNoChildrenNode() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseNoChildrenNode ( std::string_view base,
int slice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 926 of file KTBNAdaptiveLearner_tpl.h.

926 {
927 // validate before _encode_ flattens the slice (see the arc overloads above)
930 }
KTBNAdaptiveLearner< GUM_SCALAR > & eraseNoChildrenNode(std::string_view base, int slice) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and eraseNoChildrenNode().

Referenced by eraseNoChildrenNode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ eraseNoChildrenNode() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseNoChildrenNode ( std::string_view name)
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 934 of file KTBNAdaptiveLearner_tpl.h.

934 {
935 const auto [base, slice] = _determineNode_(std::string{name});
939 return *this;
940 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _noChildrenNodes_, _recomputeKMin_(), and _verifyBase_().

Here is the call graph for this function:

◆ eraseNoParentNode() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseNoParentNode ( std::string_view base,
int slice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 890 of file KTBNAdaptiveLearner_tpl.h.

890 {
891 // validate before _encode_ flattens the slice (see the arc overloads above)
894 }
KTBNAdaptiveLearner< GUM_SCALAR > & eraseNoParentNode(std::string_view base, int slice) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and eraseNoParentNode().

Referenced by eraseNoParentNode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ eraseNoParentNode() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::eraseNoParentNode ( std::string_view name)
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 898 of file KTBNAdaptiveLearner_tpl.h.

898 {
899 const auto [base, slice] = _determineNode_(std::string{name});
903 return *this;
904 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _noParentNodes_, _recomputeKMin_(), and _verifyBase_().

Here is the call graph for this function:

◆ erasePossibleEdge() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::erasePossibleEdge ( std::string_view tail,
std::string_view head )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 991 of file KTBNAdaptiveLearner_tpl.h.

992 {
997 // same alphabetical normalization as addPossibleEdge, so erasing (B,A)
998 // removes the edge recorded as (A,B)
1003 return *this;
1004 }

References gum::learning::IKTBNLearner< GUM_SCALAR >::_determineNode_(), _possibleEdges_, _recomputeKMin_(), and _verifyBase_().

Here is the call graph for this function:

◆ erasePossibleEdge() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::erasePossibleEdge ( std::string_view tailBase,
int tailSlice,
std::string_view headBase,
int headSlice )
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 978 of file KTBNAdaptiveLearner_tpl.h.

981 {
982 // validate before _encode_ flattens the slice (a negative one would
983 // silently read back as atemporal, losing the real error)
987 }
KTBNAdaptiveLearner< GUM_SCALAR > & erasePossibleEdge(std::string_view tailBase, int tailSlice, std::string_view headBase, int headSlice) override
Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at sli...

References gum::learning::IKTBNLearner< GUM_SCALAR >::_encode_(), _verifyBase_(), and erasePossibleEdge().

Referenced by erasePossibleEdge().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ignoreMissingSymbols()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::ignoreMissingSymbols ( bool ignore = true)

Learn and score on the fully observed data only, dropping every row and every scoring instance that carries a missing symbol.

Without this, learnKTBN() refuses trajectories containing missing values: aGrUM's structure learning cannot cope with them (gum::learning::IBNLearner::learnDag_ raises MissingValueInDatabase), so there is nothing sensible to hand it. With it, each candidate's databases are built by complete-case selection and the cross-k score skips any instance whose family is incomplete — the two agree on which data counts.

Warning
This inflates \(\log_2 L\), and inflates it more for larger \(k\) — so it biases the order selection this class exists to perform.

A row or instance is dropped as soon as one cell of its window is missing, so a single gap costs up to \(k\) of them. A larger \(k\) spans more rows per window and loses proportionally more.

\(\log_2 L\) is a sum of per-instance terms, each \(\leq 0\). Dropping instances removes negative terms and therefore raises the total: the candidate is not fitting better, it is being charged for less data. Since the larger \(k\) drops more, it gains more — precisely the comparison bestK() rests on.

The BIC penalty does not compensate. \(\log_2 N\) is computed once from the raw trajectory lengths (deliberately, so it is identical across candidates) and so describes a sample size the likelihood no longer uses; the penalty is unchanged while the likelihood is inflated.

The distortion grows with the missing-value rate. At a few percent it is usually harmless; on heavily incomplete trajectories bestK() can be pulled a full order upwards. Inspect scorePerCandidateK() rather than trusting bestK() alone, and prefer complete trajectories whenever the order itself is the question. gum::learning::KTBNLearner::nbDroppedRows() reports how much each candidate actually lost.

Definition at line 573 of file KTBNAdaptiveLearner_tpl.h.

573 {
575 return *this;
576 }
bool _ignoreMissingSymbols_
whether incomplete rows/instances are dropped (see ignoreMissingSymbols())

References _ignoreMissingSymbols_.

◆ isIgnoringMissingSymbols()

template<GUM_Numeric GUM_SCALAR>
INLINE bool gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::isIgnoringMissingSymbols ( ) const

Whether incomplete rows and instances are dropped. False by default.

Definition at line 579 of file KTBNAdaptiveLearner_tpl.h.

579 {
581 }

References _ignoreMissingSymbols_.

◆ kMax()

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::kMax ( ) const

Largest order explored (the kMax argument of the constructor).

Definition at line 333 of file KTBNAdaptiveLearner_tpl.h.

333 {
334 return _kMax_;
335 }

References _kMax_.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), and _inferAtemporalVars_().

Here is the caller graph for this function:

◆ latentVariables()

template<GUM_Numeric GUM_SCALAR>
const std::vector< std::pair< std::string, std::string > > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::latentVariables ( ) const

Engine-name (tail, head) pairs of arcs the selected model's MIIC run flagged as hiding a latent variable. Empty when the recorded algorithm is not MIIC (only MIIC produces latent-variable annotations) or when none were found.

Exceptions
OperationNotAllowedif learnKTBN() has not run yet.

Definition at line 310 of file KTBNAdaptiveLearner_tpl.h.

310 {
311 // gated on the same sentinel as bestK(): 0 means learnKTBN() has not run.
312 if (_bestK_ == 0)
313 GUM_ERROR(OperationNotAllowed, "latentVariables() is undefined: call learnKTBN() first.")
315 }
std::vector< std::pair< std::string, std::string > > _bestLatentVariables_
latent-variable arcs (engine-name pairs) reported by the winning candidate's MIIC run,...

References _bestK_, _bestLatentVariables_, and GUM_ERROR.

◆ learnKTBN()

template<GUM_Numeric GUM_SCALAR>
KTBN< GUM_SCALAR > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::learnKTBN ( )
overridevirtual

Learns the best k in [kMin, kMax] together with the structure and the CPTs: one KTBNLearner is built and run per candidate k, the recorded configuration is replayed on each, and the k-TBN with the best model-selection score is returned. kMin starts at 2 and is raised by the structural-constraint setters (see class doc).

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 198 of file KTBNAdaptiveLearner_tpl.h.

198 {
199 // Explore every candidate order _kMin_.._kMax_ and keep the k-TBN with the
200 // best cross-k model-selection score (BIC by default; see useOrderScore*).
201 // _kMin_ -- 2 unless raised by a constraint naming a concrete slice, see
202 // _recomputeKMin_ -- skips candidates that would only drop that constraint.
203 // Each candidate is a full fixed-k problem: a fresh KTBNLearner on the same
204 // trajectories, replaying the recorded configuration and constraints (those
205 // whose slices do not fit that k are dropped by _applyConstraints_).
206 // Reset first: a re-entry, or a throw below, must not leave a stale selection
207 // readable through bestK() / latentVariables().
208 _bestK_ = 0;
209 _bestLatentVariables_.clear();
210 _scorePerCandidateK_.clear();
212 Size bestK = 0; // local; committed to _bestK_ only if the whole sweep succeeds
213 double bestScore = 0.0; // unread until the first candidate sets it
214 double logN = 0.0; // log2 of the total number of observations
215 std::vector< std::pair< Size, double > > scores; // per-k scores, committed at the end
217 bestLatents; // winner's latent pairs, committed at the end
218
219 for (Size k = _kMin_; k <= _kMax_; ++k) {
220 // build this candidate's fixed-k learner: from the schema BN when one was
221 // supplied (domains fixed explicitly), else from the CSV (domains inferred).
222 // KTBNLearner is non-movable, so hold it through a unique_ptr.
227 k,
228 *_prior_bn_,
235 k,
241
242 // Refused here rather than deep inside structure learning: learnDag_ would
243 // otherwise raise its own generic message only after this candidate's
244 // databases had been built. Every candidate reads the same trajectories, so
245 // the verdict on the first holds for all.
246 if (!_ignoreMissingSymbols_ && learner.hasMissingValues())
248 "the trajectories contain missing values. Neither aGrUM's structure learning "
249 "nor the cross-k order score can evaluate an incomplete window. Call "
250 "ignoreMissingSymbols() to learn and score on the fully observed data only "
251 "(see its warning: dropping skews the selection towards larger k).")
252
253 // sample size for the BIC penalty: the total number of time-slice rows over
254 // all trajectories. Independent of k, so it is computed once on the first
255 // candidate and reused — it must stay fixed for the scores to compare.
256 if (logN == 0.0) {
257 Size nbObs = 0;
258 for (const Size len: learner.nbRows())
259 nbObs += len;
261 }
262
265
267
268 // Cross-k model selection by the recorded order score (BIC by default):
269 // it must be comparable across k, unlike the per-k structure score, so it
270 // is computed here on the whole learned k-TBN rather than read off the
271 // internal learners. bestK == 0 means nothing is selected yet, so the
272 // first candidate is always taken; a strict '>' afterwards keeps the
273 // smallest k on ties (mild parsimony).
274 const double score = _orderSelectionScore_(candidate, logN);
275 scores.emplace_back(k, score);
276 if (bestK == 0 || score > bestScore) {
279 bestK = k;
280 // capture the winner's latent-variable annotations while its learner is
281 // still alive (only MIIC produces them; other algos leave the set empty)
285 }
286 }
287
288 // Commit only after every candidate has succeeded. An exception thrown above
289 // (e.g. a trajectory too short for some candidate k) leaves the members at
290 // their reset state, so bestK() / latentVariables() / scorePerCandidateK()
291 // keep reporting "not learned" — the all-or-nothing guarantee promised above.
292 _bestK_ = bestK;
295 return best;
296 }
void _applyConstraints_(KTBNLearner< GUM_SCALAR > &learner, Size k) const
Replay the recorded structural constraints onto learner (built for order k). Engine-name constraints ...
double _orderSelectionScore_(const KTBN< GUM_SCALAR > &net, double logN) const
The cross-k order-selection score of net under the recorded orderScore criterion, given logN = log2 o...
const std::vector< std::pair< std::string, std::string > > & latentVariables() const
Engine-name (tail, head) pairs of arcs the selected model's MIIC run flagged as hiding a latent varia...
Size bestK() const
Order k selected by the last learnKTBN() call.
void _applyConfig_(KTBNLearner< GUM_SCALAR > &learner) const
Apply the recorded score / algorithm / correction / prior onto a freshly-built learner....
std::vector< std::pair< Size, double > > _scorePerCandidateK_
per-candidate (k, order-score) pairs from the last learnKTBN() run, in ascending k....
KTBN< GUM_SCALAR > learnKTBN() override
Learns the best k in [kMin, kMax] together with the structure and the CPTs: one KTBNLearner is built ...

References _algo_, _applyConfig_(), _applyConstraints_(), _atemporalVars_, _bestK_, _bestLatentVariables_, _csvBaseName_, _dirPath_, _ignoreMissingSymbols_, _induceTypes_, _kMax_, _kMin_, _missingSymbols_, _nbSamples_, _orderSelectionScore_(), _prior_bn_, _scorePerCandidateK_, bestK(), GUM_ERROR, and gum::learning::IBNLearner::MIIC.

Here is the call graph for this function:

◆ operator=() [1/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::operator= ( const KTBNAdaptiveLearner< GUM_SCALAR > & )
privatedelete

References KTBNAdaptiveLearner().

Here is the call graph for this function:

◆ operator=() [2/2]

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::operator= ( KTBNAdaptiveLearner< GUM_SCALAR > && )
privatedelete

References KTBNAdaptiveLearner().

Here is the call graph for this function:

◆ scorePerCandidateK()

template<GUM_Numeric GUM_SCALAR>
const std::vector< std::pair< Size, double > > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::scorePerCandidateK ( ) const

Per-candidate cross-k scores from the last learnKTBN() call, as (k, score) pairs for k = kMin..kMax in ascending k order — the values the order selection compared to choose bestK() (higher is better; the argmax is bestK()). Under the default useOrderScoreBIC() each score is \(\log_2 L - \tfrac{1}{2}\,d\,\log_2 N\) of the k-TBN learned for that k.

Exceptions
OperationNotAllowedif learnKTBN() has not run yet.

Definition at line 319 of file KTBNAdaptiveLearner_tpl.h.

319 {
320 // same sentinel gate as bestK()/latentVariables(): 0 means learnKTBN() has not run.
321 if (_bestK_ == 0)
322 GUM_ERROR(
324 "scorePerCandidateK() is undefined: call learnKTBN() before querying the per-k scores.")
326 }

References _bestK_, _scorePerCandidateK_, and GUM_ERROR.

◆ setMaxIndegree()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::setMaxIndegree ( Size max_indegree)
overridevirtual

Forbid an arc from tailBase, lag slices before the kernel, to headBase in the kernel: tailBase at slice k-1-lag -> headBase at slice k-1, for whichever k is selected. The slice is not given directly but derived from lag relative to the kernel slice k-1, which moves with the candidate — so no absolute slice could express it at record time. Adaptive-only: the fixed-k learners have no moving kernel slice to anchor it to. lag must be in [0, kMax) and both bases temporal (an atemporal variable has no kernel-slice instance). Raises kMin to at least lag+1, like a constraint naming slice lag.

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 1029 of file KTBNAdaptiveLearner_tpl.h.

1029 {
1031 return *this;
1032 }

References _maxIndegree_.

◆ state()

template<GUM_Numeric GUM_SCALAR>
std::vector< std::tuple< std::string, std::string, std::string > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::state ( ) const

The recorded configuration as (key, value, comment) tuples (mirrors KTBNLearner::state()); toString() is a formatted view of it.

Definition at line 365 of file KTBNAdaptiveLearner_tpl.h.

365 {
367 const auto add = [&](std::string k, std::string v, std::string c = "") {
368 vals.emplace_back(std::move(k), std::move(v), std::move(c));
369 };
370 // render a set of engine-name pairs as "{a->b, c->d}"
371 const auto arcs = [](const std::set< std::pair< std::string, std::string > >& s) {
372 std::string r = "{";
373 bool first = true;
374 for (const auto& [a, b]: s) {
375 if (!first) r += ", ";
376 first = false;
377 r += a + "->" + b;
378 }
379 return r + "}";
380 };
381 const auto names = [](const std::set< std::string >& s) {
382 std::string r = "{";
383 bool first = true;
384 for (const auto& n: s) {
385 if (!first) r += ", ";
386 first = false;
387 r += n;
388 }
389 return r + "}";
390 };
391 // render a set of (tailBase, headBase, lag) triples as "{a->b (lag 1), ...}"
393 std::string r = "{";
394 bool first = true;
395 for (const auto& [a, b, lag]: s) {
396 if (!first) r += ", ";
397 first = false;
398 r += a + "->" + b + " (lag " + std::to_string(lag) + ")";
399 }
400 return r + "}";
401 };
402
403 add("Candidate orders", std::to_string(_kMin_) + ".." + std::to_string(_kMax_));
404 add("Selected k", _bestK_ == 0 ? "not learned yet" : std::to_string(_bestK_));
405 add("Base variables", std::to_string(_baseNames_.size()));
406 add("Atemporal variables", names({_atemporalVars_.begin(), _atemporalVars_.end()}));
407
408 switch (_algo_) {
409 case IBNLearner::AlgoType::MIIC : add("Algorithm", "MIIC"); break;
411 add("Algorithm", "Greedy Hill Climbing");
412 break;
414 add("Algorithm", "Extended Greedy Hill Climbing");
415 break;
417 add("Algorithm", "Local Search with Tabu List");
418 add("Tabu list size", std::to_string(_tabuSize_));
419 add("Tabu nb decrease", std::to_string(_nbDecrease_));
420 break;
421 default : add("Algorithm", "(other)"); break;
422 }
423
425 switch (_correction_) {
426 case CorrectedMutualInformation::KModeTypes::MDL : add("Correction", "MDL"); break;
427 case CorrectedMutualInformation::KModeTypes::NML : add("Correction", "NML"); break;
429 add("Correction", "No correction");
430 break;
431 }
432 } else {
433 switch (_score_) {
434 case IBNLearner::ScoreType::AIC : add("Structure score", "AIC"); break;
435 case IBNLearner::ScoreType::BD : add("Structure score", "BD"); break;
436 case IBNLearner::ScoreType::BDeu : add("Structure score", "BDeu"); break;
437 case IBNLearner::ScoreType::BIC : add("Structure score", "BIC"); break;
438 case IBNLearner::ScoreType::fNML : add("Structure score", "fNML"); break;
440 add("Structure score", "Log2Likelihood");
441 break;
442 case IBNLearner::ScoreType::MDL : add("Structure score", "MDL"); break;
443 default : add("Structure score", "(other)"); break;
444 }
445 }
446
447 // the outer, cross-k criterion — distinct from the per-k structure score above
448 switch (_orderScore_) {
449 case OrderScoreType::BIC : add("Order selection score", "BIC"); break;
450 case OrderScoreType::AIC : add("Order selection score", "AIC"); break;
451 case OrderScoreType::fNML : add("Order selection score", "fNML"); break;
452 }
453
455 add("Prior", "Smoothing", checkScorePriorCompatibility());
456 add("Prior weight", std::to_string(_priorWeight_));
457 } else {
458 add("Prior", "no prior is set", checkScorePriorCompatibility());
459 }
460
461 if (!_forbiddenArcs_.empty()) add("Forbidden arcs", arcs(_forbiddenArcs_));
462 if (!_mandatoryArcs_.empty()) add("Mandatory arcs", arcs(_mandatoryArcs_));
463 if (!_forbiddenKernelArcs_.empty())
464 add("Forbidden kernel arcs", kernelArcs(_forbiddenKernelArcs_));
465 if (!_mandatoryKernelArcs_.empty())
466 add("Mandatory kernel arcs", kernelArcs(_mandatoryKernelArcs_));
467 if (!_possibleEdges_.empty()) add("Possible edges", arcs(_possibleEdges_));
468 if (!_forbiddenIntraSliceArcs_.empty())
469 add("Forbidden intra-slice arcs", arcs(_forbiddenIntraSliceArcs_));
470 if (!_forbiddenArcsAllSlices_.empty())
471 add("Forbidden all-slices arcs", arcs(_forbiddenArcsAllSlices_));
472 if (!_noParentNodes_.empty()) add("No-parent nodes", names(_noParentNodes_));
473 if (!_noChildrenNodes_.empty()) add("No-children nodes", names(_noChildrenNodes_));
475 add("Max in-degree", std::to_string(_maxIndegree_));
476 if (!_allowAdditions_) add("Arc additions", "forbidden");
477 if (!_allowDeletions_) add("Arc deletions", "forbidden");
478 if (!_allowReversals_) add("Arc reversals", "forbidden");
479
480 return vals;
481 }
std::string checkScorePriorCompatibility() const
Warning string if the recorded score and prior are incompatible, empty otherwise. Data-free: it evalu...

References _algo_, _allowAdditions_, _allowDeletions_, _allowReversals_, _atemporalVars_, _baseNames_, _bestK_, _correction_, _forbiddenArcs_, _forbiddenArcsAllSlices_, _forbiddenIntraSliceArcs_, _forbiddenKernelArcs_, _kMax_, _kMin_, _mandatoryArcs_, _mandatoryKernelArcs_, _maxIndegree_, _nbDecrease_, _noChildrenNodes_, _noParentNodes_, _orderScore_, _possibleEdges_, _prior_, _priorWeight_, _score_, _tabuSize_, gum::learning::IBNLearner::AIC, AIC, gum::learning::IBNLearner::BD, gum::learning::IBNLearner::BDeu, gum::learning::IBNLearner::BIC, BIC, checkScorePriorCompatibility(), gum::learning::IBNLearner::EXTENDED_GREEDY_HILL_CLIMBING, gum::learning::IBNLearner::fNML, fNML, gum::learning::IBNLearner::GREEDY_HILL_CLIMBING, gum::learning::IBNLearner::LOCAL_SEARCH_WITH_TABU_LIST, gum::learning::IBNLearner::LOG2LIKELIHOOD, gum::learning::CorrectedMutualInformation::MDL, gum::learning::IBNLearner::MDL, gum::learning::IBNLearner::MIIC, gum::learning::CorrectedMutualInformation::NML, gum::learning::CorrectedMutualInformation::NoCorr, and gum::learning::IBNLearner::SMOOTHING.

Referenced by toString().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ toString()

template<GUM_Numeric GUM_SCALAR>
std::string gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::toString ( ) const

Human-readable summary of the recorded configuration (candidate order range, algorithm / score / correction / prior, structural constraints) plus the selected k once learnKTBN() has run.

Definition at line 484 of file KTBNAdaptiveLearner_tpl.h.

484 {
485 // aligned "key : value (comment)" listing, same layout as BNLearner::toString
486 const auto st = state();
488 for (const auto& t: st)
490
492 for (const auto& t: st) {
493 s += std::format("{:<{}} : {}", std::get< 0 >(t), maxkey, std::get< 1 >(t));
494 if (!std::get< 2 >(t).empty()) s += std::format(" ({})", std::get< 2 >(t));
495 s += '\n';
496 }
497 return s;
498 }
std::vector< std::tuple< std::string, std::string, std::string > > state() const
The recorded configuration as (key, value, comment) tuples (mirrors KTBNLearner::state()); toString()...

References state().

Here is the call graph for this function:

◆ useExtendedGreedyHillClimbing()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useExtendedGreedyHillClimbing ( )
overridevirtual

◆ useGreedyHillClimbing()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useGreedyHillClimbing ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 588 of file KTBNAdaptiveLearner_tpl.h.

588 {
590 return *this;
591 }

References KTBNAdaptiveLearner(), _algo_, and gum::learning::IBNLearner::GREEDY_HILL_CLIMBING.

Here is the call graph for this function:

◆ useLocalSearchWithTabuList()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useLocalSearchWithTabuList ( Size tabu_size = 100,
Size nb_decrease = 2 )
overridevirtual

◆ useMDLCorrection()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useMDLCorrection ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 627 of file KTBNAdaptiveLearner_tpl.h.

627 {
629 return *this;
630 }

References KTBNAdaptiveLearner(), _correction_, and gum::learning::CorrectedMutualInformation::MDL.

Here is the call graph for this function:

◆ useMIIC()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useMIIC ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 611 of file KTBNAdaptiveLearner_tpl.h.

611 {
613 return *this;
614 }

References KTBNAdaptiveLearner(), _algo_, and gum::learning::IBNLearner::MIIC.

Here is the call graph for this function:

◆ useNMLCorrection()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useNMLCorrection ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 621 of file KTBNAdaptiveLearner_tpl.h.

621 {
623 return *this;
624 }

References KTBNAdaptiveLearner(), _correction_, and gum::learning::CorrectedMutualInformation::NML.

Here is the call graph for this function:

◆ useNoCorrection()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useNoCorrection ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 633 of file KTBNAdaptiveLearner_tpl.h.

633 {
635 return *this;
636 }

References KTBNAdaptiveLearner(), _correction_, and gum::learning::CorrectedMutualInformation::NoCorr.

Here is the call graph for this function:

◆ useOrderScoreAIC()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useOrderScoreAIC ( )

Select k by AIC: keep the k whose learned model maximises \(\log_2 L - d\) (a lighter, sample-size-independent complexity penalty than BIC).

Definition at line 556 of file KTBNAdaptiveLearner_tpl.h.

556 {
558 return *this;
559 }

References KTBNAdaptiveLearner(), _orderScore_, and AIC.

Here is the call graph for this function:

◆ useOrderScoreBIC()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useOrderScoreBIC ( )

Select k by BIC (the default): keep the k whose learned model maximises \(\log_2 L - \tfrac{1}{2}\,d\,\log_2 N\).

Definition at line 550 of file KTBNAdaptiveLearner_tpl.h.

550 {
552 return *this;
553 }

References KTBNAdaptiveLearner(), _orderScore_, and BIC.

Here is the call graph for this function:

◆ useOrderScorefNML()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useOrderScorefNML ( )

\(\tfrac{1}{2}\,d\,\log_2 N\) by a sum of per-node, per-parent-configuration multinomial parametric complexities (regret) – data-dependent, unlike BIC/AIC, matching aGrUM's ScorefNML.

Definition at line 562 of file KTBNAdaptiveLearner_tpl.h.

562 {
564 return *this;
565 }

References KTBNAdaptiveLearner(), _orderScore_, and fNML.

Here is the call graph for this function:

◆ useScoreAIC()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useScoreAIC ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 505 of file KTBNAdaptiveLearner_tpl.h.

505 {
507 return *this;
508 }

References KTBNAdaptiveLearner(), _score_, and gum::learning::IBNLearner::AIC.

Here is the call graph for this function:

◆ useScoreBD()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useScoreBD ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 511 of file KTBNAdaptiveLearner_tpl.h.

511 {
513 return *this;
514 }

References KTBNAdaptiveLearner(), _score_, and gum::learning::IBNLearner::BD.

Here is the call graph for this function:

◆ useScoreBDeu()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useScoreBDeu ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 517 of file KTBNAdaptiveLearner_tpl.h.

517 {
519 return *this;
520 }

References KTBNAdaptiveLearner(), _score_, and gum::learning::IBNLearner::BDeu.

Here is the call graph for this function:

◆ useScoreBIC()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useScoreBIC ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 523 of file KTBNAdaptiveLearner_tpl.h.

523 {
525 return *this;
526 }

References KTBNAdaptiveLearner(), _score_, and gum::learning::IBNLearner::BIC.

Here is the call graph for this function:

◆ useScorefNML()

template<GUM_Numeric GUM_SCALAR>
void gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useScorefNML ( )
overridevirtual

◆ useScoreLog2Likelihood()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useScoreLog2Likelihood ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 529 of file KTBNAdaptiveLearner_tpl.h.

529 {
531 return *this;
532 }

References KTBNAdaptiveLearner(), _score_, and gum::learning::IBNLearner::LOG2LIKELIHOOD.

Here is the call graph for this function:

◆ useScoreMDL()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useScoreMDL ( )
overridevirtual

Implements gum::learning::IKTBNLearner< GUM_SCALAR >.

Definition at line 535 of file KTBNAdaptiveLearner_tpl.h.

535 {
537 return *this;
538 }

References KTBNAdaptiveLearner(), _score_, and gum::learning::IBNLearner::MDL.

Here is the call graph for this function:

◆ useSmoothingPrior()

template<GUM_Numeric GUM_SCALAR>
KTBNAdaptiveLearner< GUM_SCALAR > & gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::useSmoothingPrior ( double weight = 1.0)
overridevirtual

Member Data Documentation

◆ _algo_

◆ _allowAdditions_

template<GUM_Numeric GUM_SCALAR>
bool gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_allowAdditions_ {true}
private

recorded graph-change permissions / indegree cap

Definition at line 580 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), allowArcAdditions(), and state().

◆ _allowDeletions_

template<GUM_Numeric GUM_SCALAR>
bool gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_allowDeletions_ {true}
private

Definition at line 581 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), allowArcDeletions(), and state().

◆ _allowReversals_

template<GUM_Numeric GUM_SCALAR>
bool gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_allowReversals_ {true}
private

Definition at line 582 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), allowArcReversals(), and state().

◆ _atemporalVars_

template<GUM_Numeric GUM_SCALAR>
std::unordered_set< std::string > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_atemporalVars_
private

base names of the atemporal (static) variables

Definition at line 531 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), _atemporalVarNames_(), _verifyBase_(), learnKTBN(), and state().

◆ _baseNames_

template<GUM_Numeric GUM_SCALAR>
std::unordered_set< std::string > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_baseNames_
private

all base variable names (temporal + atemporal), read from the first trajectory CSV header at construction. Authoritative universe used by the constraint setters to reject names that do not exist.

Definition at line 536 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), _isKnownBase_(), _verifyBase_(), and state().

◆ _bestK_

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_bestK_ {0}
private

k selected by the last learnKTBN() call, or 0 as a sentinel while no learning has happened yet. 0 can never be a valid order (candidates are 2..kMax), so bestK() reads it to decide whether learnKTBN() has run.

Definition at line 624 of file KTBNAdaptiveLearner.h.

Referenced by bestK(), latentVariables(), learnKTBN(), scorePerCandidateK(), and state().

◆ _bestLatentVariables_

template<GUM_Numeric GUM_SCALAR>
std::vector< std::pair< std::string, std::string > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_bestLatentVariables_
private

latent-variable arcs (engine-name pairs) reported by the winning candidate's MIIC run, captured by learnKTBN(); empty when the selected algorithm is not MIIC. Exposed by latentVariables().

Definition at line 629 of file KTBNAdaptiveLearner.h.

Referenced by latentVariables(), and learnKTBN().

◆ _correction_

◆ _csvBaseName_

template<GUM_Numeric GUM_SCALAR>
std::string gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_csvBaseName_
private

stem of each trajectory file name

Definition at line 515 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), _forEachScoredNode_(), and learnKTBN().

◆ _ctable_

template<GUM_Numeric GUM_SCALAR>
VariableLog2ParamComplexity gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_ctable_
mutableprivate

cache of log2 of the multinomial parametric complexity C^r_n, used by the fNML order penalty. Mutable because log2Cnr() memoizes; the const order-score helpers may therefore call it. Only touched under fNML.

Definition at line 771 of file KTBNAdaptiveLearner.h.

Referenced by _fNMLScore_().

◆ _dirPath_

template<GUM_Numeric GUM_SCALAR>
std::string gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_dirPath_
private

directory holding the trajectory CSV files

Definition at line 512 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), _forEachScoredNode_(), and learnKTBN().

◆ _forbiddenArcs_

template<GUM_Numeric GUM_SCALAR>
std::set< std::pair< std::string, std::string > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_forbiddenArcs_
private

forbidden arcs, as (tail, head) engine-name pairs

Definition at line 592 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), _recomputeKMin_(), addForbiddenArc(), eraseForbiddenArc(), and state().

◆ _forbiddenArcsAllSlices_

template<GUM_Numeric GUM_SCALAR>
std::set< std::pair< std::string, std::string > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_forbiddenArcsAllSlices_
private

forbidden all-slices arcs, as (tailBase, headBase) pairs

Definition at line 604 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), addForbiddenArcAllSlices(), eraseForbiddenArcAllSlices(), and state().

◆ _forbiddenIntraSliceArcs_

template<GUM_Numeric GUM_SCALAR>
std::set< std::pair< std::string, std::string > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_forbiddenIntraSliceArcs_
private

forbidden intra-slice arcs, as (tailBase, headBase) pairs

Definition at line 601 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), addForbiddenIntraSliceArc(), eraseForbiddenIntraSliceArc(), and state().

◆ _forbiddenKernelArcs_

template<GUM_Numeric GUM_SCALAR>
std::set< std::tuple< std::string, std::string, int > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_forbiddenKernelArcs_
private

forbidden kernel-relative arcs, as (tailBase, headBase, lag) triples: tailBase at slice k-1-lag -> headBase at the kernel slice k-1. Kept separate from forbiddenArcs (which stores resolved engine names) since the slice here is only known once a candidate k is fixed.

Definition at line 610 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), _recomputeKMin_(), addForbiddenKernelArc(), eraseForbiddenKernelArc(), and state().

◆ _ignoreMissingSymbols_

template<GUM_Numeric GUM_SCALAR>
bool gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_ignoreMissingSymbols_ {false}
private

whether incomplete rows/instances are dropped (see ignoreMissingSymbols())

Definition at line 542 of file KTBNAdaptiveLearner.h.

Referenced by ignoreMissingSymbols(), isIgnoringMissingSymbols(), and learnKTBN().

◆ _induceTypes_

template<GUM_Numeric GUM_SCALAR>
bool gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_induceTypes_
private

whether numeric columns are retyped (see KTBNLearner); unused (and forced false) when a schema BN is supplied

Definition at line 546 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), and learnKTBN().

◆ _kMax_

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_kMax_
private

largest order to explore (candidates are kMin..kMax)

Definition at line 521 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), _verifyBase_(), _verifyKernelArc_(), kMax(), learnKTBN(), and state().

◆ _kMin_

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_kMin_ {2}
private

smallest order worth exploring (candidates are kMin..kMax). Starts at 2 and is recomputed by recomputeKMin() from the recorded slice-bearing constraints every time one is added or erased; never set directly. See recomputeKMin() for why it must be a recompute rather than an incremental raise/lower.

Definition at line 528 of file KTBNAdaptiveLearner.h.

Referenced by _raiseKMinForSlice_(), _recomputeKMin_(), learnKTBN(), and state().

◆ _mandatoryArcs_

template<GUM_Numeric GUM_SCALAR>
std::set< std::pair< std::string, std::string > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_mandatoryArcs_
private

mandatory arcs, as (tail, head) engine-name pairs

Definition at line 595 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), _recomputeKMin_(), addMandatoryArc(), eraseMandatoryArc(), and state().

◆ _mandatoryKernelArcs_

template<GUM_Numeric GUM_SCALAR>
std::set< std::tuple< std::string, std::string, int > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_mandatoryKernelArcs_
private

mandatory kernel-relative arcs, same shape as forbiddenKernelArcs

Definition at line 613 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), _recomputeKMin_(), addMandatoryKernelArc(), eraseMandatoryKernelArc(), and state().

◆ _maxIndegree_

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_maxIndegree_ {std::numeric_limits< Size >::max()}
private

Definition at line 583 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), setMaxIndegree(), and state().

◆ _missingSymbols_

template<GUM_Numeric GUM_SCALAR>
std::vector< std::string > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_missingSymbols_
private

symbols in the CSVs to interpret as missing values

Definition at line 539 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), _forEachScoredNode_(), and learnKTBN().

◆ _nbDecrease_

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_nbDecrease_ {2}
private

Definition at line 569 of file KTBNAdaptiveLearner.h.

Referenced by _applyConfig_(), state(), and useLocalSearchWithTabuList().

◆ _nbSamples_

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_nbSamples_
private

number of CSV files to read

Definition at line 518 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), KTBNAdaptiveLearner(), _forEachScoredNode_(), and learnKTBN().

◆ _noChildrenNodes_

template<GUM_Numeric GUM_SCALAR>
std::set< std::string > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_noChildrenNodes_
private

leaf nodes (no children), as engine names

Definition at line 619 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), _recomputeKMin_(), addNoChildrenNode(), eraseNoChildrenNode(), and state().

◆ _noParentNodes_

template<GUM_Numeric GUM_SCALAR>
std::set< std::string > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_noParentNodes_
private

root nodes (no parents), as engine names

Definition at line 616 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), _recomputeKMin_(), addNoParentNode(), eraseNoParentNode(), and state().

◆ _orderScore_

template<GUM_Numeric GUM_SCALAR>
OrderScoreType gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_orderScore_ {OrderScoreType::BIC}
private

recorded cross-k order-selection criterion (the outer score used by learnKTBN() to pick the best k; independent of score)

Definition at line 562 of file KTBNAdaptiveLearner.h.

Referenced by _orderSelectionScore_(), state(), useOrderScoreAIC(), useOrderScoreBIC(), and useOrderScorefNML().

◆ _possibleEdges_

template<GUM_Numeric GUM_SCALAR>
std::set< std::pair< std::string, std::string > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_possibleEdges_
private

MIIC candidate edges, as (tail, head) engine-name pairs.

Definition at line 598 of file KTBNAdaptiveLearner.h.

Referenced by _applyConstraints_(), _recomputeKMin_(), addPossibleEdge(), erasePossibleEdge(), and state().

◆ _prior_

template<GUM_Numeric GUM_SCALAR>
IBNLearner::BNLearnerPriorType gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_prior_ {IBNLearner::BNLearnerPriorType::NO_prior}
private

recorded prior and its weight

Definition at line 576 of file KTBNAdaptiveLearner.h.

Referenced by _applyConfig_(), checkScorePriorCompatibility(), state(), and useSmoothingPrior().

◆ _prior_bn_

template<GUM_Numeric GUM_SCALAR>
std::unique_ptr< BayesNet< GUM_SCALAR > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_prior_bn_
private

optional variable-schema BN (set by the BN constructor): when present, each per-k KTBNLearner is built from it so the variable domains are fixed explicitly instead of inferred from trajectory 1. Null in CSV mode.

Definition at line 551 of file KTBNAdaptiveLearner.h.

Referenced by KTBNAdaptiveLearner(), and learnKTBN().

◆ _priorWeight_

template<GUM_Numeric GUM_SCALAR>
double gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_priorWeight_ {1.0}
private

◆ _score_

template<GUM_Numeric GUM_SCALAR>
IBNLearner::ScoreType gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_score_ {IBNLearner::ScoreType::BDeu}
private

recorded per-k structure score (the inner score, replayed on each candidate)

Definition at line 558 of file KTBNAdaptiveLearner.h.

Referenced by _applyConfig_(), checkScorePriorCompatibility(), state(), useScoreAIC(), useScoreBD(), useScoreBDeu(), useScoreBIC(), useScorefNML(), useScoreLog2Likelihood(), and useScoreMDL().

◆ _scorePerCandidateK_

template<GUM_Numeric GUM_SCALAR>
std::vector< std::pair< Size, double > > gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_scorePerCandidateK_
private

per-candidate (k, order-score) pairs from the last learnKTBN() run, in ascending k. One entry appended per candidate; read by scorePerCandidateK(). Cleared at the start of each learnKTBN() (empty while bestK == 0).

Definition at line 634 of file KTBNAdaptiveLearner.h.

Referenced by learnKTBN(), and scorePerCandidateK().

◆ _tabuSize_

template<GUM_Numeric GUM_SCALAR>
Size gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::_tabuSize_ {100}
private

tabu-list parameters (meaningful when algo is LOCAL_SEARCH_WITH_TABU_LIST)

Definition at line 568 of file KTBNAdaptiveLearner.h.

Referenced by _applyConfig_(), state(), and useLocalSearchWithTabuList().

◆ C

template<GUM_Numeric GUM_SCALAR>
log_2 gum::learning::KTBNAdaptiveLearner< GUM_SCALAR >::C {r_i}_{N_{ij}}@f$

Select k by fNML (factorized Normalized Maximum Likelihood): keep the k whose learned model maximises .

Definition at line 279 of file KTBNAdaptiveLearner.h.


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