value.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #ifndef value_hpp
  2. #define value_hpp
  3. #include <iostream>
  4. #include <utility>
  5. #include <algorithm>
  6. #include <map>
  7. #include <vector>
  8. #include <tuple>
  9. #include <initializer_list>
  10. #include <functional>
  11. namespace filval{
  12. class GenValue{
  13. private:
  14. inline static std::vector<GenValue*> values;
  15. virtual void _reset() = 0;
  16. public:
  17. GenValue(){
  18. values.push_back(this);
  19. }
  20. static void reset(){
  21. for (auto val : values){
  22. val->_reset();
  23. }
  24. }
  25. };
  26. typedef std::map<std::string, GenValue*> ValueSet;
  27. template <typename T>
  28. class Value : public GenValue{
  29. public:
  30. Value(): GenValue(){}
  31. virtual T& get_value() = 0;
  32. };
  33. template <typename T>
  34. class ObservedValue : public Value<T>{
  35. /* For "observed" values, there is nothing to calculate since this is
  36. * merely a wrapper around a field in the observation. A pointer to the
  37. * value is kept and it's value is read when requested.
  38. */
  39. private:
  40. T *val_ref;
  41. void _reset(){ }
  42. public:
  43. ObservedValue(T* val_ref)
  44. :Value<T>(),
  45. val_ref(val_ref){ }
  46. T& get_value(){
  47. return *val_ref;
  48. }
  49. };
  50. template <typename T>
  51. class DerivedValue : public Value<T>{
  52. /* A "derived" value is the result of some sort of calculation. Since it is
  53. * desireable for the calculation to occur at most a single time for each
  54. * observation, the result of the calculation is stored in the object. be
  55. * sure that "reset" is called between processing observations to force a
  56. * re-calculation.
  57. */
  58. private:
  59. void _reset(){
  60. value_valid = false;
  61. }
  62. protected:
  63. T value;
  64. bool value_valid;
  65. virtual void update_value() = 0;
  66. public:
  67. DerivedValue() :Value<T>(), value_valid(false) { }
  68. T& get_value(){
  69. if (!value_valid){
  70. update_value();
  71. value_valid = true;
  72. }
  73. return value;
  74. }
  75. };
  76. template <typename T>
  77. class WrapperVector : public DerivedValue<std::vector<T> >{
  78. private:
  79. Value<int>* size;
  80. Value<T*>* data;
  81. void update_value(){
  82. int n = size->get_value();
  83. T* data_ref = data->get_value();
  84. this->value.resize(n);
  85. for (int i=0; i<n; i++){
  86. this->value[i] = *(data_ref+i);
  87. }
  88. }
  89. public:
  90. WrapperVector(Value<int>* _size, Value<T*>* _data)
  91. :DerivedValue<std::vector<T> >(),
  92. size(_size), data(_data){ }
  93. WrapperVector(ValueSet *values, const std::string &label_size, const std::string &label_data)
  94. :WrapperVector(dynamic_cast<Value<int>*>(values->at(label_size)),
  95. dynamic_cast<Value<T*>*>(values->at(label_data))) { }
  96. };
  97. template <typename T1, typename T2>
  98. class Pair : public DerivedValue<std::pair<T1, T2> >{
  99. protected:
  100. std::pair<Value<T1>*, Value<T2>* > value_pair;
  101. void update_value(){
  102. this->value.first = value_pair.first->get_value();
  103. this->value.second = value_pair.second->get_value();
  104. }
  105. public:
  106. Pair(Value<T1> *value1, Value<T2> *value2)
  107. :DerivedValue<std::pair<T1, T2> >(),
  108. value_pair(value1, value2){ }
  109. Pair(ValueSet *values, const std::string &label1, const std::string &label2)
  110. :Pair((Value<T1>*) values->at(label1),
  111. (Value<T1>*) values->at(label2)){ }
  112. };
  113. template <typename R, typename T>
  114. class ZipMapFour : public DerivedValue<std::vector<R> >{
  115. private:
  116. std::function<R(T, T, T, T)> f;
  117. Value<std::vector<T> >* v1;
  118. Value<std::vector<T> >* v2;
  119. Value<std::vector<T> >* v3;
  120. Value<std::vector<T> >* v4;
  121. void update_value(){
  122. std::vector<T> v1_val = v1->get_value();
  123. std::vector<T> v2_val = v2->get_value();
  124. std::vector<T> v3_val = v3->get_value();
  125. std::vector<T> v4_val = v4->get_value();
  126. int n;
  127. std::tie(n, std::ignore) = std::minmax({v1_val.size(), v2_val.size(), v3_val.size(), v4_val.size()});
  128. this->value.resize(n);
  129. for (int i=0; i<n; i++){
  130. this->value[i] = f(v1_val[i], v2_val[i], v3_val[i], v4_val[i]);
  131. }
  132. }
  133. public:
  134. ZipMapFour(std::function<R(T, T, T, T)> f,
  135. Value<std::vector<T> >* v1, Value<std::vector<T> >* v2,
  136. Value<std::vector<T> >* v3, Value<std::vector<T> >* v4)
  137. :DerivedValue<std::vector<R> >(),
  138. f(f), v1(v1), v2(v2), v3(v3), v4(v4) { }
  139. ZipMapFour(std::function<R(T, T, T, T)> f,
  140. ValueSet *values,
  141. const std::string &label1,
  142. const std::string &label2,
  143. const std::string &label3,
  144. const std::string &label4)
  145. :ZipMapFour(f,
  146. dynamic_cast<Value<std::vector<T> >*>(values->at(label1)),
  147. dynamic_cast<Value<std::vector<T> >*>(values->at(label2)),
  148. dynamic_cast<Value<std::vector<T> >*>(values->at(label3)),
  149. dynamic_cast<Value<std::vector<T> >*>(values->at(label4))){ }
  150. };
  151. template <typename T>
  152. class Reduce : public DerivedValue<T>{
  153. private:
  154. std::function<T(std::vector<T>)> reduce;
  155. Value<std::vector<T> >* v;
  156. void update_value(){
  157. this->value = reduce(v->get_value());
  158. }
  159. public:
  160. Reduce(std::function<T(std::vector<T>)> reduce, Value<std::vector<T> >* v)
  161. :DerivedValue<T>(),
  162. reduce(reduce), v(v) { }
  163. };
  164. template <typename R, typename... T>
  165. class MultiFunc : public DerivedValue<R>{
  166. private:
  167. std::function<R(T...)> f;
  168. std::tuple<T...> value_tuple;
  169. void update_value(){
  170. this->value = f(value_tuple);
  171. }
  172. public:
  173. MultiFunc(std::function<R(std::tuple<T...>)> f, T... varargs)
  174. :f(f),
  175. value_tuple(varargs...){ }
  176. };
  177. template <typename T>
  178. class BoundValue : public DerivedValue<T>{
  179. /* A "bound" value has it's dependencies bound into a function object. */
  180. protected:
  181. std::function<T()> f;
  182. void update_value(){
  183. this->value = f();
  184. }
  185. public:
  186. BoundValue(std::function<T()> f)
  187. :f(f) { }
  188. };
  189. template <typename T>
  190. class ConstantValue : public DerivedValue<T>{
  191. protected:
  192. T const_value;
  193. void update_value(){
  194. this->value = const_value;
  195. }
  196. public:
  197. ConstantValue(T const_value)
  198. :const_value(const_value) { }
  199. };
  200. }
  201. #endif // value_hpp