value.hpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. /**
  2. * @file
  3. * @author Caleb Fangmeier <caleb@fangmeier.tech>
  4. * @version 0.1
  5. *
  6. * @section LICENSE
  7. *
  8. *
  9. * MIT License
  10. *
  11. * Copyright (c) 2017 Caleb Fangmeier
  12. *
  13. * Permission is hereby granted, free of charge, to any person obtaining a copy
  14. * of this software and associated documentation files (the "Software"), to deal
  15. * in the Software without restriction, including without limitation the rights
  16. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  17. * copies of the Software, and to permit persons to whom the Software is
  18. * furnished to do so, subject to the following conditions:
  19. *
  20. * The above copyright notice and this permission notice shall be included in all
  21. * copies or substantial portions of the Software.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  24. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  26. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  27. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  28. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  29. * SOFTWARE.
  30. *
  31. * @section DESCRIPTION
  32. * This header defines a set of generic classes that wrap up "values". In
  33. * essence, a Value<T> object is just something that contains a value of type T
  34. * and can provide it when requested. The usefulness stems from composing
  35. * values together with calculations. This enables very clear dependency
  36. * mapping and a way to know clearly how every value was arrived at. This could
  37. * be used to, for example, automatically generate commentary for plots that
  38. * explain the exect calculation used to create it. Or easily making a series
  39. * of plots contrasting different values that have been composed slightly
  40. * differently.
  41. */
  42. #ifndef value_hpp
  43. #define value_hpp
  44. #include <iomanip>
  45. #include <iostream>
  46. #include <sstream>
  47. #include <utility>
  48. #include <algorithm>
  49. #include <map>
  50. #include <limits>
  51. #include <vector>
  52. #include <tuple>
  53. #include <initializer_list>
  54. #include <functional>
  55. #include "log.hpp"
  56. /**
  57. * The namespace containing all filval classes and functions.
  58. */
  59. namespace fv{
  60. template <typename F, typename TUPLE, bool Done, int Total, int... N>
  61. struct call_impl
  62. {
  63. static auto call(F& f, TUPLE && t)
  64. {
  65. return call_impl<F, TUPLE, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(f, std::forward<TUPLE>(t));
  66. }
  67. };
  68. template <typename F, typename TUPLE, int Total, int... N>
  69. struct call_impl<F, TUPLE, true, Total, N...>
  70. {
  71. static auto call(F& f, TUPLE && t)
  72. {
  73. return f(std::get<N>(std::forward<TUPLE>(t))...);
  74. }
  75. };
  76. /**
  77. * This calls a function of type F with the contents of the tuple as separate arguments.
  78. * \see http://stackoverflow.com/questions/10766112/c11-i-can-go-from-multiple-args-to-tuple-but-can-i-go-from-tuple-to-multiple
  79. */
  80. template <typename F, typename TUPLE>
  81. auto call(F& f, TUPLE && t)
  82. {
  83. typedef typename std::decay<TUPLE>::type ttype;
  84. return call_impl<F, TUPLE, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<TUPLE>(t));
  85. }
  86. template<typename> class Function; // undefined
  87. /**
  88. * Parent class to all Function classes. Holds a class-level collection of all
  89. * created function objects.
  90. */
  91. class GenFunction {
  92. private:
  93. std::string name;
  94. std::string impl;
  95. protected:
  96. inline static bool in_register_function=false;
  97. public:
  98. /**
  99. * Static mapping of functions from their name to the object wrapper of
  100. * the function.
  101. */
  102. inline static std::map<const std::string, GenFunction*> function_registry;
  103. GenFunction(const std::string& name, const std::string& impl)
  104. :name(name),
  105. impl(impl){ }
  106. virtual ~GenFunction() { };
  107. std::string& get_name(){
  108. return name;
  109. }
  110. /**
  111. * Attempt to invoke clang-format for the purpose of printing out
  112. * nicely formatted functions to the log file. If clang-format is not
  113. * present, this function just passes through the code unmodified.
  114. */
  115. static std::string format_code(const std::string& code){
  116. std::stringstream code_out("");
  117. std::string command("echo \""+code+"\" | clang-format");
  118. char buffer[255];
  119. FILE *stream = popen(command.c_str(), "r");
  120. while (fgets(buffer, 255, stream) != NULL)
  121. code_out << buffer;
  122. if (pclose(stream) == 0)
  123. return code_out.str();
  124. else
  125. return code;
  126. }
  127. static std::string summary(){
  128. std::stringstream ss;
  129. ss << "The following functions have been registered" << std::endl;
  130. for(auto p : function_registry){
  131. if (p.second == nullptr) continue;
  132. ss << "-->" << p.second->name << "@" << p.second << std::endl;
  133. ss << format_code(p.second->impl);
  134. }
  135. return ss.str();
  136. }
  137. template <typename T>
  138. static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
  139. in_register_function = true;
  140. Function<T>* func;
  141. if (GenFunction::function_registry[name] != nullptr){
  142. func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
  143. if (func == nullptr){
  144. ERROR("Trying to register function which has already been registered with a different type");
  145. }
  146. } else {
  147. func = new Function<T>(name, impl, f);
  148. GenFunction::function_registry[name] = func;
  149. }
  150. in_register_function = false;
  151. return *func;
  152. }
  153. template <typename T>
  154. static Function<T>& lookup_function(const std::string& name){
  155. if (GenFunction::function_registry[name] == nullptr){
  156. CRITICAL("Function \"" << name << "\" not previously registered", -1);
  157. } else {
  158. Function<T>* func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
  159. if (func == nullptr){
  160. CRITICAL("Function \"" << name << "\" request and register have mismatched types", -1);
  161. }
  162. return *GenFunction::function_registry[name];
  163. }
  164. }
  165. };
  166. /**
  167. * In order to enable proper provenance tracking, and at the same time keep
  168. * the ability to embed functions into values, the Function class should be
  169. * used. It is simply a wrapper around a std::function that also has a name.
  170. * This name is used when generating the name of values that use the function.
  171. * A function name is automatically prepended with "func::" to explicitly state
  172. * that the value is the result of a computation encoded within the function
  173. * object, and not from some other Value object. Unfortunately, it is up to the
  174. * user to find where that function is defined in the source code to inspect
  175. * what it is doing. But hopefully this isn't too onerous by just using grep.
  176. */
  177. template <typename R, typename... ArgTypes>
  178. class Function<R(ArgTypes...)> : public GenFunction {
  179. private:
  180. std::function<R(ArgTypes...)> f;
  181. public:
  182. Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
  183. :GenFunction(name, impl), f(f){
  184. if (!in_register_function) {
  185. WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
  186. }
  187. }
  188. Function(const std::string& name, std::function<R(ArgTypes...)> f)
  189. :Function(name, "N/A", f){ }
  190. ~Function() { }
  191. R operator()(ArgTypes ...args){
  192. return f(args...);
  193. }
  194. };
  195. #define FUNC(f) f, #f
  196. /**
  197. * A type-agnostic value.
  198. * It is necessary to create a type-agnostic parent class to Value so that
  199. * it is possible to handle collections of them. GenValue also provides the
  200. * rest of the type-independent interface to Value.
  201. */
  202. class GenValue;
  203. typedef std::map<std::string, GenValue*> ValueSet;
  204. class GenValue{
  205. private:
  206. /**
  207. * The name of the value.
  208. * This is used to allow for dynamic lookup of
  209. * values based on their name via GenValue::get_value.
  210. */
  211. std::string name;
  212. protected:
  213. /**
  214. * Mark the internal value as invalid. This is needed for DerivedValue
  215. * to force a recalculation of the internal value when a new
  216. * observation is loaded into memory. It is called automatically for
  217. * all GenValue objects when reset is called.
  218. */
  219. virtual void _reset() = 0;
  220. /**
  221. * A static mapping containing all created Value objects.
  222. * Every value object must have a unique name, and this name is used as
  223. * a key in values to that object. This is used to enable more dynamic
  224. * creation of objects as well as avoiding the uneccesary passing of
  225. * pointers.
  226. */
  227. inline static std::map<const std::string, GenValue*> values;
  228. /**
  229. * Composite value names are typically nested. This makes complex
  230. * values have rather unwieldy names. Therefore, one can declare
  231. * aliases which allow for more human-usable names to be used. When a
  232. * value is requested by name, an alias with that value takes precidence
  233. * over a name with that value.
  234. */
  235. inline static std::map<const std::string, GenValue*> aliases;
  236. public:
  237. GenValue(const std::string& name, const std::string& alias)
  238. :name(name){
  239. values[name] = this;
  240. if (alias != "")
  241. GenValue::alias(alias, this);
  242. }
  243. const std::string& get_name(){
  244. return name;
  245. }
  246. void set_name(const std::string& new_name){
  247. values[name] = nullptr;
  248. name = new_name;
  249. values[name] = this;
  250. }
  251. static void reset(){
  252. for (auto val : values){
  253. if (val.second != nullptr){
  254. val.second->_reset();
  255. }
  256. }
  257. }
  258. static GenValue* get_value(const std::string& name){
  259. if (aliases[name] != nullptr)
  260. return aliases[name];
  261. else if (values[name] != nullptr)
  262. return values[name];
  263. else{
  264. ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
  265. << summary());
  266. CRITICAL("Aborting... :(",-1);
  267. }
  268. }
  269. static void alias(const std::string& name, GenValue* value){
  270. if (aliases[name] != nullptr){
  271. WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
  272. }
  273. aliases[name] = value;
  274. }
  275. static GenValue* alias(const std::string& name){
  276. if (values[name] != nullptr){
  277. WARNING("Alias \"" << name << "\" does not exist.");
  278. }
  279. return aliases[name];
  280. }
  281. static std::string summary(){
  282. std::stringstream ss;
  283. ss << "The following values have been created: " << std::endl;
  284. for (auto value : values){
  285. if (value.second == nullptr) continue;
  286. ss << "\t\"" << value.first << "\" at address " << value.second << std::endl;
  287. }
  288. ss << "And these aliases:" << std::endl;
  289. for (auto alias : aliases){
  290. std::string orig("VOID");
  291. if (alias.second == nullptr) continue;
  292. for (auto value : values){
  293. if (alias.second == value.second){
  294. orig = value.second->get_name();
  295. break;
  296. }
  297. }
  298. ss << "\t\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
  299. }
  300. return ss.str();
  301. }
  302. friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
  303. };
  304. std::ostream& operator<<(std::ostream& os, GenValue& gv){
  305. os << gv.get_name();
  306. return os;
  307. }
  308. /**
  309. * A generic value.
  310. * In order to facilitate run-time creation of analysis routines, it is
  311. * necessary to have some ability to get and store *values*. Values can either
  312. * be directly taken from some original data source (i.e. ObservedValue), or
  313. * they can be a function of some other set of values (i.e. DerivedValue). They
  314. * template class T of Value<T> is the type of thing that is returned upon
  315. * calling get_value().
  316. */
  317. template <typename T>
  318. class Value : public GenValue{
  319. public:
  320. Value(const std::string& name, const std::string& alias="")
  321. :GenValue(name, alias){ }
  322. /** Calculate, if necessary, and return the value held by this object.
  323. */
  324. virtual T& get_value() = 0;
  325. };
  326. /**
  327. * A value supplied by the dataset, not derived.
  328. * An ObservedValue is the interface to your dataset. Upon creation, an
  329. * ObservedValue is given a pointer to an object of type T. When an observation
  330. * is loaded into memory, the value at the location referenced by that pointer
  331. * must be updated with the associated data from that observation. This is the
  332. * responsibility of whatever DataSet implementation is being used. This object
  333. * then will read that data and return it when requested.
  334. */
  335. template <typename T>
  336. class ObservedValue : public Value<T>{
  337. private:
  338. T *val_ref;
  339. void _reset(){ }
  340. public:
  341. ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
  342. :Value<T>(name, alias),
  343. val_ref(val_ref){ }
  344. T& get_value(){
  345. return *val_ref;
  346. }
  347. };
  348. /**
  349. * A Value derived from some other Values, not directly from the dataset.
  350. * A DerivedValue is generally defined as some function of other Value objects.
  351. * For example, a Pair is a function of two other Value objects that makes a
  352. * pair of them. Note that these other Value objects are free to be either
  353. * ObservedValues or other DerivedValues.
  354. *
  355. * It is desireable from a performance standpoint that each DerivedValue be
  356. * calculated no more than once per observation. Therefore, when a get_value is
  357. * called on a DerivedValue, it first checks whether the value that it holds is
  358. * **valid**, meaning it has already been calculated for this observation. If
  359. * so, it simply returns the value. If not, the update_value function is called
  360. * to calculate the value. and then the newly calculated value is marked as
  361. * valid and returned.
  362. */
  363. template <typename T>
  364. class DerivedValue : public Value<T>{
  365. private:
  366. void _reset(){
  367. value_valid = false;
  368. }
  369. protected:
  370. T value;
  371. bool value_valid;
  372. /**
  373. * Updates the internal value.
  374. * This function should be overridden by any child class to do the
  375. * actual work of updating value based on whatever rules the class
  376. * chooses. Normally, this consists of geting the values from some
  377. * associated Value objects, doing some calculation on them, and
  378. * storing the result in value.
  379. */
  380. virtual void update_value() = 0;
  381. public:
  382. DerivedValue(const std::string& name, const std::string& alias="")
  383. :Value<T>(name, alias),
  384. value_valid(false) { }
  385. T& get_value(){
  386. if (!value_valid){
  387. update_value();
  388. value_valid = true;
  389. }
  390. return value;
  391. }
  392. };
  393. /**
  394. * A std::vector wrapper around a C-style array.
  395. * In order to make some of the higher-level Value types easier to work with,
  396. * it is a good idea to wrap all arrays in the original data source with
  397. * std::vector objects. To do this, it is necessary to supply both a Value
  398. * object containing the array itself as well as another Value object
  399. * containing the size of that array. Currently, update_value will simply copy
  400. * the contents of the array into the interally held vector.
  401. */
  402. template <typename T>
  403. class WrapperVector : public DerivedValue<std::vector<T> >{
  404. private:
  405. Value<int>* size;
  406. Value<T*>* data;
  407. void update_value(){
  408. int n = size->get_value();
  409. T* data_ref = data->get_value();
  410. this->value.assign(data_ref, data_ref+n);
  411. }
  412. public:
  413. WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
  414. :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
  415. size(size), data(data){ }
  416. };
  417. /**
  418. * Creates a std::pair type from a two other Value objects.
  419. */
  420. template <typename T1, typename T2>
  421. class Pair : public DerivedValue<std::pair<T1, T2> >{
  422. protected:
  423. std::pair<Value<T1>*, Value<T2>* > value_pair;
  424. void update_value(){
  425. this->value.first = value_pair.first->get_value();
  426. this->value.second = value_pair.second->get_value();
  427. }
  428. public:
  429. Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
  430. :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
  431. value_pair(value1, value2){ }
  432. };
  433. template<typename... T> class _Zip;
  434. template<>
  435. class _Zip<> {
  436. protected:
  437. int _get_size(){
  438. return std::numeric_limits<int>::max();
  439. }
  440. std::tuple<> _get_at(int idx){
  441. return std::make_tuple();
  442. }
  443. std::string _get_name(){
  444. return "";
  445. }
  446. public:
  447. _Zip() { }
  448. };
  449. template<typename Head, typename... Tail>
  450. class _Zip<Head, Tail...> : private _Zip<Tail...> {
  451. protected:
  452. Value<std::vector<Head>>* head;
  453. int _get_size(){
  454. int this_size = head->get_value().size();
  455. int rest_size = _Zip<Tail...>::_get_size();
  456. return std::min(this_size, rest_size);
  457. }
  458. typename std::tuple<Head,Tail...> _get_at(int idx){
  459. auto tail_tuple = _Zip<Tail...>::_get_at(idx);
  460. return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
  461. }
  462. std::string _get_name(){
  463. return head->get_name()+","+_Zip<Tail...>::_get_name();
  464. }
  465. public:
  466. _Zip() { }
  467. _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
  468. : _Zip<Tail...>(tail...),
  469. head(head) { }
  470. };
  471. /**
  472. * Zips a series of vectors together. Can be combined with Map to
  473. * yield a Value whose elements are individually a function of the
  474. * corresponding elements of the vectors that were zipped together. For those
  475. * familiar with python, it accompilishes the same thing as
  476. * @code{.py}
  477. * xs = [1,2,3,4]
  478. * ys = [10,20,30,40]
  479. * print(list(map(lambda t:t[0]+t[1],zip(xs,ys))))
  480. * @endcode
  481. * which outputs
  482. * @code
  483. * [11, 22, 33, 44]
  484. * @endcode
  485. */
  486. template <typename... ArgTypes>
  487. class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
  488. private _Zip<ArgTypes...>{
  489. protected:
  490. void update_value(){
  491. this->value.clear();
  492. int size = _Zip<ArgTypes...>::_get_size();
  493. for(int i=0; i<size; i++){
  494. this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
  495. }
  496. }
  497. std::string _get_name(){
  498. return "zip("+_Zip<ArgTypes...>::_get_name()+")";
  499. }
  500. public:
  501. Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
  502. :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
  503. _Zip<ArgTypes...>(args...) {
  504. this->set_name(_get_name());
  505. }
  506. };
  507. template<typename> class Map; // undefined
  508. /**
  509. * Maps a function over an input vector. The input vector must be a vector of
  510. * tuples, where the the elements of the tuple match the arguments of the
  511. * function. For example if the function takes two floats as arguments, the
  512. * tuple should contain two floats. The Value object required by Map will
  513. * typically be created as a Zip.
  514. */
  515. template <typename Ret, typename... ArgTypes>
  516. class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
  517. private:
  518. typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
  519. Function<Ret(ArgTypes...)>& fn;
  520. arg_type* arg;
  521. void update_value(){
  522. this->value.clear();
  523. for(auto tup : arg->get_value()){
  524. this->value.push_back(call(fn,tup));
  525. }
  526. }
  527. public:
  528. Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
  529. :DerivedValue<std::vector<Ret>>("map("+fn.get_name()+":"+arg->get_name()+")", alias),
  530. fn(fn), arg(arg){ }
  531. };
  532. /**
  533. * Returns the elements in a vector that pass a test function. The elements on
  534. * the vector must be tuples. Typically this will be used in conjunction with
  535. * Zip and Map.
  536. */
  537. template<typename... ArgTypes>
  538. class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
  539. private:
  540. typedef std::vector<std::tuple<ArgTypes...>> value_type;
  541. Function<bool(ArgTypes...)>& filter;
  542. Value<value_type>* arg;
  543. void update_value(){
  544. this->value.clear();
  545. for(auto val : arg->get_value()){
  546. if(call(filter,val))
  547. this->value.push_back(val);
  548. }
  549. }
  550. public:
  551. TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
  552. :DerivedValue<value_type>("filter("+filter.get_name()+":"+arg->get_name()+")", alias),
  553. filter(filter), arg(arg) { }
  554. };
  555. template<typename... T> class _Tuple;
  556. template<>
  557. class _Tuple<> {
  558. protected:
  559. std::tuple<> _get_value(){
  560. return std::make_tuple();
  561. }
  562. std::string _get_name(){
  563. return "";
  564. }
  565. public:
  566. _Tuple() { }
  567. };
  568. template<typename Head, typename... Tail>
  569. class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
  570. protected:
  571. Value<Head>* head;
  572. typename std::tuple<Head,Tail...> _get_value(){
  573. auto tail_tuple = _Tuple<Tail...>::_get_value();
  574. return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
  575. }
  576. std::string _get_name(){
  577. return head->get_name()+","+_Tuple<Tail...>::_get_name();
  578. }
  579. public:
  580. _Tuple() { }
  581. _Tuple(Value<Head>* head, Value<Tail>*... tail)
  582. : _Tuple<Tail...>(tail...),
  583. head(head) { }
  584. };
  585. /**
  586. * Takes a series of Value objects and bundles them together into a std::tuple
  587. * object. Typically, this is most usefull when one wants to apply a function
  588. * to a few values and store the result. This class can be used in conjunction
  589. * with Apply to achieve this.
  590. */
  591. template <typename... ArgTypes>
  592. class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
  593. private _Tuple<ArgTypes...>{
  594. protected:
  595. void update_value(){
  596. this->value = _Tuple<ArgTypes...>::_get_value();
  597. }
  598. std::string _get_name(){
  599. return "tuple("+_Tuple<ArgTypes...>::_get_name()+")";
  600. }
  601. public:
  602. Tuple(Value<ArgTypes>*... args, const std::string& alias)
  603. :DerivedValue<std::tuple<ArgTypes...>>("", alias),
  604. _Tuple<ArgTypes...>(args...) {
  605. this->set_name(_get_name());
  606. }
  607. };
  608. template<typename> class Apply; // undefined
  609. /**
  610. * Applies a function to a tuple of values and returns a value. This will
  611. * typically be called with a Tuple object as an argument.
  612. */
  613. template <typename Ret, typename... ArgTypes>
  614. class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
  615. private:
  616. Function<Ret(ArgTypes...)>& fn;
  617. Tuple<ArgTypes...>* arg;
  618. void update_value(){
  619. auto &tup = arg->get_value();
  620. this->value = call(fn, tup);
  621. }
  622. public:
  623. Apply(Function<Ret(ArgTypes...)>& fn, Tuple<ArgTypes...>* arg, const std::string& alias)
  624. :DerivedValue<Ret>("apply("+fn.get_name()+":"+arg->get_name()+")", alias),
  625. fn(fn), arg(arg){ }
  626. };
  627. /**
  628. * Returns the count of elements in the input vector passing a test function.
  629. */
  630. template<typename T>
  631. class Count : public DerivedValue<int>{
  632. private:
  633. Function<bool(T)>& selector;
  634. Value<std::vector<T> >* v;
  635. void update_value(){
  636. value = 0;
  637. for(auto val : v->get_value()){
  638. if(selector(val))
  639. value++;
  640. }
  641. }
  642. public:
  643. Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
  644. :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
  645. selector(selector), v(v) { }
  646. };
  647. /**
  648. * Returns the elements in a vector that pass a test function.
  649. */
  650. template<typename T>
  651. class Filter : public DerivedValue<std::vector<T>>{
  652. private:
  653. Function<bool(T)>& filter;
  654. Value<std::vector<T> >* v;
  655. void update_value(){
  656. this->value.clear();
  657. for(auto val : v->get_value()){
  658. if(selector(val))
  659. this->value.push_back(val);
  660. }
  661. }
  662. public:
  663. Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
  664. :DerivedValue<std::vector<T>>("filter("+filter.get_name()+":"+v->get_name()+")", alias),
  665. filter(filter), v(v) { }
  666. };
  667. /**
  668. * Reduce a Value of type vector<T> to just a T.
  669. * This is useful functionality to model, for instance, calculating the maximum
  670. * element of a vector, or a the mean. See child classes for specific
  671. * implementations.
  672. */
  673. template <typename T>
  674. class Reduce : public DerivedValue<T>{
  675. private:
  676. Function<T(std::vector<T>)>& reduce;
  677. void update_value(){
  678. this->value = reduce(v->get_value());
  679. }
  680. protected:
  681. Value<std::vector<T> >* v;
  682. public:
  683. Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
  684. :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
  685. reduce(reduce), v(v) { }
  686. };
  687. /**
  688. * Find and return the maximum value of a vector.
  689. */
  690. template <typename T>
  691. class Max : public Reduce<T>{
  692. public:
  693. Max(Value<std::vector<T>>* v, const std::string alias)
  694. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
  695. FUNC(([](std::vector<T> vec){
  696. return *std::max_element(vec.begin(), vec.end());}))),
  697. v, alias) { }
  698. };
  699. /**
  700. * Find and return the minimum value of a vector.
  701. */
  702. template <typename T>
  703. class Min : public Reduce<T>{
  704. public:
  705. Min(Value<std::vector<T>>* v, const std::string alias)
  706. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
  707. FUNC(([](std::vector<T> vec){
  708. return *std::min_element(vec.begin(), vec.end());}))),
  709. v, alias) { }
  710. };
  711. /**
  712. * Calculate the mean value of a vector.
  713. */
  714. template <typename T>
  715. class Mean : public Reduce<T>{
  716. public:
  717. Mean(Value<std::vector<T>>* v, const std::string alias)
  718. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
  719. FUNC(([](std::vector<T> vec){
  720. int n = 0; T sum = 0;
  721. for (T e : vec){ n++; sum += e; }
  722. return n>0 ? sum / n : 0; }))),
  723. v, alias) { }
  724. };
  725. /**
  726. * Calculate the range of the values in a vector
  727. */
  728. template <typename T>
  729. class Range : public Reduce<T>{
  730. public:
  731. Range(Value<std::vector<T>>* v, const std::string alias)
  732. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
  733. FUNC(([](std::vector<T> vec){
  734. auto minmax = std::minmax_element(vec.begin(), vec.end());
  735. return (*minmax.second) - (*minmax.first); }))),
  736. v, alias) { }
  737. };
  738. /**
  739. * Extract the element at a specific index from a vector.
  740. */
  741. template <typename T>
  742. class ElementOf : public Reduce<T>{
  743. public:
  744. ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
  745. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
  746. FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
  747. v, alias) { }
  748. };
  749. /**
  750. * Similar to Reduce, but returns a pair of a T and an int.
  751. * This is useful if you need to know where in the vector exists the element
  752. * being returned.
  753. */
  754. template <typename T>
  755. class ReduceIndex : public DerivedValue<std::pair<T, int> >{
  756. private:
  757. Function<std::pair<T,int>(std::vector<T>)>& reduce;
  758. Value<std::vector<T> >* v;
  759. void update_value(){
  760. this->value = reduce(v->get_value());
  761. }
  762. public:
  763. ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
  764. :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
  765. reduce(reduce), v(v) { }
  766. };
  767. /**
  768. * Find and return the maximum value of a vector and its index.
  769. */
  770. template <typename T>
  771. class MaxIndex : public ReduceIndex<T>{
  772. public:
  773. MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
  774. :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
  775. FUNC(([](std::vector<T> vec){
  776. auto elptr = std::max_element(vec.begin(), vec.end());
  777. return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
  778. v, alias) { }
  779. };
  780. /**
  781. * Find and return the minimum value of a vector and its index.
  782. */
  783. template <typename T>
  784. class MinIndex : public ReduceIndex<T>{
  785. public:
  786. MinIndex(Value<std::vector<T>>* v, const std::string alias="")
  787. :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
  788. FUNC(([](std::vector<T> vec){
  789. auto elptr = std::min_element(vec.begin(), vec.end());
  790. return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
  791. v, alias) { }
  792. };
  793. /**
  794. * Find and return the minimum value of a vector and its index.
  795. */
  796. template <typename FST, typename SND>
  797. class CartProduct : public DerivedValue<std::vector<std::tuple<FST,SND>>>{
  798. private:
  799. Value<std::vector<FST>>* val1;
  800. Value<std::vector<SND>>* val2;
  801. bool self_product;
  802. void update_value(){
  803. this->value.clear();
  804. auto& v1 = val1->get_value();
  805. auto& v2 = val2->get_value();
  806. for(int i=0; i<v1.size(); i++){
  807. int lower_lim = self_product ? i+1 : 0;
  808. for(int j=lower_lim; j<v2.size(); j++){
  809. this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
  810. }
  811. }
  812. }
  813. public:
  814. CartProduct(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string alias="")
  815. :DerivedValue<std::vector<std::tuple<FST,SND>>>("cartProduct("+
  816. val1->get_name()+","+
  817. val2->get_name()+")", alias),
  818. val1(val1),
  819. val2(val2),
  820. self_product(val1 == val2) { }
  821. };
  822. /**
  823. * A generic value owning only a function object.
  824. * All necessary values upon which this value depends must be bound to the
  825. * function object.
  826. */
  827. template <typename T>
  828. class BoundValue : public DerivedValue<T>{
  829. protected:
  830. Function<T()>& f;
  831. void update_value(){
  832. this->value = f();
  833. }
  834. public:
  835. BoundValue(Function<T()>& f, const std::string alias="")
  836. :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
  837. f(f) { }
  838. };
  839. /**
  840. * A Value of a pointer. The pointer is constant, however the data the pointer
  841. * points to is variable.
  842. */
  843. template <typename T>
  844. class PointerValue : public DerivedValue<T*>{
  845. protected:
  846. void update_value(){ }
  847. public:
  848. PointerValue(const std::string& name, T* ptr, const std::string alias="")
  849. :DerivedValue<T*>(name, alias){
  850. this->value = ptr;
  851. }
  852. };
  853. /**
  854. * A Value which always returns the same value, supplied in the constructor.
  855. */
  856. template <typename T>
  857. class ConstantValue : public DerivedValue<T>{
  858. protected:
  859. void update_value(){ }
  860. public:
  861. ConstantValue(const std::string& name, T const_value, const std::string alias="")
  862. :DerivedValue<T>("const::"+name, alias),
  863. Value<T>::value(const_value) { }
  864. };
  865. }
  866. #endif // value_hpp