aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
utils_prm_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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 >
29  const Bijection< const DiscreteVariable*, const DiscreteVariable* >& bij,
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 >(
38  new MultiDimNoisyORCompound< GUM_SCALAR >(
39  bij,
40  static_cast< const MultiDimNoisyORCompound< GUM_SCALAR >& >(
41  *impl)));
42  } else if (dynamic_cast< const MultiDimNoisyORNet< GUM_SCALAR >* >(
43  impl)) {
44  p = new Potential< GUM_SCALAR >(new MultiDimNoisyORNet< GUM_SCALAR >(
45  bij,
46  static_cast< const MultiDimNoisyORNet< GUM_SCALAR >& >(*impl)));
47  } else if (dynamic_cast<
48  const aggregator::MultiDimAggregator< GUM_SCALAR >* >(
49  impl)) {
50  p = new Potential< GUM_SCALAR >(
51  static_cast< MultiDimImplementation< GUM_SCALAR >* >(
52  impl->newFactory()));
53 
54  for (auto var: impl->variablesSequence())
55  p->add(*(bij.second(var)));
56  } else if (dynamic_cast< const MultiDimBucket< GUM_SCALAR >* >(impl)) {
57  // This is necessary just to prevent non initialized arrays
58  const_cast< MultiDimBucket< GUM_SCALAR >* >(
59  static_cast< const MultiDimBucket< GUM_SCALAR >* >(impl))
60  ->compute();
61 
62  try {
63  p = new Potential< GUM_SCALAR >(new MultiDimBijArray< GUM_SCALAR >(
64  bij,
65  static_cast< const MultiDimBucket< GUM_SCALAR >* >(impl)
66  ->bucket()));
67  } catch (OperationNotAllowed&) {
68  // This is an empty bucket, it happens if all variables were
69  // eliminated
70  return new Potential< GUM_SCALAR >();
71  }
72  } else {
73  GUM_ERROR(FatalError,
74  "encountered an unexpected MultiDim implementation");
75  }
76  } else {
77  if (dynamic_cast< const MultiDimArray< GUM_SCALAR >* >(impl)) {
78  p = new Potential< GUM_SCALAR >(new MultiDimBijArray< GUM_SCALAR >(
79  bij,
80  static_cast< const MultiDimArray< GUM_SCALAR >& >(*impl)));
81  } else if (dynamic_cast< const MultiDimBijArray< GUM_SCALAR >* >(impl)) {
82  p = new Potential< GUM_SCALAR >(new MultiDimBijArray< GUM_SCALAR >(
83  bij,
84  static_cast< const MultiDimBijArray< GUM_SCALAR >& >(*impl)));
85  } else if (dynamic_cast< const MultiDimSparse< GUM_SCALAR >* >(impl)) {
86  GUM_ERROR(FatalError,
87  "There is no MultiDimSparse in PRMs, normally...");
88  } else {
89  // Just need to make the copy using the bijection but we only use
90  // multidim array
91  GUM_ERROR(FatalError,
92  "encountered an unexpected MultiDim implementation");
93  }
94  }
95 
96  return p;
97  } catch (Exception&) {
98  if (p) delete p;
99 
100  throw;
101  }
102  }
103 
104  // the function used to combine two tables
105  template < typename GUM_SCALAR >
107  const Potential< GUM_SCALAR >& t2) {
108  return new Potential< GUM_SCALAR >(t1 * t2);
109  }
110 
111  template < typename GUM_SCALAR >
112  void eliminateNode(const DiscreteVariable* var,
113  Set< Potential< GUM_SCALAR >* >& pool,
114  Set< Potential< GUM_SCALAR >* >& trash) {
115  Potential< GUM_SCALAR >* pot = nullptr;
116  Potential< GUM_SCALAR >* tmp = nullptr;
117 
118  Set< const DiscreteVariable* > var_set;
119  var_set.insert(var);
120  Set< const Potential< GUM_SCALAR >* > pots;
121 
122  for (const auto p: pool)
123  if (p->contains(*var)) pots.insert(p);
124 
125  if (pots.size() == 0) {
126  return;
127  } else if (pots.size() == 1) {
128  tmp = const_cast< Potential< GUM_SCALAR >* >(*pots.begin());
129  pot = new Potential< GUM_SCALAR >(tmp->margSumOut(var_set));
130  } else {
131  MultiDimCombinationDefault< GUM_SCALAR, Potential > Comb(multPotential);
132  tmp = Comb.combine(pots);
133  pot = new Potential< GUM_SCALAR >(tmp->margSumOut(var_set));
134  delete tmp;
135  }
136 
137  for (const auto p: pots) {
138  pool.erase(const_cast< Potential< GUM_SCALAR >* >(p));
139 
140  if (trash.exists(const_cast< Potential< GUM_SCALAR >* >(p))) {
141  trash.erase(const_cast< Potential< GUM_SCALAR >* >(p));
142  delete const_cast< Potential< GUM_SCALAR >* >(p);
143  }
144  }
145 
146  pool.insert(pot);
147  trash.insert(pot);
148  }
149 
150  template < typename GUM_SCALAR >
151  void eliminateNodes(const std::vector< const DiscreteVariable* >& elim_order,
152  Set< Potential< GUM_SCALAR >* >& pool,
153  Set< Potential< GUM_SCALAR >* >& trash) {
154  for (auto var: elim_order) {
155  eliminateNode(var, pool, trash);
156  }
157  }
158 
159  } /* namespace prm */
160 } // namespace gum
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
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:28
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)