value.hpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  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. // This calls a function of type F with the contents of the tuple as arguments
  77. template <typename F, typename Tuple>
  78. auto call(F f, Tuple && t)
  79. {
  80. typedef typename std::decay<Tuple>::type ttype;
  81. return call_impl<F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
  82. }
  83. template<typename> class Function; // undefined
  84. /**
  85. * Parent class to all Function classes. Holds a class-level collection of all
  86. * created function objects.
  87. */
  88. class GenFunction {
  89. private:
  90. std::string name;
  91. std::string impl;
  92. protected:
  93. inline static bool in_register_function=false;
  94. public:
  95. /**
  96. * Static mapping of functions from their name to the object wrapper of
  97. * the function.
  98. */
  99. inline static std::map<const std::string, GenFunction*> function_registry;
  100. GenFunction(const std::string& name, const std::string& impl)
  101. :name(name),
  102. impl(impl){ }
  103. virtual ~GenFunction() { };
  104. std::string& get_name(){
  105. return name;
  106. }
  107. /**
  108. * Attempt to invoke clang-format for the purpose of printing out
  109. * nicely formatted functions to the log file. If clang-format is not
  110. * present, this function just passes through the code unmodified.
  111. */
  112. static std::string format_code(const std::string& code){
  113. std::stringstream code_out("");
  114. std::string command("echo \""+code+"\" | clang-format");
  115. char buffer[255];
  116. FILE *stream = popen(command.c_str(), "r");
  117. while (fgets(buffer, 255, stream) != NULL)
  118. code_out << buffer;
  119. if (pclose(stream) == 0)
  120. return code_out.str();
  121. else
  122. return code;
  123. }
  124. static std::string summary(){
  125. std::stringstream ss;
  126. ss << "The following functions have been registered" << std::endl;
  127. for(auto p : function_registry){
  128. if (p.second == nullptr) continue;
  129. ss << "-->" << p.second->name << std::endl;
  130. ss << format_code(p.second->impl);
  131. }
  132. return ss.str();
  133. }
  134. template <typename T>
  135. static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
  136. in_register_function = true;
  137. Function<T>* func;
  138. if (GenFunction::function_registry[name] != nullptr){
  139. func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
  140. if (func == nullptr){
  141. ERROR("Trying to register function which has already been registered with a different type");
  142. }
  143. } else {
  144. func = new Function<T>(name, impl, f);
  145. GenFunction::function_registry[name] = func;
  146. }
  147. in_register_function = false;
  148. return *func;
  149. }
  150. };
  151. /**
  152. * In order to enable proper provenance tracking, and at the same time keep
  153. * the ability to embed functions into values, the Function class should be
  154. * used. It is simply a wrapper around a std::function that also has a name.
  155. * This name is used when generating the name of values that use the function.
  156. * A function name is automatically prepended with "func::" to explicitly state
  157. * that the value is the result of a computation encoded within the function
  158. * object, and not from some other Value object. Unfortunately, it is up to the
  159. * user to find where that function is defined in the source code to inspect
  160. * what it is doing. But hopefully this isn't too onerous by just using grep.
  161. */
  162. template <typename R, typename... ArgTypes>
  163. class Function<R(ArgTypes...)> : public GenFunction {
  164. private:
  165. std::function<R(ArgTypes...)> f;
  166. public:
  167. Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
  168. :GenFunction(name, impl), f(f){
  169. if (!in_register_function) {
  170. WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
  171. }
  172. }
  173. Function(const std::string& name, std::function<R(ArgTypes...)> f)
  174. :Function(name, "N/A", f){ }
  175. ~Function() { }
  176. R operator()(ArgTypes ...args){
  177. return f(args...);
  178. }
  179. };
  180. #define FUNC(f) f, #f
  181. /**
  182. * A type-agnostic value.
  183. * It is necessary to create a type-agnostic parent class to Value so that
  184. * it is possible to handle collections of them. GenValue also provides the
  185. * rest of the type-independent interface to Value.
  186. */
  187. class GenValue;
  188. typedef std::map<std::string, GenValue*> ValueSet;
  189. class GenValue{
  190. private:
  191. /**
  192. * The name of the value.
  193. * This is used to allow for dynamic lookup of
  194. * values based on their name via GenValue::get_value.
  195. */
  196. std::string name;
  197. protected:
  198. /**
  199. * Mark the internal value as invalid. This is needed for DerivedValue
  200. * to force a recalculation of the internal value when a new
  201. * observation is loaded into memory. It is called automatically for
  202. * all GenValue objects when reset is called.
  203. */
  204. virtual void _reset() = 0;
  205. /**
  206. * A static mapping containing all created Value objects.
  207. * Every value object must have a unique name, and this name is used as
  208. * a key in values to that object. This is used to enable more dynamic
  209. * creation of objects as well as avoiding the uneccesary passing of
  210. * pointers.
  211. */
  212. inline static std::map<const std::string, GenValue*> values;
  213. /**
  214. * Composite value names are typically nested. This makes complex
  215. * values have rather unwieldy names. Therefore, one can declare
  216. * aliases which allow for more human-usable names to be used. When a
  217. * value is requested by name, an alias with that value takes precidence
  218. * over a name with that value.
  219. */
  220. inline static std::map<const std::string, GenValue*> aliases;
  221. public:
  222. GenValue(const std::string& name, const std::string& alias)
  223. :name(name){
  224. values[name] = this;
  225. if (alias != "")
  226. GenValue::alias(alias, this);
  227. }
  228. const std::string& get_name(){
  229. return name;
  230. }
  231. void set_name(const std::string& new_name){
  232. values[name] = nullptr;
  233. name = new_name;
  234. values[name] = this;
  235. }
  236. static void reset(){
  237. for (auto val : values){
  238. if (val.second != nullptr){
  239. val.second->_reset();
  240. }
  241. }
  242. }
  243. static GenValue* get_value(const std::string& name){
  244. if (aliases[name] != nullptr)
  245. return aliases[name];
  246. else if (values[name] != nullptr)
  247. return values[name];
  248. else{
  249. ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
  250. << summary());
  251. CRITICAL("Aborting... :(",-1);
  252. }
  253. }
  254. static void alias(const std::string& name, GenValue* value){
  255. if (aliases[name] != nullptr){
  256. WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
  257. }
  258. aliases[name] = value;
  259. }
  260. static GenValue* alias(const std::string& name){
  261. if (values[name] != nullptr){
  262. WARNING("Alias \"" << name << "\" does not exist.");
  263. }
  264. return aliases[name];
  265. }
  266. static std::string summary(){
  267. std::stringstream ss;
  268. ss << "The following values have been created: " << std::endl;
  269. for (auto value : values){
  270. if (value.second == nullptr) continue;
  271. ss << "\t\"" << value.first << "\" at address " << value.second << std::endl;
  272. }
  273. ss << "And these aliases:" << std::endl;
  274. for (auto alias : aliases){
  275. std::string orig("VOID");
  276. if (alias.second == nullptr) continue;
  277. for (auto value : values){
  278. if (alias.second == value.second){
  279. orig = value.second->get_name();
  280. break;
  281. }
  282. }
  283. ss << "\t\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
  284. }
  285. return ss.str();
  286. }
  287. friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
  288. };
  289. std::ostream& operator<<(std::ostream& os, GenValue& gv){
  290. os << gv.get_name();
  291. return os;
  292. }
  293. /**
  294. * A generic value.
  295. * In order to facilitate run-time creation of analysis routines, it is
  296. * necessary to have some ability to get and store *values*. Values can either
  297. * be directly taken from some original data source (i.e. ObservedValue), or
  298. * they can be a function of some other set of values (i.e. DerivedValue). They
  299. * template class T of Value<T> is the type of thing that is returned upon
  300. * calling get_value().
  301. */
  302. template <typename T>
  303. class Value : public GenValue{
  304. public:
  305. Value(const std::string& name, const std::string& alias="")
  306. :GenValue(name, alias){ }
  307. /** Calculate, if necessary, and return the value held by this object.
  308. */
  309. virtual T& get_value() = 0;
  310. };
  311. /**
  312. * A generic, observed, value.
  313. * An ObservedValue is the interface to your dataset. Upon creation, an
  314. * ObservedValue is given a pointer to an object of type T. When an observation
  315. * is loaded into memory, the value at the location referenced by that pointer
  316. * must be updated with the associated data from that observation. This is the
  317. * responsibility of whatever DataSet implementation is being used. This object
  318. * then will read that data and return it when requested.
  319. */
  320. template <typename T>
  321. class ObservedValue : public Value<T>{
  322. private:
  323. T *val_ref;
  324. void _reset(){ }
  325. public:
  326. ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
  327. :Value<T>(name, alias),
  328. val_ref(val_ref){ }
  329. T& get_value(){
  330. return *val_ref;
  331. }
  332. };
  333. /**
  334. * A generic, derived, value.
  335. * A DerivedValue is generally defined as some function of other Value objects.
  336. * For example, a Pair is a function of two other Value objects that makes a
  337. * pair of them. Note that these other Value objects are free to be either
  338. * ObservedValues or other DerivedValues.
  339. *
  340. * It is desireable from a performance standpoint that each DerivedValue be
  341. * calculated no more than once per observation. Therefore, when a get_value is
  342. * called on a DerivedValue, it first checks whether the value that it holds is
  343. * **valid**, meaning it has already been calculated for this observation. If
  344. * so, it simply returns the value. If not, the update_value function is called
  345. * to calculate the value. and then the newly calculated value is marked as
  346. * valid and returned.
  347. */
  348. template <typename T>
  349. class DerivedValue : public Value<T>{
  350. private:
  351. void _reset(){
  352. value_valid = false;
  353. }
  354. protected:
  355. T value;
  356. bool value_valid;
  357. /**
  358. * Updates the internal value.
  359. * This function should be overridden by any child class to do the
  360. * actual work of updating value based on whatever rules the class
  361. * chooses. Normally, this consists of geting the values from some
  362. * associated Value objects, doing some calculation on them, and
  363. * storing the result in value.
  364. */
  365. virtual void update_value() = 0;
  366. public:
  367. DerivedValue(const std::string& name, const std::string& alias="")
  368. :Value<T>(name, alias),
  369. value_valid(false) { }
  370. T& get_value(){
  371. /* std::cout << "getting value of " << this->get_name() << std::endl; */
  372. if (!value_valid){
  373. update_value();
  374. value_valid = true;
  375. }
  376. return value;
  377. }
  378. };
  379. /**
  380. * A std::vector wrapper around a C-style array.
  381. * In order to make some of the higher-level Value types easier to work with,
  382. * it is a good idea to wrap all arrays in the original data source with
  383. * std::vector objects. To do this, it is necessary to supply both a Value
  384. * object containing the array itself as well as another Value object
  385. * containing the size of that array. Currently, update_value will simply copy
  386. * the contents of the array into the interally held vector.
  387. */
  388. template <typename T>
  389. class WrapperVector : public DerivedValue<std::vector<T> >{
  390. private:
  391. Value<int>* size;
  392. Value<T*>* data;
  393. void update_value(){
  394. int n = size->get_value();
  395. T* data_ref = data->get_value();
  396. this->value.assign(data_ref, data_ref+n);
  397. }
  398. public:
  399. WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
  400. :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
  401. size(size), data(data){ }
  402. };
  403. /**
  404. * Creates a std::pair type from a two other Value objects.
  405. */
  406. template <typename T1, typename T2>
  407. class Pair : public DerivedValue<std::pair<T1, T2> >{
  408. protected:
  409. std::pair<Value<T1>*, Value<T2>* > value_pair;
  410. void update_value(){
  411. this->value.first = value_pair.first->get_value();
  412. this->value.second = value_pair.second->get_value();
  413. }
  414. public:
  415. Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
  416. :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
  417. value_pair(value1, value2){ }
  418. };
  419. template<typename... T> class _Zip;
  420. template<>
  421. class _Zip<> {
  422. protected:
  423. int _get_size(){
  424. return std::numeric_limits<int>::max();
  425. }
  426. std::tuple<> _get_at(int idx){
  427. return std::make_tuple();
  428. }
  429. bool _verify_integrity() {
  430. return true;
  431. }
  432. std::string _get_name(){
  433. return "";
  434. }
  435. public:
  436. _Zip() { }
  437. };
  438. template<typename Head, typename... Tail>
  439. class _Zip<Head, Tail...> : private _Zip<Tail...> {
  440. protected:
  441. Value<std::vector<Head>>* head;
  442. int _get_size(){
  443. int this_size = head->get_value().size();
  444. int rest_size = _Zip<Tail...>::_get_size();
  445. return std::min(this_size, rest_size);
  446. }
  447. typename std::tuple<Head,Tail...> _get_at(int idx){
  448. auto tail_tuple = _Zip<Tail...>::_get_at(idx);
  449. return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
  450. }
  451. bool _verify_integrity() {
  452. return (head != nullptr) &&_Zip<Tail...>::_verify_integrity();
  453. }
  454. std::string _get_name(){
  455. return head->get_name()+","+_Zip<Tail...>::_get_name();
  456. }
  457. public:
  458. _Zip() { }
  459. _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
  460. : _Zip<Tail...>(tail...),
  461. head(head) { }
  462. };
  463. /**
  464. * Zips a series of observations together
  465. */
  466. template <typename... ArgTypes>
  467. class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
  468. private _Zip<ArgTypes...>{
  469. protected:
  470. void update_value(){
  471. this->value.clear();
  472. int size = _Zip<ArgTypes...>::_get_size();
  473. for(int i=0; i<size; i++){
  474. this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
  475. }
  476. }
  477. std::string _get_name(){
  478. return "zip("+_Zip<ArgTypes...>::_get_name()+")";
  479. }
  480. public:
  481. Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
  482. :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
  483. _Zip<ArgTypes...>(args...) {
  484. this->set_name(_get_name());
  485. }
  486. };
  487. template<typename> class MapOver; // undefined
  488. template <typename Ret, typename... ArgTypes>
  489. class MapOver<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
  490. private:
  491. Function<Ret(ArgTypes...)>& fn;
  492. Zip<ArgTypes...>* arg;
  493. void update_value(){
  494. this->value.clear();
  495. for(auto tup : arg->get_value()){
  496. this->value.push_back(call(fn,tup));
  497. }
  498. }
  499. public:
  500. MapOver(Function<Ret(ArgTypes...)>& fn, Zip<ArgTypes...>* arg, const std::string& alias)
  501. :DerivedValue<std::vector<Ret>>("map_over("+fn.get_name()+":"+arg->get_name()+")", alias),
  502. fn(fn), arg(arg){ }
  503. };
  504. /**
  505. * Takes a set of four Value<std::vector<T> > objects and a function of four Ts
  506. * and returns a std::vector<R>. This is used in, for instance, calculating the
  507. * energy of a set of particles when one has separate arrays containing pt,
  508. * eta, phi, and mass. These arrays are first wrapped up in VectorWrappers and
  509. * then passes along with a function to calculate the energy into a ZipMapFour.
  510. * The result of this calculation is a new vector containing the energy for
  511. * each particle. Note that if the input vectors are not all the same size,
  512. * calculations are only performed up to the size of the shortest.
  513. * \see MiniTreeDataSet
  514. * \todo find way to implement for arbitrary number(and possibly type) of
  515. * vector inputs.
  516. */
  517. template <typename R, typename T>
  518. class ZipMapFour : public DerivedValue<std::vector<R> >{
  519. private:
  520. Function<R(T, T, T, T)>& f;
  521. Value<std::vector<T> >* v1;
  522. Value<std::vector<T> >* v2;
  523. Value<std::vector<T> >* v3;
  524. Value<std::vector<T> >* v4;
  525. void update_value(){
  526. std::vector<T> v1_val = v1->get_value();
  527. std::vector<T> v2_val = v2->get_value();
  528. std::vector<T> v3_val = v3->get_value();
  529. std::vector<T> v4_val = v4->get_value();
  530. int n;
  531. std::tie(n, std::ignore) = std::minmax({v1_val.size(), v2_val.size(), v3_val.size(), v4_val.size()});
  532. this->value.resize(n);
  533. for (int i=0; i<n; i++){
  534. this->value[i] = f(v1_val[i], v2_val[i], v3_val[i], v4_val[i]);
  535. }
  536. }
  537. public:
  538. ZipMapFour(Function<R(T, T, T, T)>& f,
  539. Value<std::vector<T> >* v1, Value<std::vector<T> >* v2,
  540. Value<std::vector<T> >* v3, Value<std::vector<T> >* v4, const std::string alias)
  541. :DerivedValue<std::vector<R> >("zipmap("+f.get_name()+":"+v1->get_name()+","+v2->get_name()+","+
  542. v3->get_name()+","+v4->get_name()+")", alias),
  543. f(f), v1(v1), v2(v2), v3(v3), v4(v4) { }
  544. ZipMapFour(Function<R(T, T, T, T)>& f,
  545. const std::string& label1, const std::string& label2,
  546. const std::string& label3, const std::string& label4, const std::string alias)
  547. :ZipMapFour(f,
  548. dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label1)),
  549. dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label2)),
  550. dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label3)),
  551. dynamic_cast<Value<std::vector<T> >*>(GenValue::get_value(label4)),
  552. alias){ }
  553. };
  554. /**
  555. * Returns the count of elements in the input vector passing a test function.
  556. */
  557. template<typename T>
  558. class Count : public DerivedValue<int>{
  559. private:
  560. Function<bool(T)>& selector;
  561. Value<std::vector<T> >* v;
  562. void update_value(){
  563. value = 0;
  564. for(auto val : v->get_value()){
  565. if(selector(val))
  566. value++;
  567. }
  568. }
  569. public:
  570. Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
  571. :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
  572. selector(selector), v(v) { }
  573. };
  574. /**
  575. * Reduce a Value of type vector<T> to just a T.
  576. * This is useful functionality to model, for instance, calculating the maximum
  577. * element of a vector, or a the mean. See child classes for specific
  578. * implementations.
  579. */
  580. template <typename T>
  581. class Reduce : public DerivedValue<T>{
  582. private:
  583. Function<T(std::vector<T>)>& reduce;
  584. void update_value(){
  585. this->value = reduce(v->get_value());
  586. }
  587. protected:
  588. Value<std::vector<T> >* v;
  589. public:
  590. Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
  591. :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
  592. reduce(reduce), v(v) { }
  593. };
  594. /**
  595. * Find and return the maximum value of a vector.
  596. */
  597. template <typename T>
  598. class Max : public Reduce<T>{
  599. public:
  600. Max(Value<std::vector<T>>* v, const std::string alias)
  601. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
  602. FUNC(([](std::vector<T> vec){
  603. return *std::max_element(vec.begin(), vec.end());}))),
  604. v, alias) { }
  605. };
  606. /**
  607. * Find and return the minimum value of a vector.
  608. */
  609. template <typename T>
  610. class Min : public Reduce<T>{
  611. public:
  612. Min(Value<std::vector<T>>* v, const std::string alias)
  613. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
  614. FUNC(([](std::vector<T> vec){
  615. return *std::min_element(vec.begin(), vec.end());}))),
  616. v, alias) { }
  617. };
  618. /**
  619. * Calculate the mean value of a vector.
  620. */
  621. template <typename T>
  622. class Mean : public Reduce<T>{
  623. public:
  624. Mean(Value<std::vector<T>>* v, const std::string alias)
  625. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
  626. FUNC(([](std::vector<T> vec){
  627. int n = 0; T sum = 0;
  628. for (T e : vec){ n++; sum += e; }
  629. return n>0 ? sum / n : 0; }))),
  630. v, alias) { }
  631. };
  632. /**
  633. * Calculate the range of the values in a vector
  634. */
  635. template <typename T>
  636. class Range : public Reduce<T>{
  637. public:
  638. Range(Value<std::vector<T>>* v, const std::string alias)
  639. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
  640. FUNC(([](std::vector<T> vec){
  641. auto minmax = std::minmax_element(vec.begin(), vec.end());
  642. return (*minmax.second) - (*minmax.first); }))),
  643. v, alias) { }
  644. };
  645. /**
  646. * Extract the element at a specific index from a vector.
  647. */
  648. template <typename T>
  649. class ElementOf : public Reduce<T>{
  650. public:
  651. ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
  652. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
  653. FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
  654. v, alias) { }
  655. };
  656. /**
  657. * Similar to Reduce, but returns a pair of a T and an int.
  658. * This is useful if you need to know where in the vector exists the element
  659. * being returned.
  660. */
  661. template <typename T>
  662. class ReduceIndex : public DerivedValue<std::pair<T, int> >{
  663. private:
  664. Function<std::pair<T,int>(std::vector<T>)>& reduce;
  665. Value<std::vector<T> >* v;
  666. void update_value(){
  667. this->value = reduce(v->get_value());
  668. }
  669. public:
  670. ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
  671. :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
  672. reduce(reduce), v(v) { }
  673. };
  674. /**
  675. * Find and return the maximum value of a vector and its index.
  676. */
  677. template <typename T>
  678. class MaxIndex : public ReduceIndex<T>{
  679. public:
  680. MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
  681. :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
  682. FUNC(([](std::vector<T> vec){
  683. auto elptr = std::max_element(vec.begin(), vec.end());
  684. return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
  685. v, alias) { }
  686. };
  687. /**
  688. * Find and return the minimum value of a vector and its index.
  689. */
  690. template <typename T>
  691. class MinIndex : public ReduceIndex<T>{
  692. public:
  693. MinIndex(Value<std::vector<T>>* v, const std::string alias="")
  694. :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
  695. FUNC(([](std::vector<T> vec){
  696. auto elptr = std::min_element(vec.begin(), vec.end());
  697. return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
  698. v, alias) { }
  699. };
  700. /**
  701. * A generic value owning only a function object.
  702. * All necessary values upon which this value depends must be bound to the
  703. * function object.
  704. */
  705. template <typename T>
  706. class BoundValue : public DerivedValue<T>{
  707. protected:
  708. Function<T()>& f;
  709. void update_value(){
  710. this->value = f();
  711. }
  712. public:
  713. BoundValue(Function<T()>& f, const std::string alias="")
  714. :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
  715. f(f) { }
  716. };
  717. /**
  718. * A Value of a pointer. The pointer is constant, however the data the pointer
  719. * points to is variable.
  720. */
  721. template <typename T>
  722. class PointerValue : public DerivedValue<T*>{
  723. protected:
  724. void update_value(){ }
  725. public:
  726. PointerValue(const std::string& name, T* ptr, const std::string alias="")
  727. :DerivedValue<T*>(name, alias){
  728. this->value = ptr;
  729. }
  730. };
  731. /**
  732. * A Value which always returns the same value, supplied in the constructor.
  733. */
  734. template <typename T>
  735. class ConstantValue : public DerivedValue<T>{
  736. protected:
  737. void update_value(){ }
  738. public:
  739. ConstantValue(const std::string& name, T const_value, const std::string alias="")
  740. :DerivedValue<T>("const::"+name, alias),
  741. Value<T>::value(const_value) { }
  742. };
  743. }
  744. #endif // value_hpp