value.hpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  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. namespace detail {
  61. template<typename T, int N, bool Done, typename... TYPES>
  62. struct _HomoTuple {
  63. typedef _HomoTuple<T, N, sizeof...(TYPES)+1==N, TYPES..., T> stype;
  64. typedef typename stype::type type;
  65. };
  66. template<typename T, int N, typename... TYPES>
  67. struct _HomoTuple<T, N, true, TYPES...> {
  68. typedef std::tuple<TYPES...> type;
  69. };
  70. }
  71. template<typename T, int N>
  72. struct HomoTuple {
  73. typedef detail::_HomoTuple<T, N, N==0> stype;
  74. typedef typename stype::type type;
  75. };
  76. namespace detail {
  77. // Convert array into a tuple
  78. template<typename Array, std::size_t... I>
  79. decltype(auto) a2t_impl(const Array& a, std::index_sequence<I...>){
  80. return std::make_tuple(a[I]...);
  81. }
  82. }
  83. /**
  84. * Converts a std::vector to a std::tuple.
  85. */
  86. template<typename T, std::size_t N, typename Indices = std::make_index_sequence<N>>
  87. decltype(auto) a2t(const std::array<T, N>& a){
  88. return detail::a2t_impl(a, Indices());
  89. }
  90. namespace detail {
  91. template <class F, class Tuple, std::size_t... I>
  92. constexpr decltype(auto) call_impl(F &&f, Tuple &&t, std::index_sequence<I...>){
  93. return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
  94. }
  95. }
  96. template <class F, class Tuple>
  97. constexpr decltype(auto) call(F &&f, Tuple &&t){
  98. return detail::call_impl(
  99. std::forward<F>(f), std::forward<Tuple>(t),
  100. std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
  101. }
  102. namespace detail{
  103. template <typename T, int N, int I>
  104. struct t2s_impl{
  105. public:
  106. static std::string cvt(typename HomoTuple<T,N>::type& tup, std::function<std::string(T)>& f){
  107. std::stringstream ss;
  108. ss << f(std::get<N-I>(tup)) << ", " << t2s_impl<T, N, I+1>::cvt(tup, f);
  109. return ss.str();
  110. }
  111. };
  112. template <typename T, int N>
  113. struct t2s_impl<T, N, 0>{
  114. public:
  115. static std::string cvt(typename HomoTuple<T,N>::type&, std::function<std::string(T)>&){
  116. return "";
  117. }
  118. };
  119. }
  120. template <typename T, int N>
  121. std::string t2s(typename HomoTuple<T,N>::type& tup, std::function<std::string(T)>& f){
  122. return detail::t2s_impl<T, N, N>(tup, f);
  123. }
  124. template<typename> class Function; // undefined
  125. /**
  126. * Parent class to all Function classes. Holds a class-level collection of all
  127. * created function objects.
  128. */
  129. class GenFunction {
  130. private:
  131. std::string name;
  132. std::string impl;
  133. protected:
  134. inline static bool in_register_function=false;
  135. public:
  136. /**
  137. * Static mapping of functions from their name to the object wrapper of
  138. * the function.
  139. */
  140. inline static std::map<const std::string, GenFunction*> function_registry;
  141. GenFunction(const std::string& name, const std::string& impl)
  142. :name(name),
  143. impl(impl){ }
  144. virtual ~GenFunction() { };
  145. std::string& get_name(){
  146. return name;
  147. }
  148. /**
  149. * Attempt to invoke clang-format for the purpose of printing out
  150. * nicely formatted functions to the log file. If clang-format is not
  151. * present, this function just passes through the code unmodified.
  152. */
  153. static std::string format_code(const std::string& code){
  154. std::stringstream code_out("");
  155. std::string command("echo \""+code+"\" | clang-format");
  156. char buffer[255];
  157. FILE *stream = popen(command.c_str(), "r");
  158. while (fgets(buffer, 255, stream) != NULL)
  159. code_out << buffer;
  160. if (pclose(stream) == 0)
  161. return code_out.str();
  162. else
  163. return code;
  164. }
  165. static std::string summary(){
  166. std::stringstream ss;
  167. ss << "The following functions have been registered" << std::endl;
  168. for(auto p : function_registry){
  169. if (p.second == nullptr) continue;
  170. ss << "FUNCTION::" << p.second->name << "@" << p.second << std::endl;
  171. ss << format_code(p.second->impl);
  172. }
  173. return ss.str();
  174. }
  175. template <typename T>
  176. static Function<T>& register_function(const std::string& name, std::function<T> f, const std::string& impl){
  177. in_register_function = true;
  178. Function<T>* func;
  179. if (GenFunction::function_registry[name] != nullptr){
  180. func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
  181. if (func == nullptr){
  182. ERROR("Trying to register function which has already been registered with a different type");
  183. }
  184. } else {
  185. func = new Function<T>(name, impl, f);
  186. GenFunction::function_registry[name] = func;
  187. }
  188. in_register_function = false;
  189. return *func;
  190. }
  191. template <typename T>
  192. static Function<T>& lookup_function(const std::string& name){
  193. if (GenFunction::function_registry[name] == nullptr){
  194. CRITICAL("Function \"" << name << "\" not previously registered", -1);
  195. } else {
  196. Function<T>* func = dynamic_cast<Function<T>*>(GenFunction::function_registry[name]);
  197. if (func == nullptr){
  198. CRITICAL("Function \"" << name << "\" request and register have mismatched types", -1);
  199. }
  200. return *GenFunction::function_registry[name];
  201. }
  202. }
  203. };
  204. /**
  205. * In order to enable proper provenance tracking, and at the same time keep
  206. * the ability to embed functions into values, the Function class should be
  207. * used. It is simply a wrapper around a std::function that also has a name.
  208. * This name is used when generating the name of values that use the function.
  209. * A function name is automatically prepended with "func::" to explicitly state
  210. * that the value is the result of a computation encoded within the function
  211. * object, and not from some other Value object. Unfortunately, it is up to the
  212. * user to find where that function is defined in the source code to inspect
  213. * what it is doing. But hopefully this isn't too onerous by just using grep.
  214. */
  215. template <typename R, typename... ArgTypes>
  216. class Function<R(ArgTypes...)> : public GenFunction {
  217. private:
  218. std::function<R(ArgTypes...)> f;
  219. public:
  220. Function(const std::string& name, const std::string& impl, std::function<R(ArgTypes...)> f)
  221. :GenFunction(name, impl), f(f){
  222. if (!in_register_function) {
  223. WARNING("Don't instantiate Function objects directly! Use GenFunction::register_function instead.");
  224. }
  225. }
  226. Function(const std::string& name, std::function<R(ArgTypes...)> f)
  227. :Function(name, "N/A", f){ }
  228. ~Function() { }
  229. R operator()(ArgTypes ...args){
  230. return f(args...);
  231. }
  232. };
  233. #define FUNC(f) f, #f
  234. /**
  235. * A type-agnostic value.
  236. * It is necessary to create a type-agnostic parent class to Value so that
  237. * it is possible to handle collections of them. GenValue also provides the
  238. * rest of the type-independent interface to Value.
  239. */
  240. class GenValue;
  241. typedef std::map<std::string, GenValue*> ValueSet;
  242. class GenValue{
  243. private:
  244. /**
  245. * The name of the value.
  246. * This is used to allow for dynamic lookup of
  247. * values based on their name via GenValue::get_value.
  248. */
  249. std::string name;
  250. protected:
  251. /**
  252. * Mark the internal value as invalid. This is needed for DerivedValue
  253. * to force a recalculation of the internal value when a new
  254. * observation is loaded into memory. It is called automatically for
  255. * all GenValue objects when reset is called.
  256. */
  257. bool value_valid;
  258. void _reset(){
  259. /* if (this->logging_enabled){ */
  260. /* std::cout << "Resetting validity for " << this->get_name() << std::endl; */
  261. /* } */
  262. /* std::cout << "Resetting validity for " << this->get_name() << std::endl; */
  263. this->value_valid = false;
  264. }
  265. /**
  266. * A static mapping containing all created Value objects.
  267. * Every value object must have a unique name, and this name is used as
  268. * a key in values to that object. This is used to enable more dynamic
  269. * creation of objects as well as avoiding the uneccesary passing of
  270. * pointers.
  271. */
  272. inline static std::map<const std::string, GenValue*> values;
  273. /**
  274. * Composite value names are typically nested. This makes complex
  275. * values have rather unwieldy names. Therefore, one can declare
  276. * aliases which allow for more human-usable names to be used. When a
  277. * value is requested by name, an alias with that value takes precidence
  278. * over a name with that value.
  279. */
  280. inline static std::map<const std::string, GenValue*> aliases;
  281. bool logging_enabled;
  282. public:
  283. GenValue(const std::string& name, const std::string& alias)
  284. :name(name),
  285. value_valid(false),
  286. logging_enabled(false){
  287. INFO("Registered value: \"" << name << "\" with alias: \"" << alias << "\"");
  288. values[name] = this;
  289. if (alias != "")
  290. GenValue::alias(alias, this);
  291. }
  292. const std::string& get_name(){
  293. return name;
  294. }
  295. void set_name(const std::string& new_name){
  296. values[name] = nullptr;
  297. name = new_name;
  298. values[name] = this;
  299. }
  300. virtual void log() = 0;
  301. static void reset(){
  302. for (auto val : values){
  303. if (val.second != nullptr){
  304. val.second->_reset();
  305. }
  306. }
  307. }
  308. static GenValue* get_value(const std::string& name){
  309. if (aliases[name] != nullptr)
  310. return aliases[name];
  311. else if (values[name] != nullptr)
  312. return values[name];
  313. else{
  314. ERROR("Could not find alias or value \"" << name << "\". I'll tell you the ones I know about." << std::endl
  315. << summary());
  316. CRITICAL("Aborting... :(",-1);
  317. }
  318. }
  319. static void alias(const std::string& name, GenValue* value){
  320. if (aliases[name] != nullptr){
  321. WARNING("WARNING: alias \"" << name << "\" overrides previous entry.");
  322. }
  323. aliases[name] = value;
  324. }
  325. static GenValue* alias(const std::string& name){
  326. if (values[name] != nullptr){
  327. WARNING("Alias \"" << name << "\" does not exist.");
  328. }
  329. return aliases[name];
  330. }
  331. static std::string summary(){
  332. std::stringstream ss;
  333. ss << "The following values have been created:" << std::endl;
  334. for (auto value : values){
  335. if (value.second == nullptr) continue;
  336. ss << "\tVALUE::\"" << value.first << "\" at address " << value.second << std::endl;
  337. }
  338. ss << "And these aliases:" << std::endl;
  339. for (auto alias : aliases){
  340. std::string orig("VOID");
  341. if (alias.second == nullptr) continue;
  342. for (auto value : values){
  343. if (alias.second == value.second){
  344. orig = value.second->get_name();
  345. break;
  346. }
  347. }
  348. ss << "\tALIAS::\"" << alias.first << "\" referring to \"" << orig << "\"" << std::endl;
  349. }
  350. return ss.str();
  351. }
  352. friend std::ostream& operator<<(std::ostream& os, const GenValue& gv);
  353. };
  354. std::ostream& operator<<(std::ostream& os, GenValue& gv){
  355. os << gv.get_name();
  356. return os;
  357. }
  358. /**
  359. * A generic value.
  360. * In order to facilitate run-time creation of analysis routines, it is
  361. * necessary to have some ability to get and store *values*. Values can either
  362. * be directly taken from some original data source (i.e. ObservedValue), or
  363. * they can be a function of some other set of values (i.e. DerivedValue). They
  364. * template class T of Value<T> is the type of thing that is returned upon
  365. * calling get_value().
  366. */
  367. template <typename T>
  368. class Value : public GenValue{
  369. protected:
  370. std::function<std::string(T)> value_to_string;
  371. public:
  372. Value(const std::string& name, const std::string& alias="")
  373. :value_to_string([](T){return "";}),
  374. GenValue(name, alias){ }
  375. /** Calculate, if necessary, and return the value held by this object.
  376. */
  377. virtual T& get_value() = 0;
  378. void enable_logging(const std::function<std::string(T)>& value_to_string = [](T){return "";}){
  379. logging_enabled = true;
  380. this->value_to_string = value_to_string;
  381. }
  382. void disable_logging(){
  383. logging_enabled = false;
  384. }
  385. };
  386. /**
  387. * A value supplied by the dataset, not derived.
  388. * An ObservedValue is the interface to your dataset. Upon creation, an
  389. * ObservedValue is given a pointer to an object of type T. When an observation
  390. * is loaded into memory, the value at the location referenced by that pointer
  391. * must be updated with the associated data from that observation. This is the
  392. * responsibility of whatever DataSet implementation is being used. This object
  393. * then will read that data and return it when requested.
  394. */
  395. template <typename T>
  396. class ObservedValue : public Value<T>{
  397. private:
  398. T *val_ref;
  399. public:
  400. ObservedValue(const std::string& name, T* val_ref, const std::string& alias="")
  401. :Value<T>(name, alias),
  402. val_ref(val_ref){ }
  403. void log(){
  404. if(this->logging_enabled){
  405. INFO(this->get_name() << ": " << this->value_to_string(*val_ref));
  406. }
  407. }
  408. T& get_value(){
  409. if (!this->value_valid){
  410. this->value_valid = true;
  411. this->log();
  412. }
  413. return *val_ref;
  414. }
  415. };
  416. /**
  417. * A Value derived from some other Values, not directly from the dataset.
  418. * A DerivedValue is generally defined as some function of other Value objects.
  419. * For example, a Pair is a function of two other Value objects that makes a
  420. * pair of them. Note that these other Value objects are free to be either
  421. * ObservedValues or other DerivedValues.
  422. *
  423. * It is desireable from a performance standpoint that each DerivedValue be
  424. * calculated no more than once per observation. Therefore, when a get_value is
  425. * called on a DerivedValue, it first checks whether the value that it holds is
  426. * **valid**, meaning it has already been calculated for this observation. If
  427. * so, it simply returns the value. If not, the update_value function is called
  428. * to calculate the value. and then the newly calculated value is marked as
  429. * valid and returned.
  430. */
  431. template <typename T>
  432. class DerivedValue : public Value<T>{
  433. protected:
  434. T value;
  435. /**
  436. * Updates the internal value.
  437. * This function should be overridden by any child class to do the
  438. * actual work of updating value based on whatever rules the class
  439. * chooses. Normally, this consists of geting the values from some
  440. * associated Value objects, doing some calculation on them, and
  441. * storing the result in value.
  442. */
  443. virtual void update_value() = 0;
  444. public:
  445. DerivedValue(const std::string& name, const std::string& alias="")
  446. :Value<T>(name, alias){ }
  447. void log(){
  448. if(this->logging_enabled){
  449. INFO(this->get_name() << ": " << this->value_to_string(value));
  450. }
  451. }
  452. T& get_value(){
  453. /* if (this->logging_enabled){ */
  454. /* std::cout << "Getting value for " << this->get_name() << std::endl; */
  455. /* } */
  456. if (!this->value_valid){
  457. /* if (this->logging_enabled){ */
  458. /* std::cout << "Updating value for " << this->get_name() << std::endl; */
  459. /* } */
  460. update_value();
  461. this->value_valid = true;
  462. this->log();
  463. }
  464. return value;
  465. }
  466. };
  467. /**
  468. * A std::vector wrapper around a C-style array.
  469. * In order to make some of the higher-level Value types easier to work with,
  470. * it is a good idea to wrap all arrays in the original data source with
  471. * std::vector objects. To do this, it is necessary to supply both a Value
  472. * object containing the array itself as well as another Value object
  473. * containing the size of that array. Currently, update_value will simply copy
  474. * the contents of the array into the interally held vector.
  475. */
  476. template <typename T>
  477. class WrapperVector : public DerivedValue<std::vector<T> >{
  478. private:
  479. Value<int>* size;
  480. Value<T*>* data;
  481. void update_value(){
  482. int n = size->get_value();
  483. T* data_ref = data->get_value();
  484. this->value.assign(data_ref, data_ref+n);
  485. }
  486. public:
  487. WrapperVector(Value<int>* size, Value<T*>* data, const std::string& alias="")
  488. :DerivedValue<std::vector<T> >("vectorOf("+size->get_name()+","+data->get_name()+")", alias),
  489. size(size), data(data){ }
  490. };
  491. /**
  492. * Creates a std::pair type from a two other Value objects.
  493. */
  494. template <typename T1, typename T2>
  495. class Pair : public DerivedValue<std::pair<T1, T2> >{
  496. protected:
  497. std::pair<Value<T1>*, Value<T2>* > value_pair;
  498. void update_value(){
  499. this->value.first = value_pair.first->get_value();
  500. this->value.second = value_pair.second->get_value();
  501. }
  502. public:
  503. Pair(Value<T1> *value1, Value<T2> *value2, const std::string alias="")
  504. :DerivedValue<std::pair<T1, T2> >("pair("+value1->get_name()+","+value2->get_name()+")", alias),
  505. value_pair(value1, value2){ }
  506. };
  507. template<typename... T> class _Zip;
  508. template<>
  509. class _Zip<> {
  510. protected:
  511. int _get_size(){
  512. return std::numeric_limits<int>::max();
  513. }
  514. std::tuple<> _get_at(int){
  515. return std::make_tuple();
  516. }
  517. std::string _get_name(){
  518. return "";
  519. }
  520. public:
  521. _Zip() { }
  522. };
  523. template<typename Head, typename... Tail>
  524. class _Zip<Head, Tail...> : private _Zip<Tail...> {
  525. protected:
  526. Value<std::vector<Head>>* head;
  527. int _get_size(){
  528. int this_size = head->get_value().size();
  529. int rest_size = _Zip<Tail...>::_get_size();
  530. return std::min(this_size, rest_size);
  531. }
  532. typename std::tuple<Head,Tail...> _get_at(int idx){
  533. auto tail_tuple = _Zip<Tail...>::_get_at(idx);
  534. return std::tuple_cat(std::make_tuple(head->get_value()[idx]),tail_tuple);
  535. }
  536. std::string _get_name(){
  537. return head->get_name()+","+_Zip<Tail...>::_get_name();
  538. }
  539. public:
  540. _Zip() { }
  541. _Zip(Value<std::vector<Head>>* head, Value<std::vector<Tail>>*... tail)
  542. : _Zip<Tail...>(tail...),
  543. head(head) { }
  544. };
  545. /**
  546. * Zips a series of vectors together. Can be combined with Map to
  547. * yield a Value whose elements are individually a function of the
  548. * corresponding elements of the vectors that were zipped together. For those
  549. * familiar with python, it accompilishes the same thing as
  550. * @code{.py}
  551. * xs = [1,2,3,4]
  552. * ys = [10,20,30,40]
  553. * print(list(map(lambda t:t[0]+t[1],zip(xs,ys))))
  554. * @endcode
  555. * which outputs
  556. * @code
  557. * [11, 22, 33, 44]
  558. * @endcode
  559. */
  560. template <typename... ArgTypes>
  561. class Zip : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>,
  562. private _Zip<ArgTypes...>{
  563. protected:
  564. void update_value(){
  565. this->value.clear();
  566. int size = _Zip<ArgTypes...>::_get_size();
  567. for(int i=0; i<size; i++){
  568. this->value.push_back(_Zip<ArgTypes...>::_get_at(i));
  569. }
  570. }
  571. std::string _get_name(){
  572. return "zip("+_Zip<ArgTypes...>::_get_name()+")";
  573. }
  574. public:
  575. Zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias)
  576. :DerivedValue<std::vector<std::tuple<ArgTypes...>>>("", alias),
  577. _Zip<ArgTypes...>(args...) {
  578. this->set_name(_get_name());
  579. }
  580. };
  581. template<typename> class Map; // undefined
  582. /**
  583. * Maps a function over an input vector. The input vector must be a vector of
  584. * tuples, where the the elements of the tuple match the arguments of the
  585. * function. For example if the function takes two floats as arguments, the
  586. * tuple should contain two floats. The Value object required by Map will
  587. * typically be created as a Zip.
  588. */
  589. template <typename Ret, typename... ArgTypes>
  590. class Map<Ret(ArgTypes...)> : public DerivedValue<std::vector<Ret>>{
  591. private:
  592. typedef Value<std::vector<std::tuple<ArgTypes...>>> arg_type;
  593. Function<Ret(ArgTypes...)>& fn;
  594. arg_type* arg;
  595. void update_value(){
  596. this->value.clear();
  597. for(auto tup : arg->get_value()){
  598. this->value.push_back(call(fn,tup));
  599. }
  600. }
  601. public:
  602. Map(Function<Ret(ArgTypes...)>& fn, arg_type* arg, const std::string& alias)
  603. :DerivedValue<std::vector<Ret>>("map("+fn.get_name()+":"+arg->get_name()+")", alias),
  604. fn(fn), arg(arg){ }
  605. };
  606. template<typename... T> class _Tuple;
  607. template<>
  608. class _Tuple<> {
  609. protected:
  610. std::tuple<> _get_value(){
  611. return std::make_tuple();
  612. }
  613. std::string _get_name(){
  614. return "";
  615. }
  616. public:
  617. _Tuple() { }
  618. };
  619. template<typename Head, typename... Tail>
  620. class _Tuple<Head, Tail...> : private _Tuple<Tail...> {
  621. protected:
  622. Value<Head>* head;
  623. typename std::tuple<Head,Tail...> _get_value(){
  624. auto tail_tuple = _Tuple<Tail...>::_get_value();
  625. return std::tuple_cat(std::make_tuple(head->get_value()),tail_tuple);
  626. }
  627. std::string _get_name(){
  628. return head->get_name()+","+_Tuple<Tail...>::_get_name();
  629. }
  630. public:
  631. _Tuple() { }
  632. _Tuple(Value<Head>* head, Value<Tail>*... tail)
  633. : _Tuple<Tail...>(tail...),
  634. head(head) { }
  635. };
  636. /**
  637. * Takes a series of Value objects and bundles them together into a std::tuple
  638. * object. Typically, this is most usefull when one wants to apply a function
  639. * to a few values and store the result. This class can be used in conjunction
  640. * with Apply to achieve this.
  641. */
  642. template <typename... ArgTypes>
  643. class Tuple : public DerivedValue<std::tuple<ArgTypes...>>,
  644. private _Tuple<ArgTypes...>{
  645. protected:
  646. void update_value(){
  647. this->value = _Tuple<ArgTypes...>::_get_value();
  648. }
  649. std::string _get_name(){
  650. return "tuple("+_Tuple<ArgTypes...>::_get_name()+")";
  651. }
  652. public:
  653. Tuple(Value<ArgTypes>*... args, const std::string& alias)
  654. :DerivedValue<std::tuple<ArgTypes...>>("", alias),
  655. _Tuple<ArgTypes...>(args...) {
  656. this->set_name(_get_name());
  657. }
  658. };
  659. /**
  660. * Gets the Nth element from a tuple value
  661. */
  662. template <size_t N, typename... ArgTypes>
  663. class DeTup : public DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>{
  664. Value<std::tuple<ArgTypes...>> tup;
  665. protected:
  666. void update_value(){
  667. this->value = std::get<N>(tup->get_value());
  668. }
  669. public:
  670. DeTup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias)
  671. :DerivedValue<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>("detup("+tup->get_name()+")", alias),
  672. tup(tup) { }
  673. };
  674. /**
  675. * Creates a vector of extracting the Nth value from each entry in a vector of
  676. * tuples.
  677. */
  678. template <size_t N, typename... ArgTypes>
  679. class DeTupVector : public DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>{
  680. Value<std::vector<std::tuple<ArgTypes...>>>* tup;
  681. protected:
  682. void update_value(){
  683. this->value.clear();
  684. for( auto& t : tup->get_value()){
  685. this->value.push_back(std::get<N>(t));
  686. }
  687. }
  688. public:
  689. DeTupVector(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias)
  690. :DerivedValue<std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type>>("detup("+tup->get_name()+")", alias),
  691. tup(tup) { }
  692. };
  693. template<typename> class Apply; // undefined
  694. /**
  695. * Applies a function to a tuple of values and returns a value. This will
  696. * typically be called with a Tuple object as an argument.
  697. */
  698. template <typename Ret, typename... ArgTypes>
  699. class Apply<Ret(ArgTypes...)> : public DerivedValue<Ret>{
  700. private:
  701. Function<Ret(ArgTypes...)>& fn;
  702. Value<std::tuple<ArgTypes...>>* arg;
  703. void update_value(){
  704. auto &tup = arg->get_value();
  705. this->value = call(fn, tup);
  706. }
  707. public:
  708. Apply(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias)
  709. :DerivedValue<Ret>("apply("+fn.get_name()+":"+arg->get_name()+")", alias),
  710. fn(fn), arg(arg){ }
  711. };
  712. /**
  713. * Returns the count of elements in the input vector passing a test function.
  714. */
  715. template<typename T>
  716. class Count : public DerivedValue<int>{
  717. private:
  718. Function<bool(T)>& selector;
  719. Value<std::vector<T> >* v;
  720. void update_value(){
  721. value = 0;
  722. for(auto val : v->get_value()){
  723. if(selector(val))
  724. value++;
  725. }
  726. }
  727. public:
  728. Count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string alias)
  729. :DerivedValue<int>("count("+selector.get_name()+":"+v->get_name()+")", alias),
  730. selector(selector), v(v) { }
  731. };
  732. /**
  733. * Returns the elements in a vector that pass a test function.
  734. */
  735. template<typename T>
  736. class Filter : public DerivedValue<std::vector<T>>{
  737. private:
  738. Function<bool(T)>& filter;
  739. Value<std::vector<T> >* v;
  740. void update_value(){
  741. this->value.clear();
  742. for(auto val : v->get_value()){
  743. if(this->filter(val))
  744. this->value.push_back(val);
  745. }
  746. }
  747. public:
  748. Filter(Function<bool(T)>& filter, Value<std::vector<T>>* v, const std::string alias)
  749. :DerivedValue<std::vector<T>>("filter("+filter.get_name()+":"+v->get_name()+")", alias),
  750. filter(filter), v(v) { }
  751. };
  752. /**
  753. * Returns the elements in a vector that pass a test function. The elements on
  754. * the vector must be tuples. Typically this will be used in conjunction with
  755. * Zip and Map.
  756. */
  757. template<typename... ArgTypes>
  758. class TupFilter : public DerivedValue<std::vector<std::tuple<ArgTypes...>>>{
  759. private:
  760. typedef std::vector<std::tuple<ArgTypes...>> value_type;
  761. Function<bool(ArgTypes...)>& filter;
  762. Value<value_type>* arg;
  763. void update_value(){
  764. this->value.clear();
  765. for(auto val : arg->get_value()){
  766. if(call(filter,val))
  767. this->value.push_back(val);
  768. }
  769. }
  770. public:
  771. TupFilter(Function<bool(ArgTypes...)>& filter, Value<value_type>* arg, const std::string alias)
  772. :DerivedValue<value_type>("tupfilter("+filter.get_name()+":"+arg->get_name()+")", alias),
  773. filter(filter), arg(arg) { }
  774. };
  775. /**
  776. * Reduce a Value of type vector<T> to just a T.
  777. * This is useful functionality to model, for instance, calculating the maximum
  778. * element of a vector, or a the mean. See child classes for specific
  779. * implementations.
  780. */
  781. template <typename T>
  782. class Reduce : public DerivedValue<T>{
  783. private:
  784. Function<T(std::vector<T>)>& reduce;
  785. void update_value(){
  786. this->value = reduce(v->get_value());
  787. }
  788. protected:
  789. Value<std::vector<T> >* v;
  790. public:
  791. Reduce(Function<T(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias)
  792. :DerivedValue<T>("reduceWith("+reduce.get_name()+":"+v->get_name()+")", alias),
  793. reduce(reduce), v(v) { }
  794. };
  795. /**
  796. * Find and return the maximum value of a vector.
  797. */
  798. template <typename T>
  799. class Max : public Reduce<T>{
  800. public:
  801. Max(Value<std::vector<T>>* v, const std::string alias)
  802. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("max",
  803. FUNC(([](std::vector<T> vec){
  804. return *std::max_element(vec.begin(), vec.end());}))),
  805. v, alias) { }
  806. };
  807. /**
  808. * Find and return the minimum value of a vector.
  809. */
  810. template <typename T>
  811. class Min : public Reduce<T>{
  812. public:
  813. Min(Value<std::vector<T>>* v, const std::string alias)
  814. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("min",
  815. FUNC(([](std::vector<T> vec){
  816. return *std::min_element(vec.begin(), vec.end());}))),
  817. v, alias) { }
  818. };
  819. /**
  820. * Calculate the mean value of a vector.
  821. */
  822. template <typename T>
  823. class Mean : public Reduce<T>{
  824. public:
  825. Mean(Value<std::vector<T>>* v, const std::string alias)
  826. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("mean",
  827. FUNC(([](std::vector<T> vec){
  828. int n = 0; T sum = 0;
  829. for (T e : vec){ n++; sum += e; }
  830. return n>0 ? sum / n : 0; }))),
  831. v, alias) { }
  832. };
  833. /**
  834. * Calculate the range of the values in a vector
  835. */
  836. template <typename T>
  837. class Range : public Reduce<T>{
  838. public:
  839. Range(Value<std::vector<T>>* v, const std::string alias)
  840. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("range",
  841. FUNC(([](std::vector<T> vec){
  842. auto minmax = std::minmax_element(vec.begin(), vec.end());
  843. return (*minmax.second) - (*minmax.first); }))),
  844. v, alias) { }
  845. };
  846. /**
  847. * Extract the element at a specific index from a vector.
  848. */
  849. template <typename T>
  850. class ElementOf : public Reduce<T>{
  851. public:
  852. ElementOf(Value<int>* index, Value<std::vector<T>>* v, const std::string alias)
  853. :Reduce<T>(GenFunction::register_function<T(std::vector<T>)>("elementOf",
  854. FUNC(([index](std::vector<T> vec){return vec[index->get_value()];}))),
  855. v, alias) { }
  856. };
  857. /**
  858. * Similar to Reduce, but returns a pair of a T and an int.
  859. * This is useful if you need to know where in the vector exists the element
  860. * being returned.
  861. */
  862. template <typename T>
  863. class ReduceIndex : public DerivedValue<std::pair<T, int> >{
  864. private:
  865. Function<std::pair<T,int>(std::vector<T>)>& reduce;
  866. Value<std::vector<T> >* v;
  867. void update_value(){
  868. this->value = reduce(v->get_value());
  869. }
  870. public:
  871. ReduceIndex(Function<std::pair<T,int>(std::vector<T>)>& reduce, Value<std::vector<T> >* v, const std::string alias="")
  872. :DerivedValue<T>("reduceIndexWith("+reduce.get_name()+":"+v->get_name()+")", alias),
  873. reduce(reduce), v(v) { }
  874. };
  875. /**
  876. * Find and return the maximum value of a vector and its index.
  877. */
  878. template <typename T>
  879. class MaxIndex : public ReduceIndex<T>{
  880. public:
  881. MaxIndex(Value<std::vector<T>>* v, const std::string alias="")
  882. :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("maxIndex",
  883. FUNC(([](std::vector<T> vec){
  884. auto elptr = std::max_element(vec.begin(), vec.end());
  885. return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
  886. v, alias) { }
  887. };
  888. /**
  889. * Find and return the minimum value of a vector and its index.
  890. */
  891. template <typename T>
  892. class MinIndex : public ReduceIndex<T>{
  893. public:
  894. MinIndex(Value<std::vector<T>>* v, const std::string alias="")
  895. :ReduceIndex<T>(GenFunction::register_function<T(std::vector<T>)>("minIndex",
  896. FUNC(([](std::vector<T> vec){
  897. auto elptr = std::min_element(vec.begin(), vec.end());
  898. return std::pair<T,int>(*elptr, int(elptr-vec.begin())); }))),
  899. v, alias) { }
  900. };
  901. /**
  902. * Find combinations of items from an input vector
  903. */
  904. template <typename T, int Size>
  905. class Combinations : public DerivedValue<std::vector<typename HomoTuple<T,Size>::type>>{
  906. private:
  907. Value<std::vector<T>>* val;
  908. typedef typename HomoTuple<T,Size>::type tuple_type;
  909. void update_value(){
  910. auto& v = val->get_value();
  911. int data_size = v.size();
  912. this->value.clear();
  913. std::vector<bool> selector(data_size);
  914. std::fill(selector.begin(), selector.begin()+std::min({Size,data_size}), true);
  915. do {
  916. std::array<T, Size> perm;
  917. int idx = 0;
  918. for (int i=0; i<data_size; i++){
  919. if (selector[i]){
  920. perm[idx] = v[i];
  921. idx++;
  922. if (idx == Size) break;
  923. }
  924. }
  925. this->value.push_back(a2t(perm)); //!!!
  926. } while(std::prev_permutation(selector.begin(), selector.end()));
  927. }
  928. static std::string calc_name(Value<std::vector<T>>* val){
  929. std::stringstream ss;
  930. ss << "combinations(" << Size << "," << val->get_name() << ")";
  931. return ss.str();
  932. }
  933. public:
  934. Combinations(Value<std::vector<T>>* val, const std::string alias="")
  935. :DerivedValue<std::vector<tuple_type>>(calc_name(val), alias),
  936. val(val) { }
  937. };
  938. /**
  939. * Calculate the cartesian product of two input vectors
  940. */
  941. template <typename FST, typename SND>
  942. class CartProduct : public DerivedValue<std::vector<std::tuple<FST,SND>>>{
  943. private:
  944. Value<std::vector<FST>>* val1;
  945. Value<std::vector<SND>>* val2;
  946. void update_value(){
  947. this->value.clear();
  948. auto& v1 = val1->get_value();
  949. auto& v2 = val2->get_value();
  950. for(int i=0; i<v1.size(); i++){
  951. for(int j=0; j<v2.size(); j++){
  952. this->value.push_back(std::tuple<FST,SND>(v1[i],v2[j]));
  953. }
  954. }
  955. }
  956. static std::string calc_name(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2){
  957. std::stringstream ss;
  958. ss << "cartProduct("
  959. << val1->get_name() << ", " << val2->get_name()
  960. << ")";
  961. return ss.str();
  962. }
  963. public:
  964. CartProduct(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string alias="")
  965. :DerivedValue<std::vector<std::tuple<FST,SND>>>(calc_name(val1, val2), alias),
  966. val1(val1),
  967. val2(val2) { }
  968. };
  969. /**
  970. * A generic value owning only a function object.
  971. * All necessary values upon which this value depends must be bound to the
  972. * function object.
  973. */
  974. template <typename T>
  975. class BoundValue : public DerivedValue<T>{
  976. protected:
  977. Function<T()>& f;
  978. void update_value(){
  979. this->value = f();
  980. }
  981. public:
  982. BoundValue(Function<T()>& f, const std::string alias="")
  983. :DerivedValue<T>(f.get_name()+"(<bound>)", alias),
  984. f(f) { }
  985. };
  986. /**
  987. * A Value of a pointer. The pointer is constant, however the data the pointer
  988. * points to is variable.
  989. */
  990. template <typename T>
  991. class PointerValue : public DerivedValue<T*>{
  992. protected:
  993. void update_value(){ }
  994. public:
  995. PointerValue(const std::string& name, T* ptr, const std::string alias="")
  996. :DerivedValue<T*>(name, alias){
  997. this->value = ptr;
  998. }
  999. };
  1000. /**
  1001. * A Value which always returns the same value, supplied in the constructor.
  1002. */
  1003. template <typename T>
  1004. class ConstantValue : public DerivedValue<T>{
  1005. protected:
  1006. void update_value(){ }
  1007. public:
  1008. ConstantValue(const std::string& name, T const_value, const std::string alias="")
  1009. :DerivedValue<T>("const::"+name, alias),
  1010. Value<T>::value(const_value) { }
  1011. };
  1012. }
  1013. #endif // value_hpp