74 template <
typename GUM_SCALAR >
76 const std::string& node,
77 const std::string& default_domain) {
82 res = mn.idFromName(v->name());
83 }
catch (gum::NotFound&) { res = mn.add(*v); }
87 template <
typename GUM_SCALAR >
88 MarkovRandomField< GUM_SCALAR >
89 MarkovRandomField< GUM_SCALAR >::fastPrototype(
const std::string& dotlike, Size domainSize) {
90 return fastPrototype(dotlike,
"[" + std::to_string(domainSize) +
"]");
93 template <
typename GUM_SCALAR >
94 MarkovRandomField< GUM_SCALAR >
95 MarkovRandomField< GUM_SCALAR >::fastPrototype(
const std::string& dotlike,
96 const std::string& domain) {
97 MarkovRandomField< GUM_SCALAR > mn;
102 for (
auto& node:
split(clikchain,
"--")) {
108 mn.generateFactors();
109 mn.setProperty(
"name",
"fastPrototype");
113 template <
typename GUM_SCALAR >
114 MarkovRandomField< GUM_SCALAR >
116 MarkovRandomField< GUM_SCALAR > mn;
117 for (
NodeId nod: bn.nodes()) {
118 mn.add(bn.variable(nod), nod);
120 mn.beginTopologyTransformation();
121 for (
NodeId nod: bn.nodes()) {
122 mn.addFactor(bn.cpt(nod));
124 mn.endTopologyTransformation();
125 mn.setProperty(
"name", bn.propertyWithDefault(
"name",
"noname"));
129 template <
typename GUM_SCALAR >
130 INLINE MarkovRandomField< GUM_SCALAR >::MarkovRandomField() :
132 GUM_CONSTRUCTOR(MarkovRandomField);
135 template <
typename GUM_SCALAR >
136 INLINE MarkovRandomField< GUM_SCALAR >::MarkovRandomField(std::string name) :
137 IMarkovRandomField< GUM_SCALAR >(name), _topologyTransformationInProgress_(false) {
138 GUM_CONSTRUCTOR(MarkovRandomField);
141 template <
typename GUM_SCALAR >
142 MarkovRandomField< GUM_SCALAR >::MarkovRandomField(
143 const MarkovRandomField< GUM_SCALAR >& source) :
144 IMarkovRandomField< GUM_SCALAR >(source), _topologyTransformationInProgress_(false),
145 _varMap_(source._varMap_) {
146 GUM_CONS_CPY(MarkovRandomField);
147 _copyFactors_(source);
150 template <
typename GUM_SCALAR >
151 MarkovRandomField< GUM_SCALAR >&
152 MarkovRandomField< GUM_SCALAR >::operator=(
const MarkovRandomField< GUM_SCALAR >& source) {
153 if (
this != &source) {
154 IMarkovRandomField< GUM_SCALAR >::operator=(source);
155 _varMap_ = source._varMap_;
156 _topologyTransformationInProgress_ =
false;
157 _copyFactors_(source);
163 template <
typename GUM_SCALAR >
164 MarkovRandomField< GUM_SCALAR >::~MarkovRandomField() {
166 GUM_DESTRUCTOR(MarkovRandomField);
169 template <
typename GUM_SCALAR >
170 INLINE
const DiscreteVariable& MarkovRandomField< GUM_SCALAR >::variable(NodeId
id)
const {
171 return _varMap_.get(
id);
174 template <
typename GUM_SCALAR >
175 INLINE
void MarkovRandomField< GUM_SCALAR >::changeVariableName(NodeId
id,
176 const std::string& new_name) {
177 _varMap_.changeName(
id, new_name);
180 template <
typename GUM_SCALAR >
181 INLINE
void MarkovRandomField< GUM_SCALAR >::changeVariableLabel(NodeId
id,
182 const std::string& old_label,
183 const std::string& new_label) {
184 if (variable(
id).varType() != VarType::LABELIZED) {
187 LabelizedVariable* var
188 =
dynamic_cast< LabelizedVariable*
>(
const_cast< DiscreteVariable*
>(&variable(
id)));
190 var->changeLabel(var->posLabel(old_label), new_label);
193 template <
typename GUM_SCALAR >
194 INLINE NodeId MarkovRandomField< GUM_SCALAR >::nodeId(
const DiscreteVariable& var)
const {
195 return _varMap_.get(var);
198 template <
typename GUM_SCALAR >
199 const Tensor< GUM_SCALAR >& MarkovRandomField< GUM_SCALAR >::factor(
const NodeSet& varIds)
const {
200 return *_factors_[varIds];
203 template <
typename GUM_SCALAR >
204 const NodeSet& MarkovRandomField< GUM_SCALAR >::smallestFactorFromNode(NodeId node)
const {
206 Size smallest = size() + 1;
207 for (
const auto& kv: factors()) {
208 const auto& fact = kv.first;
209 if (fact.contains(node))
210 if (smallest > fact.size()) {
212 smallest = fact.size();
215 if (res ==
nullptr) {
222 template <
typename GUM_SCALAR >
223 const Tensor< GUM_SCALAR >&
224 MarkovRandomField< GUM_SCALAR >::factor(
const std::vector< std::string >& varnames)
const {
225 return factor(this->nodeset(varnames));
228 template <
typename GUM_SCALAR >
229 const FactorTable< GUM_SCALAR >& MarkovRandomField< GUM_SCALAR >::factors()
const {
233 template <
typename GUM_SCALAR >
234 INLINE NodeId MarkovRandomField< GUM_SCALAR >::add(
const std::string& fast_description,
235 unsigned int default_nbrmod) {
236 auto v = fastVariable< GUM_SCALAR >(fast_description, default_nbrmod);
241 template < typename GUM_SCALAR >
242 INLINE
void MarkovRandomField< GUM_SCALAR >::_rebuildGraph_() {
243 if (_topologyTransformationInProgress_)
return;
245 this->graph_.clearEdges();
247 for (
const auto& kv: _factors_) {
248 auto& c = *kv.second;
249 for (Idx i = 0; i < c.nbrDim(); i++)
250 for (Idx j = i + 1; j < c.nbrDim(); j++)
251 this->graph_.addEdge(_varMap_.get(c.variable(i)), _varMap_.get(c.variable(j)));
255 template <
typename GUM_SCALAR >
256 INLINE NodeId MarkovRandomField< GUM_SCALAR >::add(
const DiscreteVariable& var) {
260 template <
typename GUM_SCALAR >
261 INLINE NodeId MarkovRandomField< GUM_SCALAR >::add(
const DiscreteVariable& var, NodeId
id) {
262 _varMap_.insert(
id, var);
263 this->graph_.addNodeWithId(
id);
267 template <
typename GUM_SCALAR >
268 INLINE NodeId MarkovRandomField< GUM_SCALAR >::idFromName(
const std::string& name)
const {
269 return _varMap_.idFromName(name);
272 template <
typename GUM_SCALAR >
273 INLINE
const DiscreteVariable&
274 MarkovRandomField< GUM_SCALAR >::variableFromName(
const std::string& name)
const {
275 return _varMap_.variableFromName(name);
278 template <
typename GUM_SCALAR >
279 INLINE
const VariableNodeMap& MarkovRandomField< GUM_SCALAR >::variableNodeMap()
const {
283 template <
typename GUM_SCALAR >
284 INLINE
void MarkovRandomField< GUM_SCALAR >::erase(
const DiscreteVariable& var) {
285 erase(_varMap_.get(var));
288 template <
typename GUM_SCALAR >
289 INLINE
void MarkovRandomField< GUM_SCALAR >::erase(
const std::string& name) {
290 erase(idFromName(name));
293 template <
typename GUM_SCALAR >
294 void MarkovRandomField< GUM_SCALAR >::erase(NodeId varId) {
296 _varMap_.erase(varId);
297 this->graph_.eraseNode(varId);
299 std::vector< NodeSet > vs;
300 for (
const auto& kv: _factors_) {
301 if (kv.first.contains(varId)) { vs.push_back(kv.first); }
303 for (
const auto& ns: vs) {
306 for (
const auto& ns: vs) {
309 if (nv.size() > 1) addFactor(nv);
314 template <
typename GUM_SCALAR >
315 void MarkovRandomField< GUM_SCALAR >::clear() {
316 if (!this->empty()) {
317 auto l = this->nodes();
318 for (
const auto no: l) {
325 template <
typename GUM_SCALAR >
326 INLINE std::ostream&
operator<<(std::ostream& output,
const MarkovRandomField< GUM_SCALAR >& mn) {
327 output << mn.toString();
331 template <
typename GUM_SCALAR >
332 Tensor< GUM_SCALAR >&
333 MarkovRandomField< GUM_SCALAR >::_addFactor_(
const std::vector< NodeId >& ordered_nodes) {
335 for (
auto node: ordered_nodes)
340 if (_factors_.exists(vars)) {
344 Tensor< GUM_SCALAR >* factor =
new Tensor< GUM_SCALAR >();
346 for (
auto node: ordered_nodes) {
347 factor->add(variable(node));
350 _factors_.insert(vars, factor);
356 template <
typename GUM_SCALAR >
357 INLINE
const Tensor< GUM_SCALAR >&
358 MarkovRandomField< GUM_SCALAR >::addFactor(
const NodeSet& vars) {
360 std::vector< NodeId > sorted_nodes;
361 for (
auto node: vars) {
362 sorted_nodes.push_back(node);
364 std::sort(sorted_nodes.begin(), sorted_nodes.end());
366 return _addFactor_(sorted_nodes);
369 template <
typename GUM_SCALAR >
370 INLINE
const Tensor< GUM_SCALAR >&
371 MarkovRandomField< GUM_SCALAR >::addFactor(
const std::vector< std::string >& varnames) {
372 std::vector< NodeId > sorted_nodes;
373 for (
const auto& v: varnames) {
374 sorted_nodes.push_back(idFromName(v));
377 return _addFactor_(sorted_nodes);
380 template <
typename GUM_SCALAR >
381 INLINE
const Tensor< GUM_SCALAR >&
382 MarkovRandomField< GUM_SCALAR >::addFactor(
const Tensor< GUM_SCALAR >& factor) {
383 std::vector< NodeId > sorted_nodes;
384 for (Idx i = 0; i < factor.nbrDim(); i++) {
385 sorted_nodes.push_back(idFromName(factor.variable(i).name()));
387 auto& res = _addFactor_(sorted_nodes);
388 res.fillWith(factor);
393 template <
typename GUM_SCALAR >
394 INLINE
void MarkovRandomField< GUM_SCALAR >::generateFactors()
const {
395 for (
const auto& elt: _factors_) {
396 elt.second->random();
400 template <
typename GUM_SCALAR >
401 INLINE
void MarkovRandomField< GUM_SCALAR >::generateFactor(
const NodeSet& vars)
const {
402 _factors_[vars]->random();
405 template <
typename GUM_SCALAR >
406 INLINE
void MarkovRandomField< GUM_SCALAR >::eraseFactor(
const NodeSet& vars) {
407 if (_factors_.exists(vars)) {
415 template <
typename GUM_SCALAR >
417 MarkovRandomField< GUM_SCALAR >::eraseFactor(
const std::vector< std::string >& varnames) {
418 auto vars = this->nodeset(varnames);
419 if (_factors_.exists(vars)) {
427 template <
typename GUM_SCALAR >
428 INLINE
void MarkovRandomField< GUM_SCALAR >::_eraseFactor_(
const NodeSet& vars) {
429 delete _factors_[vars];
430 _factors_.erase(vars);
433 template <
typename GUM_SCALAR >
434 void MarkovRandomField< GUM_SCALAR >::_clearFactors_() {
435 for (
const auto& kv: _factors_) {
442 template <
typename GUM_SCALAR >
443 void MarkovRandomField< GUM_SCALAR >::_copyFactors_(
444 const MarkovRandomField< GUM_SCALAR >& source) {
446 for (
const auto& pf: source.factors()) {
447 addFactor(*pf.second);
452 template <
typename GUM_SCALAR >
453 INLINE
void MarkovRandomField< GUM_SCALAR >::beginTopologyTransformation() {
454 _topologyTransformationInProgress_ =
true;
457 template <
typename GUM_SCALAR >
458 INLINE
void MarkovRandomField< GUM_SCALAR >::endTopologyTransformation() {
459 if (_topologyTransformationInProgress_) {
460 _topologyTransformationInProgress_ =
false;
Class representing Markov random fields.
Class representing a Bayesian network.
Class representing the minimal interface for Markov random field.
Exception: at least one argument passed to a function is not what was expected.
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
void insert(const Key &k)
Inserts a new element into the set.
void erase(const Key &k)
Erases an element from the set.
#define GUM_ERROR(type, msg)
Size NodeId
Type for node ids.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
std::string remove_newline(const std::string &s)
remove all newlines in a string
std::vector< std::string > split(const std::string &str, const std::string &delim)
Split str using the delimiter.
class for LOGIT implementation as multiDim
class for NoisyAND-net implementation as multiDim
class for multiDimNoisyORCompound
class for NoisyOR-net implementation as multiDim
NodeId nextNodeId()
Returns the next value of an unique counter for PRM's node id.
gum is the global namespace for all aGrUM entities
std::unique_ptr< DiscreteVariable > fastVariable(std::string var_description, Size default_domain_size)
Create a pointer on a Discrete Variable from a "fast" syntax.
NodeId build_node_for_MN(MarkovRandomField< GUM_SCALAR > &mn, const std::string &node, const std::string &default_domain)
Abstract class for generating Conditional Probability Tables.
std::ostream & operator<<(std::ostream &out, const TiXmlNode &base)
Utilities for manipulating strings.