aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
utils_prm_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 #include <agrum/PRM/utils_prm.h>
23 
24 namespace gum {
25  namespace prm {
26 
27  template < typename GUM_SCALAR >
30  const Potential< GUM_SCALAR >& source) {
31  const MultiDimImplementation< GUM_SCALAR >* impl = source.content();
32  Potential< GUM_SCALAR >* p = 0;
33 
34  try {
35  if (dynamic_cast< const MultiDimReadOnly< GUM_SCALAR >* >(impl)) {
36  if (dynamic_cast< const MultiDimNoisyORCompound< GUM_SCALAR >* >(impl)) {
37  p = new Potential< GUM_SCALAR >(new MultiDimNoisyORCompound< GUM_SCALAR >(
38  bij,
39  static_cast< const MultiDimNoisyORCompound< GUM_SCALAR >& >(*impl)));
40  } else if (dynamic_cast< const MultiDimNoisyORNet< GUM_SCALAR >* >(impl)) {
41  p = new Potential< GUM_SCALAR >(new MultiDimNoisyORNet< GUM_SCALAR >(
42  bij,
43  static_cast< const MultiDimNoisyORNet< GUM_SCALAR >& >(*impl)));
44  } else if (dynamic_cast< const aggregator::MultiDimAggregator< GUM_SCALAR >* >(impl)) {
45  p = new Potential< GUM_SCALAR >(
46  static_cast< MultiDimImplementation< GUM_SCALAR >* >(impl->newFactory()));
47 
48  for (auto var: impl->variablesSequence())
49  p->add(*(bij.second(var)));
50  } else if (dynamic_cast< const MultiDimBucket< GUM_SCALAR >* >(impl)) {
51  // This is necessary just to prevent non initialized arrays
52  const_cast< MultiDimBucket< GUM_SCALAR >* >(
53  static_cast< const MultiDimBucket< GUM_SCALAR >* >(impl))
54  ->compute();
55 
56  try {
57  p = new Potential< GUM_SCALAR >(new MultiDimBijArray< GUM_SCALAR >(
58  bij,
59  static_cast< const MultiDimBucket< GUM_SCALAR >* >(impl)->bucket()));
60  } catch (OperationNotAllowed&) {
61  // This is an empty bucket, it happens if all variables were
62  // eliminated
63  return new Potential< GUM_SCALAR >();
64  }
65  } else {
66  GUM_ERROR(FatalError, "encountered an unexpected MultiDim implementation")
67  }
68  } else {
69  if (dynamic_cast< const MultiDimArray< GUM_SCALAR >* >(impl)) {
70  p = new Potential< GUM_SCALAR >(new MultiDimBijArray< GUM_SCALAR >(
71  bij,
72  static_cast< const MultiDimArray< GUM_SCALAR >& >(*impl)));
73  } else if (dynamic_cast< const MultiDimBijArray< GUM_SCALAR >* >(impl)) {
74  p = new Potential< GUM_SCALAR >(new MultiDimBijArray< GUM_SCALAR >(
75  bij,
76  static_cast< const MultiDimBijArray< GUM_SCALAR >& >(*impl)));
77  } else if (dynamic_cast< const MultiDimSparse< GUM_SCALAR >* >(impl)) {
78  GUM_ERROR(FatalError, "There is no MultiDimSparse in PRMs, normally...")
79  } else {
80  // Just need to make the copy using the bijection but we only use
81  // multidim array
82  GUM_ERROR(FatalError, "encountered an unexpected MultiDim implementation")
83  }
84  }
85 
86  return p;
87  } catch (Exception&) {
88  if (p) delete p;
89 
90  throw;
91  }
92  }
93 
94  // the function used to combine two tables
95  template < typename GUM_SCALAR >
97  const Potential< GUM_SCALAR >& t2) {
98  return new Potential< GUM_SCALAR >(t1 * t2);
99  }
100 
101  template < typename GUM_SCALAR >
102  void eliminateNode(const DiscreteVariable* var,
103  Set< Potential< GUM_SCALAR >* >& pool,
104  Set< Potential< GUM_SCALAR >* >& trash) {
105  Potential< GUM_SCALAR >* pot = nullptr;
106  Potential< GUM_SCALAR >* tmp = nullptr;
107 
108  Set< const DiscreteVariable* > var_set;
109  var_set.insert(var);
110  Set< const Potential< GUM_SCALAR >* > pots;
111 
112  for (const auto p: pool)
113  if (p->contains(*var)) pots.insert(p);
114 
115  if (pots.size() == 0) {
116  return;
117  } else if (pots.size() == 1) {
118  tmp = const_cast< Potential< GUM_SCALAR >* >(*pots.begin());
119  pot = new Potential< GUM_SCALAR >(tmp->margSumOut(var_set));
120  } else {
121  MultiDimCombinationDefault< GUM_SCALAR, Potential > Comb(multPotential);
122  tmp = Comb.combine(pots);
123  pot = new Potential< GUM_SCALAR >(tmp->margSumOut(var_set));
124  delete tmp;
125  }
126 
127  for (const auto p: pots) {
128  pool.erase(const_cast< Potential< GUM_SCALAR >* >(p));
129 
130  if (trash.exists(const_cast< Potential< GUM_SCALAR >* >(p))) {
131  trash.erase(const_cast< Potential< GUM_SCALAR >* >(p));
132  delete const_cast< Potential< GUM_SCALAR >* >(p);
133  }
134  }
135 
136  pool.insert(pot);
137  trash.insert(pot);
138  }
139 
140  template < typename GUM_SCALAR >
141  void eliminateNodes(const std::vector< const DiscreteVariable* >& elim_order,
142  Set< Potential< GUM_SCALAR >* >& pool,
143  Set< Potential< GUM_SCALAR >* >& trash) {
144  for (auto var: elim_order) {
145  eliminateNode(var, pool, trash);
146  }
147  }
148 
149  } /* namespace prm */
150 } // namespace gum
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)
Potential< GUM_SCALAR > * copyPotential(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bij, const Potential< GUM_SCALAR > &source)
Returns a copy of a Potential after applying a bijection over the variables in source.
Definition: utils_prm_tpl.h:29
void eliminateNode(const DiscreteVariable *var, Set< Potential< GUM_SCALAR > * > &pool, Set< Potential< GUM_SCALAR > * > &trash)
Proceeds with the elimination of var in pool.
void eliminateNodes(const std::vector< const DiscreteVariable * > &elim_order, Set< Potential< GUM_SCALAR > * > &pool, Set< Potential< GUM_SCALAR > * > &trash)
Potential< GUM_SCALAR > * multPotential(const Potential< GUM_SCALAR > &t1, const Potential< GUM_SCALAR > &t2)
Definition: utils_prm_tpl.h:96