DiscreteConditional.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
22 #include <gtsam/base/Testable.h>
23 #include <gtsam/base/debug.h>
24 
25 #include <boost/make_shared.hpp>
26 
27 #include <algorithm>
28 #include <random>
29 #include <stdexcept>
30 #include <string>
31 #include <vector>
32 
33 using namespace std;
34 
35 namespace gtsam {
36 
37 // Instantiate base class
38 template class Conditional<DecisionTreeFactor, DiscreteConditional> ;
39 
40 /* ******************************************************************************** */
41 DiscreteConditional::DiscreteConditional(const size_t nrFrontals,
42  const DecisionTreeFactor& f) :
43  BaseFactor(f / (*f.sum(nrFrontals))), BaseConditional(nrFrontals) {
44 }
45 
46 /* ******************************************************************************** */
48  const DecisionTreeFactor& marginal) :
49  BaseFactor(
50  ISDEBUG("DiscreteConditional::COUNT") ? joint : joint / marginal), BaseConditional(
51  joint.size()-marginal.size()) {
52  if (ISDEBUG("DiscreteConditional::DiscreteConditional"))
53  cout << (firstFrontalKey()) << endl; //TODO Print all keys
54 }
55 
56 /* ******************************************************************************** */
58  const DecisionTreeFactor& marginal, const Ordering& orderedKeys) :
59  DiscreteConditional(joint, marginal) {
60  keys_.clear();
61  keys_.insert(keys_.end(), orderedKeys.begin(), orderedKeys.end());
62 }
63 
64 /* ******************************************************************************** */
66  : BaseFactor(signature.discreteKeys(), signature.cpt()),
67  BaseConditional(1) {}
68 
69 /* ******************************************************************************** */
70 void DiscreteConditional::print(const string& s,
71  const KeyFormatter& formatter) const {
72  cout << s << " P( ";
73  for (const_iterator it = beginFrontals(); it != endFrontals(); ++it) {
74  cout << formatter(*it) << " ";
75  }
76  if (nrParents()) {
77  cout << "| ";
78  for (const_iterator it = beginParents(); it != endParents(); ++it) {
79  cout << formatter(*it) << " ";
80  }
81  }
82  cout << ")";
84  cout << endl;
85 }
86 
87 /* ******************************************************************************** */
89  double tol) const {
90  if (!dynamic_cast<const DecisionTreeFactor*>(&other))
91  return false;
92  else {
93  const DecisionTreeFactor& f(
94  static_cast<const DecisionTreeFactor&>(other));
95  return DecisionTreeFactor::equals(f, tol);
96  }
97 }
98 
99 /* ******************************************************************************** */
101  ADT pFS(*this);
102  Key j; size_t value;
103  for(Key key: parents()) {
104  try {
105  j = (key);
106  value = parentsValues.at(j);
107  pFS = pFS.choose(j, value);
108  } catch (exception&) {
109  cout << "Key: " << j << " Value: " << value << endl;
110  parentsValues.print("parentsValues: ");
111  // pFS.print("pFS: ");
112  throw runtime_error("DiscreteConditional::choose: parent value missing");
113  };
114  }
115 
116  return pFS;
117 }
118 
119 /* ******************************************************************************** */
121  // TODO: Abhijit asks: is this really the fastest way? He thinks it is.
122  ADT pFS = choose(values); // P(F|S=parentsValues)
123 
124  // Initialize
125  Values mpe;
126  double maxP = 0;
127 
129  for(Key idx: frontals()) {
130  DiscreteKey dk(idx, cardinality(idx));
131  keys & dk;
132  }
133  // Get all Possible Configurations
134  vector<Values> allPosbValues = cartesianProduct(keys);
135 
136  // Find the MPE
137  for(Values& frontalVals: allPosbValues) {
138  double pValueS = pFS(frontalVals); // P(F=value|S=parentsValues)
139  // Update MPE solution if better
140  if (pValueS > maxP) {
141  maxP = pValueS;
142  mpe = frontalVals;
143  }
144  }
145 
146  //set values (inPlace) to mpe
147  for(Key j: frontals()) {
148  values[j] = mpe[j];
149  }
150 }
151 
152 /* ******************************************************************************** */
154  assert(nrFrontals() == 1);
155  Key j = (firstFrontalKey());
156  size_t sampled = sample(values); // Sample variable
157  values[j] = sampled; // store result in partial solution
158 }
159 
160 /* ******************************************************************************** */
161 size_t DiscreteConditional::solve(const Values& parentsValues) const {
162 
163  // TODO: is this really the fastest way? I think it is.
164  ADT pFS = choose(parentsValues); // P(F|S=parentsValues)
165 
166  // Then, find the max over all remaining
167  // TODO, only works for one key now, seems horribly slow this way
168  size_t mpe = 0;
170  double maxP = 0;
171  assert(nrFrontals() == 1);
172  Key j = (firstFrontalKey());
173  for (size_t value = 0; value < cardinality(j); value++) {
174  frontals[j] = value;
175  double pValueS = pFS(frontals); // P(F=value|S=parentsValues)
176  // Update MPE solution if better
177  if (pValueS > maxP) {
178  maxP = pValueS;
179  mpe = value;
180  }
181  }
182  return mpe;
183 }
184 
185 /* ******************************************************************************** */
186 size_t DiscreteConditional::sample(const Values& parentsValues) const {
187  static mt19937 rng(2); // random number generator
188 
189  // Get the correct conditional density
190  ADT pFS = choose(parentsValues); // P(F|S=parentsValues)
191 
192  // TODO(Duy): only works for one key now, seems horribly slow this way
193  assert(nrFrontals() == 1);
194  Key key = firstFrontalKey();
195  size_t nj = cardinality(key);
196  vector<double> p(nj);
198  for (size_t value = 0; value < nj; value++) {
199  frontals[key] = value;
200  p[value] = pFS(frontals); // P(F=value|S=parentsValues)
201  if (p[value] == 1.0) {
202  return value; // shortcut exit
203  }
204  }
205  std::discrete_distribution<size_t> distribution(p.begin(), p.end());
206  return distribution(rng);
207 }
208 
209 /* ******************************************************************************** */
210 
211 }// namespace
std::vector< Assignment< L > > cartesianProduct(const std::vector< std::pair< L, size_t > > &keys)
Get Cartesian product consisting all possible configurations.
Definition: Assignment.h:62
Concept check for values that can be used in unit tests.
signatures for conditional densities
Global debugging flags.
DecisionTreeFactor::const_iterator endParents() const
Definition: Conditional.h:114
static std::mt19937 rng
leaf::MyValues values
void solveInPlace(Values &parentsValues) const
solve a conditional, in place
KeyVector keys_
The keys involved in this factor.
Definition: Factor.h:72
Definition: Half.h:150
DecisionTree choose(const L &label, size_t index) const
Definition: DecisionTree.h:180
const KeyFormatter & formatter
size_t solve(const Values &parentsValues) const
DecisionTreeFactor::const_iterator beginParents() const
Definition: Conditional.h:111
#define ISDEBUG(S)
Definition: debug.h:60
void print(const std::string &s="Assignment: ") const
Definition: Assignment.h:36
std::pair< Key, size_t > DiscreteKey
Definition: DiscreteKey.h:34
DecisionTreeFactor::const_iterator endFrontals() const
Definition: Conditional.h:108
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: Key.h:35
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
ADT choose(const Assignment< Key > &parentsValues) const
size_t cardinality(Key j) const
Definition: Potentials.h:74
RealScalar s
const mpreal sum(const mpreal tab[], const unsigned long int n, int &status, mp_rnd_t mode=mpreal::get_default_rnd())
Definition: mpreal.h:2381
traits
Definition: chartTesting.h:28
DecisionTreeFactor::const_iterator beginFrontals() const
Definition: Conditional.h:105
void sampleInPlace(Values &parentsValues) const
sample in place, stores result in partial solution
size_t size() const
Definition: Factor.h:135
const KeyVector & keys() const
Access the factor&#39;s involved variable keys.
Definition: Factor.h:124
bool equals(const DiscreteFactor &other, double tol=1e-9) const override
GTSAM-style equals.
float * p
GTSAM_EXPORT void print(const std::string &s="Potentials: ", const KeyFormatter &formatter=DefaultKeyFormatter) const
Definition: Potentials.cpp:57
bool equals(const DiscreteFactor &other, double tol=1e-9) const override
equality
const G double tol
Definition: Group.h:83
KeyVector::const_iterator const_iterator
Const iterator over keys.
Definition: Factor.h:67
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:61
void print(const std::string &s="Discrete Conditional: ", const KeyFormatter &formatter=DefaultKeyFormatter) const override
GTSAM-style print.
size_t sample(const Values &parentsValues) const
std::ptrdiff_t j
DiscreteKeys is a set of keys that can be assembled using the & operator.
Definition: DiscreteKey.h:37


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:41:59