aGrUM/pyAgrum 3.0.0 released
This major release brings three headline changes: the causal module is promoted from pure Python to a first-class C++
module (CM), structure learning is extended with PC, FCI (with PAG output), GreedyThickThinning, and triangle
deletions in GreedyHillClimbing, and a new native GUM serialization format (jgum / bgum) is introduced for all
graphical models. It also consolidates widespread API modernisation (C++20 std::format, string_view, optional_ref,std::optional, concepts) and several breaking renames detailed below.
pyAgrum
- Breaking API:
- Graph path-finding functions
undirectedPath,directedPath,directedUnorientedPath,mixedOrientedPath,mixedUnorientedPathnow returnNoneinstead of raisingNotFound(or returning[])
when no path exists. - Causal module renames:
CausalModel.observedBN()→observationalBN();CausalModel.addLatentVariable(..., keepArcs=...)parameterkeepArcsrenamed toassumeNonSpurious;CausalModel.backDoor()/frontDoor()returnNoneinstead of raising when no valid set
exists (set()when the empty set is valid);DoorCriteria'sEnumerationOptions
removed (optionsexcluded_nodes,max_cardinality,only_minimal,stopAtFirstare now direct keyword
parameters, all methods now static);CausalImpactdirect access toresultremoved (useimpact());Counterfactual.getResult()renamedimpact();DSeparationrenamedSeparation. NodeIdandNameOrIdtype aliases removed frompyagrum.ctbnandpyagrum.clg(useintandint | str)._gum_add_properties_while_getstate_removed; pickle metadata now handled byupdateMetaData()
(pickled objects from earlier versions may not unpickle correctly).BNClassifiernow requires aDiscreteTypeProcessorconstructor parameter;createBNClassifier
signature changed accordingly; binary prediction dispatch andpredict_probaupdated;model()
method added (returns a copy of the underlying BN).
- Graph path-finding functions
- Causal Module:
- Added SWIG Python bindings for the C++ causal module (
CausalModel,CausalFormula,DoorCriteria,Counterfactual, ...). - Refactored
causalEffectEstimationas a top-level subpackage. - Fixed type references in docstrings (
pyagrum.causal.CausalModel→pyagrum.CausalModel) and restructured
the causality section in the Sphinx documentation. - Updated causality notebooks; added
causal2graphutility for causal graph visualization; added AST printing
forCausalImpactresults.
- Added SWIG Python bindings for the C++ causal module (
- Structure Learning (FCI / PAG):
- Added SWIG bindings for
PAG(Partial Ancestral Graph) and the FCI (Fast Causal Inference)
algorithm. - Exposed
BNLearner.setAlgorithmFCI(),fciExhaustiveSepSet()/setFCIExhaustiveSepSet(). - Added documentation and test suite for PAG/FCI.
- Added SWIG bindings for
- Native GUM Format (jgum / bgum):
- Added
saveGUM(),loadGUM(),saveGUMstring(),loadGUMstring()toBayesNet,InfluenceDiagram, andMarkovRandomField. - Added SWIG type mapping for
optional<vector<NodeId>>. - Added
GumFormatTestSuitecovering jgum/bgum round-trips and string serialization. - Added Sphinx page
jgum-bgum-format.rstand notebook 91-Tools-LoadAndSaveGraphicalModels
illustrating all I/O formats.
- Added
- qBNSampling (experimental, thanks to Tibor Dubois, Thierry Rioual, Mehmet Gunes):
- New
pyagrum.qBNSamplingmodule: quantum circuit encoding of Bayesian Networks and rejection-sampling
inference.
- New
- CLG (Conditional Linear Gaussian):
- Added
CLG.asDiscreteBN()to convert a CLG model to a discretized BN. - Added
CLG.__eq__,__getstate__,__setstate__(pickle support). - New
CLGModelTestSuiteand extendedCLGInference/SEM/Sampling/Randomtest suites. randomCLGgainsmax_parentsandratio_arcparameters;GaussianVariablesigma guard added (thanks to
Ima Bernada).
- Added
- BNClassifier & skbn (thanks to Lou Toubiana):
- Added
model()method returning a copy of the underlying BN; full coverageBNClassifierTestSuite. - Refactored
skbnfor full sklearn API compliance:ClassifierMixinplaced beforeBaseEstimatorin MRO, fitted attributes renamed to the trailing-underscore convention (bn_,threshold_,target_, ...),validate_data()used for input validation infit,predict, andpredict_proba. fit(X, y)signature is now positional and strictly sklearn-compliant; the oldfit(X=None, y=None, data=None, targetName=None)form is removed.- Fixed pandas 2.x compatibility (
Xcast toobjectdtype before processing infit) and suppressed a
spurious sklearn'X does not have valid feature names'warning inpredict/predict_proba.
- Added
- StructuralMetrics:
- Exposed
StructuralMetrics(formerlyStructuralComparator) with SHD, tp/fp/fn/tn accessors and SID
(Structural Intervention Distance) for BN comparison. - Updated
GraphicalBNComparatorto delegate toStructuralMetrics; addedstructuralFScore.
- Exposed
- Tensor & Numpy:
Tensormethodsrandom(),randomDistribution(),randomCPT(),noising()now returnself
for chaining.- Added Python bindings for
mean(),variance(),stdDev(),isNumerical(). - Numpy interop: new
as_nparray(),toarray(), andfillWith(ndarray)methods; optimizedTensornumpy access with zero-copy__getitem__andmemcpy-based__setitem__(numpy >= 1.7required).
- Graph API:
- Exposed
nameFromId(),idFromName(),setName(),hasName()on all graph types (DiGraph,DAG,MixedGraph, ...). - Added
connectedComponents()(returnsdict[int, int]),connectedComponentsList(), andconnectedComponentsCount(). - Fixed missing
descendants()/ancestors()onDiGraph;NodeSet,ArcSet,EdgeSetnow use dedicated
typemaps.
- Exposed
- Documentation:
- Added sentinel typedefs to replace
-> objectwith precise Python return type annotations in generated
bindings. - Added
%feature(docstring)entries for all 2174 methods; docstrings follow NumPy format (100% docstring
coverage).
- Added sentinel typedefs to replace
- Performance & Infrastructure:
- Introduced
PYTHONIZED_MARGINALSmacro and global numpy import for generated inference code. - Lazy-import of
pandasviaTYPE_CHECKING(~240 ms saved on import time). - Added
-fvisibility=hidden:_pyagrum.soreduced from 16.8 MB to 12.9 MB (−23 %). - Added full type annotations to all pyLibs (
lib/,clg/,skbn/,bnmixture/,ctbn/,causalEffectEstimation/); added inference type aliasesBNInference,MRFInference,CNInference; replacedmypywith pyrefly inact guideline, fixing all type errors across pyLibs;
addedMatrixLike/ArrayLiketype aliases to__init__.in.py. BNMixture: manifest-basedsaveBNM/loadBNM,loadRetroCompatibleBNMfor backward compatibility; fixedsaveBNM/loadBNMon Windows (colons in BN names).explain(ShAP / SHALL): API improvements, causal SHAP fix, binary BN test resources added; fixed
uninitialized array in_labelToPos(np.empty→np.zeros).- Rewritten
ipython.py, newjt2graph.py, fixedprepareDotfontcolor; fixedhtml2image
issues in notebook contexts and improved export cropping. act install: support no-make mode viacmake --install;--onlyflag (alias for--build no-make).act test pyAgrum: persistent--test_build_pathoption. FixedfastPrototype
docstring separator; removed uselessnewFactorymethods.
- Introduced
- Breaking API:
aGrUM
- Breaking API:
- Graph path-finding functions
directedPath,directedUnorientedPath,undirectedPath,mixedOrientedPath,mixedUnorientedPathnow returnstd::optional<std::vector<NodeId>>(nulloptwhen no path exists), forDiGraph,UndiGraph,MixedGraph,PDAG,CliqueGraph, and allGUM_DiGraphable/GUM_UndiGraphable/GUM_MixedGraphablegraphs. - Causal module renames:
CausalModel::observedBN()→observationalBN();CausalModel::addLatentVariable(..., keepArcs=...)parameterkeepArcsrenamed toassumeNonSpurious;CausalModel::backDoor()/frontDoor()return typeNodeSet→std::optional<NodeSet>(nullopt= no valid set,{}= empty set is valid);DoorCriteria'sEnumerationOptionsstruct removed (options are now direct parameters, all methods nowstatic),DoorCriteria::nodesOnDirectedPaths(dag, X, Y)return typeNodeSet→std::optional<NodeSet>;CausalImpactdirect access toresultremoved (useimpact());Counterfactual<GUM_ELEMENT>template parameter renamed fromGUM_SCALAR,getResult()renamedimpact();DSeparation(inCM/tools/) renamedSeparation. HashTable<Key,Val>::tryGet(key)and related methods (tryFirst,trySecond,tryPos) now returnoptional_ref<Val>/optional_ref<const Val>instead ofVal*/const Val*
(nullptrif absent).gum::optional_ref<T>behaves likestd::optionalfor references (C++26 feature
backported); callers usingif (auto* p = table.tryGet(key))must switch toif (auto ref = table.tryGet(key)).Signaler1<A>,Signaler2<A,B>,Signaler3<A,B,C>, ... removed; use variadicSignaler<A>,Signaler<A,B>,Signaler<A,B,C>, ... instead.- Widespread
string_viewmigration:const std::string¶meters replaced bystd::string_viewacross the public API (BayesNet, variables, I/O readers, learning, ...); passingstd::stringor string literals remains compatible. - I/O writers'
write()no longerconst:BNWriter<GUM_SCALAR>::write()(and all subclass writers, includingGumBNWriter) now takes the BN by non-constreference, to allow writers to callbn.updateMetaData()
before serialization;CredalNet::saveBNsMinMax()is similarly affected. - New base class
DiscreteGraphicalModel:IBayesNetandIMarkovRandomFieldnow inherit from it, which
factors five variable-map accessors (variable,variableNodeMap,nodeId,idFromName,existsInModel) previously duplicated in each interface; direct subclasses must no longer
define those accessors themselves. DiscreteVariable::closestLabelis now virtual (ABI change: recompilation required for any code linking
against aGrUM as a shared library).DAGmodel::dag()andUGmodel::graph()now return value copies (with node names propagated), notconst
references; useinternalDag()/internalGraph()for the O (1) stableconst
reference when graph mutation through the model API is not needed.StructuralComparatorrenamedStructuralMetrics(update all include paths and type names accordingly).
- Graph path-finding functions
- Structure Learning:
- Added the
FCI(Fast Causal Inference) algorithm producing aPAG(Partial Ancestral Graph)
from data; integrated intoIBNLearner/BNLearner(setAlgorithmFCI); fixedpossibleDSep
criterion (Zhang 2008); added exhaustive sepset mode (setFCIExhaustiveSepSet); enforced background knowledge
in orientation rules (R1/R2/R9/R10). - Added the
PCconstraint-based structure learning algorithm, integrated intoIBNLearner/BNLearneralongside Miic. - Added the
GreedyThickThinningscore-based structure learning algorithm, integrated intoIBNLearner/BNLearner. - Extended
GreedyHillClimbingwith arc-triangle deletion operations:GraphChangesSelector4DiGraphnow supportsapplyArcDeletion,applyArcReversal,applyTriangleDeletion;LocalSearchWithTabuListupdated;totalOrderconstraint added. - Independence tests refactoring: extracted
CachedContingencyCounterbase class from Chi2 and G2
implementations;IndependenceTest::statistics()made pure virtual (overridden inIndepTestChi2andIndepTestG2); added silent-cell df correction in Chi2/G2 tests; fixed G2 df for sampling
zeros; newChi2TestSuite. ConstraintBasedLearningrefactoring: extractedConstraintBasedLearningbase class from Miic; extractedCIBasedLearningbase class adding scorer-agnostic API (learnPDAG/learnDAG/learnBN); CMI types and
comparators moved to Miic;setMutualInformation()injector added;applyStructuralConstraints_factored intoConstraintBasedLearning; renamedscores_and_tests/directory toscores/.
- Added the
- Causal Module (CM) Development (thanks to SCALNYX):
- Promoted the causal module from pure Python to a first-class C++ module.
- Introduced
CausalModelandCausalFormula. - Developed an Abstract Syntax Tree (AST) for do-calculus, including LaTeX export and evaluation.
- Added the
DoorCriteriaclass for backdoor and frontdoor set enumeration. - Implemented ID/IDC algorithms and formula introspection.
- Added
counterfactualandcounterfactualModelfunctions with associated tests.
- Native GUM Format (jgum / bgum):
- Added
GumBNReader/GumBNWriter,GumIDReader/GumIDWriter,GumMRFReader/GumMRFWriter
supporting both JSON (.jgum) and binary (.bgum) serialization. - All GUM readers support
proceedFromString()and a no-filename constructor for in-memory round-trips. - Extracted
_readVector_/_writeVector_helpers toGumBinaryIO.h. - Fixed empty-BN jgum serialization; fixed binary writers to open files with
ios::binary; fixedIDReader::proceed()return type (void→Size).
- Added
- Modeling & Core API:
- Added optional node name support to
NodeGraphPart:nameFromId(),idFromName(),setName(),hasName(); names propagated totoDot()output (format:id:name);checkConsistency()made public,frienddeclarations for test suites removed;GraphicalModel::_nameNodes_()propagates node names to returned graphs (moralGraph(),moralizedAncestralGraph(),EssentialGraph::pdag()/skeleton(),MarkovBlanket::dag()). - Introduced
DiscreteGraphicalModelto factorize variable management acrossIBayesNetandIMarkovRandomField. - Added
connectedComponents()toDAGmodelandUGmodel, with C++ and Python tests for BN, ID, MRF; addeddescendants()andancestors()toMarkovBlanketandEssentialGraph. - Replaced nullable pointers with
optional_ref<T>and implementedstd::optionalin various interfaces; added
adata()method toMultiDimArrayfor contiguous buffer access. - Made
DiscreteVariable::closestLabel(double)virtual; addedDiscreteVariable::isNumerical()
(returnstrueiffvarType != LABELIZED). - Added
Tensor::mean(),variance(),stdDev()(fixes variance computation: wasE[X²], nowE[(X−μ)²]); addedisCloseToZero()/isCloseToOne()helpers used in these methods;Tensor::toStringnow uses Unicode box-drawing characters (│ ║ ─) for table borders. StructuralMetrics(formerlyStructuralComparator): added SHD metrics with tp/fp/fn/tn accessors; added SID
(Structural Intervention Distance) for DAG-vs-DAG andBayesNetoverload; name-based alignment for BN
compare/SID.BIFXMLBNReaderimprovements (thanks to Omi Johnson): addedstd::istreamconstructor for in-memory parsing;
now reads the networkNAMEproperty from BIF/XML files.- C++20 graph concepts: added
GUM_DiGraphable,GUM_UndiGraphable,GUM_MixedGraphableconcepts for
graph-agnostic programming; added generic path/reachability/cycle algorithms operating on any
concept-satisfying graph type; added generic moralization and separation algorithms (DAG/PDAG
methods now delegate); added genericBayesBallalgorithm (dSeparatedandBayesBall::requisiteNodesdelegate); promotedminimalCondSet,markovBlanket,areConnected
to the generic graph layer. CNmodule: fixed critical bugs (invaliddelete[]onstrtokpointer,setCPTconst-ref signature,insertEvidenceFileoverride placement, operator precedence inLrsWrapperguards); fixed naming convention
violations (protected attributes renamed to trailing-underscore convention).
- Added optional node name support to
- Code Quality & Static Analysis:
- Replaced
std::stringstreamwithstd::formatacross all modules; addedoverridespecifier to all virtual
method overrides; added[[nodiscard]]toclone()and factory methods; normalized include guards to theGUM_SOMETHING_Hconvention; added parent#includein_inl.h/_tpl.h
files for IDE LSP support. - Integrated
clang-tidyintoact guideline(check tidy/--correctionapplies fixes); a DeepSeek
static-analysis audit fixed all CRIT/HIGH/MED/LOW issues across the codebase;clang-formatapplied to C++ test suites and BN learning sources; fixednoexceptonIndepTestChi2/G2moves and braced-init returns. - Portability: fixed
int2Powto useuint64_tfor portable 64-bit shift on Windows; fixed GCC 16 warnings
(-Warray-boundspragmas,gum::Sizecasts for signed/unsigned comparisons); fixed GCCoptimizepragma guard against Clang inBNLearner; fixed-Wextra-semiandextern template
SWIG warnings; fixed Windows compilation issues (binary writers, CI uninstall). - Learning:
MeekRulesimprovements; fixedpropagateToCPDAG(restored edges-before-arcs insertion order in
PDAG); fixedArcDeletionbug inGraphChangesSelector4DiGraph;BayesBall
(_bayesBall_) replaced theexists+insert+[]pattern withgetWithDefault, plus 9 deterministic tests. - Migrated the test framework from CxxTest to doctest (updated from 2.4.12 to 2.5.2, suppressed
-Wc2y-extensions); replacedGUM_CHECK_*macros withCHECK_*across all test suites; replaced deprecatedtmpnamwith agetTempFilePathhelper across all test suites; addedLpInterface/LrsWrappertests and
marginal sanity checks; removed impropertry/catch
logic, replacing it with explicit existence checks; optimized Coco/R parser performance; fixed various MSVC
compilation issues and name lookup errors (notably regardinggum::Arc). - Added move constructors and move assignment operators across the class hierarchy; fixed GUM debug macros and
the atexit table. - CMake: removed uninstall target and obsolete policies;
AVLTreemoveoperator=no longernoexcept(containsGUM_ERROR).
- Replaced
- Build & Tooling:
act:--statsflag for project stats;--consolidatesplit;cm.handbase/ioadded to the dependency
map;act guidelinegains--dry-run,--checkwith+/-syntax, non-persistent--verbose.
- Breaking API: