value.hpp 38 KB

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