AIToolbox
A library that offers tools for AI problem solving.
Model.hpp
Go to the documentation of this file.
1 #ifndef AI_TOOLBOX_POMDP_MODEL_HEADER_FILE
2 #define AI_TOOLBOX_POMDP_MODEL_HEADER_FILE
3 
4 #include <random>
5 
6 #include <AIToolbox/Seeder.hpp>
12 
13 namespace AIToolbox::POMDP {
14  template <MDP::IsModel M>
15  class Model;
16 
17  // Declaration to warn the compiler that this is a template function
18  template <MDP::IsModel M>
19  std::istream& operator>>(std::istream &is, Model<M> & m);
20 
67  template <MDP::IsModel M>
68  class Model : public M {
69  public:
71 
82  template <typename... Args>
83  Model(size_t o, Args&&... parameters);
84 
112  // Check that ObFun is a triple-matrix, otherwise we'll call the other constructor!
113  template <IsNaive3DMatrix ObFun, typename... Args>
114  Model(size_t o, ObFun && of, Args&&... parameters);
115 
131  template <typename PM>
132  requires IsModel<PM> && std::constructible_from<M, PM>
133  Model(const PM& model);
134 
150  template <typename... Args>
151  Model(NoCheck, size_t o, ObservationMatrix && ot, Args&&... parameters);
152 
170  template <IsNaive3DMatrix ObFun>
171  void setObservationFunction(const ObFun & of);
172 
190 
210  std::tuple<size_t,size_t, double> sampleSOR(size_t s,size_t a) const;
211 
228  std::tuple<size_t, double> sampleOR(size_t s,size_t a,size_t s1) const;
229 
239  double getObservationProbability(size_t s1, size_t a, size_t o) const;
240 
248  const Matrix2D & getObservationFunction(size_t a) const;
249 
255  size_t getO() const;
256 
263 
264  private:
265  size_t O;
266  ObservationMatrix observations_;
267  // We need this because we don't know if our parent already has one,
268  // and we wouldn't know how to access it!
269  mutable RandomEngine rand_;
270  };
271 
272  template <MDP::IsModel M>
273  template <typename... Args>
274  Model<M>::Model(const size_t o, Args&&... params) :
275  M(std::forward<Args>(params)...), O(o),
276  observations_(this->getA(), Matrix2D(this->getS(), O)), rand_(Seeder::getSeed())
277  {
278  for ( size_t a = 0; a < this->getA(); ++a ) {
279  observations_[a].rightCols(O-1).setZero();
280  observations_[a].col(0).fill(1.0);
281  }
282  }
283 
284  template <MDP::IsModel M>
285  template <IsNaive3DMatrix ObFun, typename... Args>
286  Model<M>::Model(const size_t o, ObFun && of, Args&&... params) :
287  M(std::forward<Args>(params)...), O(o),
288  observations_(this->getA(), Matrix2D(this->getS(), O)), rand_(Seeder::getSeed())
289  {
291  }
292 
293  template <MDP::IsModel M>
294  template <typename... Args>
295  Model<M>::Model(NoCheck, size_t o, ObservationMatrix && ot, Args&&... params) :
296  M(std::forward<Args>(params)...), O(o),
297  observations_(std::move(ot))
298  {}
299 
300  template <MDP::IsModel M>
301  template <typename PM>
302  requires IsModel<PM> && std::constructible_from<M, PM>
303  Model<M>::Model(const PM& model) :
304  M(model), O(model.getO()), observations_(this->getA(), Matrix2D(this->getS(), O)),
305  rand_(Seeder::getSeed())
306  {
307  for ( size_t a = 0; a < this->getA(); ++a )
308  for ( size_t s1 = 0; s1 < this->getS(); ++s1 ) {
309  for ( size_t o = 0; o < O; ++o ) {
310  observations_[a](s1, o) = model.getObservationProbability(s1, a, o);
311  }
312  if ( !isProbability(O, observations_[a].row(s1)) )
313  throw std::invalid_argument("Input observation matrix does not contain valid probabilities.");
314  }
315  }
316 
317  template <MDP::IsModel M>
318  template <IsNaive3DMatrix ObFun>
319  void Model<M>::setObservationFunction(const ObFun & of) {
320  for ( size_t s1 = 0; s1 < this->getS(); ++s1 )
321  for ( size_t a = 0; a < this->getA(); ++a )
322  if ( !isProbability(O, of[s1][a]) )
323  throw std::invalid_argument("Input observation matrix does not contain valid probabilities.");
324 
325  for ( size_t s1 = 0; s1 < this->getS(); ++s1 )
326  for ( size_t a = 0; a < this->getA(); ++a )
327  for ( size_t o = 0; o < O; ++o )
328  observations_[a](s1, o) = of[s1][a][o];
329  }
330 
331  template <MDP::IsModel M>
333  if (!isProbability(of))
334  throw std::invalid_argument("Input observation matrix does not contain valid probabilities.");
335 
336  observations_ = of;
337  }
338 
339  template <MDP::IsModel M>
340  double Model<M>::getObservationProbability(const size_t s1, const size_t a, const size_t o) const {
341  return observations_[a](s1, o);
342  }
343 
344  template <MDP::IsModel M>
345  const Matrix2D & Model<M>::getObservationFunction(const size_t a) const {
346  return observations_[a];
347  }
348 
349  template <MDP::IsModel M>
350  size_t Model<M>::getO() const {
351  return O;
352  }
353 
354  template <MDP::IsModel M>
356  return observations_;
357  }
358 
359  template <MDP::IsModel M>
360  std::tuple<size_t,size_t, double> Model<M>::sampleSOR(const size_t s, const size_t a) const {
361  const auto [s1, r] = this->sampleSR(s, a);
362  const auto o = sampleProbability(O, observations_[a].row(s1), rand_);
363  return std::make_tuple(s1, o, r);
364  }
365 
366  template <MDP::IsModel M>
367  std::tuple<size_t, double> Model<M>::sampleOR(const size_t s, const size_t a, const size_t s1) const {
368  const size_t o = sampleProbability(O, observations_[a].row(s1), rand_);
369  const double r = this->getExpectedReward(s, a, s1);
370  return std::make_tuple(o, r);
371  }
372 }
373 
374 #endif
AIToolbox::POMDP
Definition: AMDP.hpp:14
Core.hpp
AIToolbox::POMDP::Model::getObservationFunction
const ObservationMatrix & getObservationFunction() const
This function returns the observation matrix for inspection.
Definition: Model.hpp:355
AIToolbox::POMDP::Model::getO
size_t getO() const
This function returns the number of observations possible.
Definition: Model.hpp:350
TypeTraits.hpp
AIToolbox::Seeder
This class is an internal class used to seed all random engines in the library.
Definition: Seeder.hpp:15
AIToolbox::Matrix2D
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor|Eigen::AutoAlign > Matrix2D
Definition: Types.hpp:18
AIToolbox::POMDP::Model
This class represents a Partially Observable Markov Decision Process.
Definition: Model.hpp:15
AIToolbox::POMDP::Model::Model
Model(size_t o, Args &&... parameters)
Basic constructor.
Definition: Model.hpp:274
AIToolbox::isProbability
bool isProbability(const size_t size, const T &in)
This function checks whether the supplied 1D container is a valid discrete distribution.
Definition: Probability.hpp:38
AIToolbox::POMDP::Model::ObservationMatrix
Matrix3D ObservationMatrix
Definition: Model.hpp:70
AIToolbox::POMDP::Model::getObservationProbability
double getObservationProbability(size_t s1, size_t a, size_t o) const
This function returns the stored observation probability for the specified state-action pair.
Definition: Model.hpp:340
Seeder.hpp
AIToolbox::RandomEngine
std::mt19937 RandomEngine
Definition: Types.hpp:14
AIToolbox::POMDP::Model::sampleOR
std::tuple< size_t, double > sampleOR(size_t s, size_t a, size_t s1) const
This function samples the POMDP for the specified state action pair.
Definition: Model.hpp:367
Types.hpp
AIToolbox::sampleProbability
size_t sampleProbability(const size_t d, const T &in, G &generator)
This function samples an index from a probability vector.
Definition: Probability.hpp:188
AIToolbox::Matrix3D
std::vector< Matrix2D > Matrix3D
Definition: Types.hpp:21
AIToolbox::IsNaive3DMatrix
concept IsNaive3DMatrix
This concept checks for a simple 3D accessible matrix.
Definition: TypeTraits.hpp:42
AIToolbox::NoCheck
This is used to tag functions that avoid runtime checks.
Definition: Types.hpp:44
AIToolbox::POMDP::Model::setObservationFunction
void setObservationFunction(const ObFun &of)
This function replaces the Model observation function with the one provided.
Definition: Model.hpp:319
Types.hpp
AIToolbox::POMDP::Model::sampleSOR
std::tuple< size_t, size_t, double > sampleSOR(size_t s, size_t a) const
This function samples the POMDP for the specified state action pair.
Definition: Model.hpp:360
AIToolbox::POMDP::operator>>
std::istream & operator>>(std::istream &is, Model< M > &m)
This function parses a Model from a stream.
Definition: IO.hpp:62
Probability.hpp