Commit 37c71af1 authored by Gaspard Ducamp's avatar Gaspard Ducamp

Merge branch 'bug/VariableFullNameInO3PRMBNReader' of...

Merge branch 'bug/VariableFullNameInO3PRMBNReader' of gitlab.com:agrumery/aGrUM into bug/VariableFullNameInO3PRMBNReader
parents 1867ee76 430bd3e8
......@@ -346,7 +346,7 @@ namespace gum {
// however, note that the nodes that received hard evidence do not belong to
// the graph and, therefore, should not be taken into account
const auto& hard_ev_nodes = this->hardEvidenceNodes();
for ( const auto node : this->allTargets() ) {
for ( const auto node : this->targets() ) {
if ( !__graph.exists( node ) && !hard_ev_nodes.exists( node ) ) return true;
}
for ( const auto& nodes : this->jointTargets() ) {
......@@ -412,7 +412,7 @@ namespace gum {
// the BN without altering the inference output
if ( __barren_nodes_type == FindBarrenNodesType::FIND_BARREN_NODES ) {
// identify the barren nodes
NodeSet target_nodes = this->allTargets();
NodeSet target_nodes = this->targets();
for ( const auto& nodeset : this->jointTargets() ) {
target_nodes += nodeset;
}
......@@ -999,7 +999,7 @@ namespace gum {
void ShaferShenoyInference<GUM_SCALAR>::__computeJoinTreeRoots() {
// get the set of cliques in which we can find the targets and joint_targets
NodeSet clique_targets;
for ( const auto node : this->allTargets() ) {
for ( const auto node : this->targets() ) {
try {
clique_targets.insert( __node_to_clique[node] );
} catch ( Exception& ) {
......@@ -1288,7 +1288,7 @@ namespace gum {
template <typename GUM_SCALAR>
INLINE void ShaferShenoyInference<GUM_SCALAR>::_makeInference() {
// collect messages for all single targets
for ( const auto node : this->allTargets() ) {
for ( const auto node : this->targets() ) {
// perform only collects in the join tree for nodes that have
// not received hard evidence (those that received hard evidence were
// not included into the join tree for speed-up reasons)
......
......@@ -149,7 +149,7 @@ namespace gum {
/// Clear all the previously defined marginal targets
virtual void eraseAllMarginalTargets() final;
/// Add a set of nodes as a new joint target
/// Add a set of nodes as a new joint target. As a collateral effect, every node is added as a marginal target.
/**
* @throw UndefinedElement if some node(s) do not belong to the Bayes net
*/
......
......@@ -91,10 +91,13 @@ namespace gum {
// Clear all previously defined targets (single targets and sets of targets)
template <typename GUM_SCALAR>
INLINE void JointTargetedInference<GUM_SCALAR>::eraseAllJointTargets() {
_onAllJointTargetsErased();
__joint_targets.clear();
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
if ( __joint_targets.size() > 0 ) {
// we already are in target mode. So no this->_setTargetedMode(); is needed
_onAllJointTargetsErased();
__joint_targets.clear();
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
}
......@@ -141,6 +144,7 @@ namespace gum {
if ( iter->isSubsetOf( joint_target ) ) eraseJointTarget( *iter );
}
this->_setTargetedMode(); // does nothing if already in targeted mode
__joint_targets.insert( joint_target );
_onJointTargetAdded( joint_target );
this->__state =
......@@ -169,6 +173,8 @@ namespace gum {
// check that the joint_target set does not contain the new target
if ( __joint_targets.contains( joint_target ) ) {
// note that we have to be in target mode when we are here
// so, no this->_setTargetedMode(); is necessary
_onJointTargetErased( joint_target );
__joint_targets.erase( joint_target );
this->__state =
......
......@@ -385,7 +385,7 @@ namespace gum {
// however, note that the nodes that received hard evidence do not belong to
// the graph and, therefore, should not be taken into account
const auto& hard_ev_nodes = this->hardEvidenceNodes();
for ( const auto node : this->allTargets() ) {
for ( const auto node : this->targets() ) {
if ( !__graph.exists( node ) && !hard_ev_nodes.exists( node ) ) return true;
}
for ( const auto& nodes : this->jointTargets() ) {
......@@ -452,7 +452,7 @@ namespace gum {
// altering the inference output
if ( __barren_nodes_type == FindBarrenNodesType::FIND_BARREN_NODES ) {
// identify the barren nodes
NodeSet target_nodes = this->allTargets();
NodeSet target_nodes = this->targets();
for ( const auto& nodeset : this->jointTargets() ) {
target_nodes += nodeset;
}
......@@ -968,7 +968,7 @@ namespace gum {
void LazyPropagation<GUM_SCALAR>::__computeJoinTreeRoots() {
// get the set of cliques in which we can find the targets and joint_targets
NodeSet clique_targets;
for ( const auto node : this->allTargets() ) {
for ( const auto node : this->targets() ) {
try {
clique_targets.insert( __node_to_clique[node] );
} catch ( Exception& ) {
......@@ -1347,7 +1347,7 @@ namespace gum {
template <typename GUM_SCALAR>
INLINE void LazyPropagation<GUM_SCALAR>::_makeInference() {
// collect messages for all single targets
for ( const auto node : this->allTargets() ) {
for ( const auto node : this->targets() ) {
// perform only collects in the join tree for nodes that have
// not received hard evidence (those that received hard evidence were
// not included into the join tree for speed-up reasons)
......
......@@ -59,9 +59,7 @@ namespace gum {
/// @{
/// default constructor
/** @warning By default (when the targets set is empty), all the nodes of
* the Bayes net are considered as targets. Once a first target is added to the
* set, the remaining nodes are not considered as default targets anymore.
/** @warning By default, all the nodes of the Bayes net are targets.
* @warning note that, by aGrUM's rule, the BN is not copied but only
* referenced by the inference algorithm. */
MarginalTargetedInference( const IBayesNet<GUM_SCALAR>* bn );
......@@ -121,12 +119,9 @@ namespace gum {
/// @{
/// Clear all previously defined targets
/// @warning this means that every node is now a target by default
virtual void eraseAllTargets();
/// adds all nodes as targets
/// @warning due to the semantic of targets, this function is an alias of
/// eraseAllTargets()
virtual void addAllTargets() final;
/// Add a marginal target to the list of targets
......@@ -143,17 +138,12 @@ namespace gum {
/// removes an existing (marginal) target
/** @warning If the target does not already exist, the method does nothing.
* In particular, it does not raise any exception.
* @warning Erasing the last target implies that every node is now a target by
* default.
* */
* In particular, it does not raise any exception. */
virtual void eraseTarget( const NodeId target ) final;
/// removes an existing (marginal) target
/** @warning If the target does not already exist, the method does nothing.
* In particular, it does not raise any exception.
* @warning Erasing the last target implies that every node is now a target by
* default.*/
* In particular, it does not raise any exception. */
virtual void eraseTarget( const std::string& nodeName ) final;
/// return true if variable is a (marginal) target
......@@ -162,22 +152,12 @@ namespace gum {
/// return true if variable is a (marginal) target
virtual bool isTarget( const std::string& nodeName ) const final;
/// returns the number of marginal targets.
//// @warning if the result is 0, it means that all the nodes are targets by
/// default.
/// returns the number of marginal targets
virtual const Size nbrTargets() const noexcept final;
/// returns the set of marginal targets
//// @warning if the set is empty, it means that all the nodes are targets by
/// default.
/// returns the list of marginal targets
virtual const NodeSet& targets() const noexcept final;
/// return all the marginal targets.
/** Particularly, if the targetSet is empty, allTargets will send a copy of the
* nodeSet of the BN
*/
virtual NodeSet allTargets() const noexcept final;
/// @}
// ############################################################################
......@@ -249,10 +229,16 @@ namespace gum {
/** @param id The variable's id. */
virtual const Potential<GUM_SCALAR>& _posterior( const NodeId id ) = 0;
protected:
void _setTargetedMode();
bool _isTargetedMode() const;
private:
/// whether the actual targets are default
bool __targeted_mode;
/// the set of marginal targets
NodeSet __targetsSet;
NodeSet __targets;
/// remove all the marginal posteriors computed
......
......@@ -39,8 +39,8 @@ namespace gum {
// sets all the nodes as targets
if ( bn != nullptr ) {
// just to be sure
__targetsSet.clear();
__targeted_mode = false;
__targets = bn->dag().asNodeSet();
}
GUM_CONSTRUCTOR( MarginalTargetedInference );
......@@ -58,6 +58,7 @@ namespace gum {
template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::_onBayesNetChanged(
const IBayesNet<GUM_SCALAR>* bn ) {
__targeted_mode = true;
__setAllMarginalTargets();
}
......@@ -75,15 +76,11 @@ namespace gum {
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the "
"inference algorithm" );
if ( !this->__bn->dag().exists( var ) ) {
GUM_ERROR( UndefinedElement, var << " is not a NodeId in the bn" );
}
if ( __targetsSet.empty() )
return true; // empty=>every node is a target by default
return __targetsSet.contains( var );
return __targets.contains( var );
}
// Add a single target to the list of targets
......@@ -98,7 +95,10 @@ namespace gum {
template <typename GUM_SCALAR>
INLINE void MarginalTargetedInference<GUM_SCALAR>::eraseAllTargets() {
_onAllMarginalTargetsErased();
__targetsSet.clear();
__targets.clear();
_setTargetedMode(); // does nothing if already in targeted mode
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
......@@ -117,9 +117,10 @@ namespace gum {
GUM_ERROR( UndefinedElement, target << " is not a NodeId in the bn" );
}
_setTargetedMode(); // does nothing if already in targeted mode
// add the new target
if ( !__targetsSet.contains( target ) ) {
__targetsSet.insert( target );
if ( !__targets.contains( target ) ) {
__targets.insert( target );
_onMarginalTargetAdded( target );
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
......@@ -136,18 +137,16 @@ namespace gum {
"No Bayes net has been assigned to the "
"inference algorithm" );
_setTargetedMode(); // does nothing if already in targeted mode
for ( auto target : this->__bn->dag() ) {
if ( !__targetsSet.contains( target ) ) {
__targetsSet.insert( target );
if ( !__targets.contains( target ) ) {
__targets.insert( target );
_onMarginalTargetAdded( target );
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
}
// now that we have added every needed targets, we clear __targetSet (every
// node is a target by default)
__targetsSet.clear();
}
......@@ -178,9 +177,12 @@ namespace gum {
GUM_ERROR( UndefinedElement, target << " is not a NodeId in the bn" );
}
if ( __targetsSet.contains( target ) ) {
if ( __targets.contains( target ) ) {
__targeted_mode = true; // we do not use _setTargetedMode because we do not
// want to clear the targets
_onMarginalTargetErased( target );
__targetsSet.erase( target );
__targets.erase( target );
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
......@@ -201,37 +203,27 @@ namespace gum {
}
// returns the list of single targets
template <typename GUM_SCALAR>
INLINE NodeSet MarginalTargetedInference<GUM_SCALAR>::allTargets() const
noexcept {
if ( __targetsSet.empty() ) {
return this->__bn->dag().asNodeSet();
} else {
return __targetsSet;
}
}
// returns the list of single targets
template <typename GUM_SCALAR>
INLINE const NodeSet& MarginalTargetedInference<GUM_SCALAR>::targets() const
noexcept {
return __targetsSet;
return __targets;
}
// returns the list of single targets
template <typename GUM_SCALAR>
INLINE const Size MarginalTargetedInference<GUM_SCALAR>::nbrTargets() const
noexcept {
return __targetsSet.size();
return __targets.size();
}
/// sets all the nodes of the Bayes net as targets
template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::__setAllMarginalTargets() {
__targetsSet.clear(); // every node is now target by default
__targets.clear();
if ( this->__bn != nullptr ) {
__targets = this->__bn->dag().asNodeSet();
_onAllMarginalTargetsAdded();
}
}
......@@ -340,4 +332,17 @@ namespace gum {
return evidenceImpact( bn.idFromName( target ), evsId );
}
template <typename GUM_SCALAR>
INLINE bool MarginalTargetedInference<GUM_SCALAR>::_isTargetedMode() const {
return __targeted_mode;
}
template <typename GUM_SCALAR>
INLINE void MarginalTargetedInference<GUM_SCALAR>::_setTargetedMode() {
if ( !__targeted_mode ) {
__targets.clear();
__targeted_mode = true;
}
}
} /* namespace gum */
......@@ -44,23 +44,25 @@ namespace gum_tests {
gum::BayesNet<double>::fastPrototype( "A->B->C->D;A->E->D;F->B;C->H;" );
gum::LazyPropagation<double> lazy( &bn );
TS_ASSERT(lazy.targets() == gum::NodeSet( {} ) );
TS_ASSERT( lazy.targets() == gum::NodeSet( {0, 1, 2, 3, 4, 5, 6} ) );
lazy.addTarget( "A" );
TS_ASSERT(lazy.targets() == gum::NodeSet( {0} ) );
TS_ASSERT( lazy.targets() == gum::NodeSet( {0} ) );
lazy.addTarget( "B" );
TS_ASSERT(lazy.targets() == gum::NodeSet( {0, 1} ) );
TS_ASSERT( lazy.targets() == gum::NodeSet( {0, 1} ) );
gum::ShaferShenoyInference<double> shafer( &bn );
TS_ASSERT( shafer.targets() == gum::NodeSet( {0, 1, 2, 3, 4, 5, 6} ) );
shafer.addTarget( "A" );
TS_ASSERT(shafer.targets() == gum::NodeSet( {0} ) );
TS_ASSERT( shafer.targets() == gum::NodeSet( {0} ) );
shafer.addTarget( "B" );
TS_ASSERT(shafer.targets() == gum::NodeSet( {0, 1} ) );
TS_ASSERT( shafer.targets() == gum::NodeSet( {0, 1} ) );
gum::VariableElimination<double> ve( &bn );
TS_ASSERT( ve.targets() == gum::NodeSet( {0, 1, 2, 3, 4, 5, 6} ) );
ve.addTarget( "A" );
TS_ASSERT(ve.targets() == gum::NodeSet( {0} ) );
TS_ASSERT( ve.targets() == gum::NodeSet( {0} ) );
ve.addTarget( "B" );
TS_ASSERT(ve.targets() == gum::NodeSet( {0, 1} ) );
TS_ASSERT( ve.targets() == gum::NodeSet( {0, 1} ) );
}
};
}
This diff is collapsed.
......@@ -130,7 +130,7 @@ class CSVGenerator:
bn = name_in
seq = bn.topologicalOrder()
writer = csv.writer(open(name_out, 'w'))
writer = csv.writer(open(name_out, 'w',newline=''))
if visible:
sys.stdout.flush()
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) Copyright by Pierre-Henri Wuillemin, UPMC, 2017 (pierre-henri.wuillemin@lip6.fr)
# (c) Copyright by Pierre-Henri Wuillemin, UPMC, 2017
# (pierre-henri.wuillemin@lip6.fr)
# Permission to use, copy, modify, and distribute this
# software and its documentation for any purpose and
......@@ -88,7 +89,8 @@ def BN2dot(bn, size="4", arcvals=None, vals=None, cmap=None, showValues=None):
minarcs = min(arcvals.values())
maxarcs = max(arcvals.values())
graph = dot.Dot(graph_type='digraph')
graph = dot.Dot(graph_type='digraph',bgcolor="transparent")
for n in bn.names():
if vals is None or n not in vals:
bgcol = "#444444"
......@@ -232,24 +234,24 @@ def BNinference2dot(bn, size="4",engine=None, evs={}, targets={}, format='png',
from tempfile import mkdtemp
temp_dir = mkdtemp("", "tmp", None) # with TemporaryDirectory() as temp_dir:
dotstr = "digraph structs {\n"
dotstr = "digraph structs {\n bgcolor=\"transparent\";"
dotstr += " label=\"Inference in {:6.2f}ms\";\n".format(1000 * (stopTime - startTime))
dotstr += " node [fillcolor=floralwhite, style=filled,color=grey];\n"
for n in bn.ids():
name = bn.variable(n).name()
for nid in bn.ids():
name = bn.variable(nid).name()
if vals is None or name not in vals:
bgcol = "sandybrown" if name in evs else "#FFFFFF"
if vals is None or name not in vals or nid not in vals:
bgcol = "sandybrown" if name in evs or nid in evs else "#FFFFFF"
fgcol = "#000000"
else:
bgcol = _proba2bgcolor(vals[name], cmap)
fgcol = _proba2fgcolor(vals[name], cmap)
colorattribute = 'fillcolor="{}", fontcolor="{}", color="#000000"'.format(bgcol, fgcol)
if len(targets) == 0 or name in targets:
if len(targets) == 0 or name in targets or nid in targets:
filename = temp_dir + name + "." + format
_saveFigProba(ie.posterior(n), filename, format=format)
_saveFigProba(ie.posterior(name), filename, format=format)
fill = ", " + colorattribute
dotstr += ' "{0}" [shape=rectangle,image="{1}",label="" {2}];\n'.format(name, filename, fill)
else:
......
......@@ -144,7 +144,9 @@ def getDot(dotstring, size="4", format="png"):
:param format: render as "png" or "svg"
:return: the HTML representation of the graph
"""
return getGraph(dot.graph_from_dot_data(dotstring), size, format)
g=dot.graph_from_dot_data(dotstring)
g.set_bgcolor("transparent")
return getGraph(g, size, format)
def showJunctionTree(bn, withNames=True, size="4", format="png"):
......@@ -637,18 +639,18 @@ def getInferenceEngine(ie, inferenceCaption):
t = '<div align="left"><ul>'
if ie.nbrHardEvidence() > 0:
t += "<li><b>hard evidence</b><br/>"
t += ", ".join([ie.BN().variable(n).name() for n in ie.hardEvidenceList()])
t += ", ".join([ie.BN().variable(n).name() for n in ie.hardEvidenceNodes()])
t += "</li>"
if ie.nbrSoftEvidence() > 0:
t += "<li><b>soft evidence</b><br/>"
t += ", ".join([ie.BN().variable(n).name() for n in ie.softEvidenceList()])
t += ", ".join([ie.BN().variable(n).name() for n in ie.softEvidenceNodes()])
t += "</li>"
if ie.nbrTargets() > 0:
t += "<li><b>target(s)</b><br/>"
if ie.nbrTargets() == ie.BN().size():
t += " all"
else:
t += ", ".join([ie.BN().variable(n).name() for n in ie.targetList()])
t += ", ".join([ie.BN().variable(n).name() for n in ie.targets()])
t += "</li>"
if hasattr(ie, 'nbrJointTargets'):
......
This diff is collapsed.
#!/usr/bin/env python3
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# pyAgrum documentation build configuration file, created by
......@@ -28,12 +28,15 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
import sys
import os
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
import sys
sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('../../../build/release/wrappers/'))
import gumDoc
extensions = [
'sphinx.ext.autodoc',
......@@ -41,9 +44,7 @@ extensions = [
'sphinx.ext.viewcode',
'sphinx.ext.coverage',
'sphinx.ext.napoleon'
]
# Napoleon settings
] # Napoleon settings
napoleon_google_docstring = True
napoleon_numpy_docstring = True
napoleon_include_private_with_doc = False
......@@ -73,7 +74,7 @@ master_doc = 'index'
# General information about the project.
project = 'pyAgrum'
copyright = '2016, aGrUM/pyAgrum Team'
copyright = '2017, aGrUM/pyAgrum Team'
author = 'Pierre-henri Wuillemin'
# The version info for the project you're documenting, acts as replacement for
......@@ -81,10 +82,11 @@ author = 'Pierre-henri Wuillemin'
# built documents.
#
import pyAgrum as gum
print("GUM VERSION ="+gum.__version__)
print("GUM VERSION =" + gum.__version__)
# The short X.Y version.
ma, mi, *_ = gum.__version__.split(".")
version = ma + "." + mi
ma, mi, pa, *_ = gum.__version__.split(".")
version = ma + "." + mi + "." + pa
# The full version, including alpha/beta/rc tags.
release = gum.__version__
......@@ -160,7 +162,7 @@ html_theme = 'classic'
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
#
html_title = project+" "+version+" documentation"
html_title = project + " " + version + " documentation"
# A shorter title for the navigation bar. Default is the same as html_title.
#
......@@ -230,7 +232,7 @@ html_static_path = ['_static']
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#
# html_show_copyright = True
html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
......@@ -252,7 +254,7 @@ html_static_path = ['_static']
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
#
# html_search_options = {'type': 'default'}
html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
......@@ -450,19 +452,9 @@ epub_exclude_files = ['search.html']
# epub_use_index = True
autodoc_member_order= 'bysource'
autodoc_member_order = 'bysource'
autoclass_content = 'both'
############################ TRANSLATER SWIG type #############
import re
......@@ -479,7 +471,7 @@ gumReplaceList = [
('std::', ''),
('const &', ' '),
('const *', ' '),
('\w+ self,','')
('\w+ self,', '')
]
dico = {re.escape(x): y for x, y in gumReplaceList}
pattern = re.compile('|'.join([re.escape(x) for x, _ in gumReplaceList]))
......@@ -488,11 +480,11 @@ pattern = re.compile('|'.join([re.escape(x) for x, _ in gumReplaceList]))
def substitution4swigautodoc(l):
if l is None:
return None
l1=l
l2=""
while l1!=l2:
l2=l1
l1=pattern.sub(lambda m: dico[re.escape(m.group(0))], l1)
l1 = l
l2 = ""
while l1 != l2:
l2 = l1
l1 = pattern.sub(lambda m: dico[re.escape(m.group(0))], l1)
return l1
......@@ -509,11 +501,24 @@ def process_signature(app, what, name, obj, options, signature, return_annotatio
return_annotation = substitution4swigautodoc(return_annotation)
return signature, return_annotation
def skip(app, what, name, obj, skip, options):
if name == "__init__":
return False
return skip
def skip(app, what, name, obj, skip, options):
exclusions = ('__weakref__', '__ne__', '__eq__', # special-members
'__doc__', '__module__', '__dict__', # undoc-members
'__swig_destroy__', # swig members
'clone', # special members
)
exclude = name in exclusions
if exclude:
print("####### {}.{} excluded ".format(obj,name))
return True
if skip:
return True
return None
autodoc_default_flags = ['members', 'private-members', 'special-members',
#'undoc-members','show-inheritance'
]
def setup(app):
app.connect('autodoc-process-docstring', process_docstring)
app.connect('autodoc-process-signature', process_signature)
......
import pyAgrum
pyAgrum.Arc.__doc__ = """
pyAgrum.Arc is the representation of an arc between two int : the head and the tail.
pyAgrum.Arc is the representation of an arc between two node represented by int : the head and the tail.
"""
pyAgrum.Arc.__init__.__doc__ = """
pyAgrum.Arc(tail,head)
Create an arc from two int.
:param head: the head
......
import pyAgrum
pyAgrum.DiscreteVariable.__doc__ = """
Discrete Variable cannot be instantiated but declare a common API for all discrete variables.
"""
pyAgrum.DiscreteVariable.__init__.__doc__ = None
Random Variables and Potentials
===============================
aGrUM/pyAgrum exclusively uses ploum ploum
Random Variables
----------------
.. autoclass:: pyAgrum.DiscreteVariable
......@@ -11,9 +13,6 @@ Random Variables
.. autoclass:: pyAgrum.DiscretizedVariable
.. autoclass:: pyAgrum.pyAgrum.DiscretizedVariable_double
:members:
.. autoclass:: pyAgrum.RangeVariable
:members:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment