codac 1.5.6
Loading...
Searching...
No Matches
codac2_AnalyticExpr.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include <map>
13#include <memory>
14#include <utility>
15#include "codac2_ExprBase.h"
16#include "codac2_Domain.h"
18#include "codac2_AnalyticType.h"
19
20namespace codac2
21{
22 using ValuesMap = std::map<ExprID,std::shared_ptr<AnalyticTypeBase>>;
23
24 template<typename T>
25 class AnalyticExpr : public ExprBase
26 {
27 public:
28
29 AnalyticExpr<T>& operator=(const AnalyticExpr<T>& x) = delete;
30
31 virtual T fwd_eval(ValuesMap& v, Index total_input_size, bool natural_eval) const = 0;
32 virtual void bwd_eval(ValuesMap& v) const = 0;
33
34 T init_value(ValuesMap& v, const T& x) const
35 {
36 auto it = v.find(unique_id());
37
38 if(it == v.end())
39 {
40 v[unique_id()] = std::make_shared<T>(x);
41 return x;
42 }
43
44 *std::dynamic_pointer_cast<T>(it->second) = x;
45 return *std::dynamic_pointer_cast<T>(it->second);
46 }
47
48 T& value(ValuesMap& v) const
49 {
50 assert(v.find(unique_id()) != v.end() && "argument cannot be found");
51 return *std::dynamic_pointer_cast<T>(v[unique_id()]);
52 }
53
54 virtual bool belongs_to_args_list(const FunctionArgsList& args) const = 0;
55 };
56
57 template<typename C,typename Y,typename... X>
58 class AnalyticOperationExpr : public AnalyticExpr<Y>, public OperationExprBase<AnalyticExpr<X>...>
59 {
60 public:
61
62 AnalyticOperationExpr(std::shared_ptr<AnalyticExpr<X>>... x)
63 : OperationExprBase<AnalyticExpr<X>...>(x...)
64 { }
65
66 AnalyticOperationExpr(const AnalyticOperationExpr<C,Y,X...>& e)
67 : OperationExprBase<AnalyticExpr<X>...>(e)
68 { }
69
70 std::shared_ptr<ExprBase> copy() const
71 {
72 return std::make_shared<AnalyticOperationExpr<C,Y,X...>>(*this);
73 }
74
75 void replace_expr(const ExprID& old_expr_id, const std::shared_ptr<ExprBase>& new_expr)
76 {
77 return OperationExprBase<AnalyticExpr<X>...>::replace_expr(old_expr_id, new_expr);
78 }
79
80 Y fwd_eval(ValuesMap& v, Index total_input_size, bool natural_eval) const
81 {
82 return std::apply(
83 [this,&v,total_input_size,natural_eval](auto &&... x)
84 {
85 if(natural_eval)
86 return AnalyticExpr<Y>::init_value(v, C::fwd_natural(x->fwd_eval(v, total_input_size, natural_eval)...));
87
88 else
89 return AnalyticExpr<Y>::init_value(v, C::fwd_centered(x->fwd_eval(v, total_input_size, natural_eval)...));
90 },
91 this->_x);
92 }
93
94 void bwd_eval(ValuesMap& v) const
95 {
96 auto y = AnalyticExpr<Y>::value(v);
97
98 std::apply([&v,y](auto &&... x)
99 {
100 C::bwd(y.a, x->value(v).a...);
101 }, this->_x);
102
103 std::apply([&v](auto &&... x)
104 {
105 (x->bwd_eval(v), ...);
106 }, this->_x);
107 }
108
109 virtual bool belongs_to_args_list(const FunctionArgsList& args) const
110 {
111 bool b = true;
112
113 std::apply([&b,args](auto &&... x)
114 {
115 ((b &= x->belongs_to_args_list(args)), ...);
116 }, this->_x);
117
118 return b;
119 }
120 };
121}