fmatvec 0.0.0

symbolic_function2_temp.h
1 template<TEMPLATE>
2 class SymbolicFunction<RET(ARG1, ARG2)> : public virtual Function<RET(ARG1, ARG2)> {
3 public:
4 using DRetDArg1 = typename Function<RET(ARG1, ARG2)>::DRetDArg1;
5 using DRetDArg2 = typename Function<RET(ARG1, ARG2)>::DRetDArg2;
6 using DRetDDir1 = typename Function<RET(ARG1, ARG2)>::DRetDDir1;
7 using DRetDDir2 = typename Function<RET(ARG1, ARG2)>::DRetDDir2;
8 using DDRetDDArg1 = typename Function<RET(ARG1, ARG2)>::DDRetDDArg1;
9 using DDRetDDArg2 = typename Function<RET(ARG1, ARG2)>::DDRetDDArg2;
10 using DDRetDArg1DArg2 = typename Function<RET(ARG1, ARG2)>::DDRetDArg1DArg2;
11 using Arg1S = typename ReplaceAT<ARG1, IndependentVariable>::Type;
12 using Arg2S = typename ReplaceAT<ARG2, IndependentVariable>::Type;
13 using RetS = typename ReplaceAT<RET, SymbolicExpression>::Type;
14
15 SymbolicFunction();
16 SymbolicFunction(const Arg1S &arg1S_, const Arg2S &arg2S_, const RetS &retS_); // calls init() at the end
17 void setIndependentVariable1(const Arg1S &arg1S_);
18 void setIndependentVariable2(const Arg2S &arg2S_);
19 void setDependentFunction(const RetS &retS_);
20 Arg1S& getIndependentVariable1();
21 Arg2S& getIndependentVariable2();
22 RetS& getDependentFunction();
23 void init(); // must be called after setIndependentVariable/setDependentFunction.
24
25 std::pair<int, int> getRetSize() const override;
26 int getArg1Size() const override;
27 int getArg2Size() const override;
28
29 RET operator()(const ARG1 &arg1, const ARG2 &arg2) override;
30 #ifdef PARDER1
31 DRetDArg1 parDer1(const ARG1 &arg1, const ARG2 &arg2) override;
32 #endif
33 DRetDDir1 dirDer1(const ARG1 &arg1Dir, const ARG1 &arg1, const ARG2 &arg2) override;
34 #ifdef PARDER2
35 DRetDArg2 parDer2(const ARG1 &arg1, const ARG2 &arg2) override;
36 #endif
37 DRetDDir2 dirDer2(const ARG2 &arg2Dir, const ARG1 &arg1, const ARG2 &arg2) override;
38 #ifdef PARDER1PARDER1
39 DDRetDDArg1 parDer1ParDer1(const ARG1 &arg1, const ARG2 &arg2) override;
40 #endif
41 #ifdef PARDER1
42 DRetDArg1 parDer1DirDer1(const ARG1 &arg1Dir, const ARG1 &arg1, const ARG2 &arg2) override;
43 #endif
44 DRetDDir1 dirDer1DirDer1(const ARG1 &arg1Dir_1, const ARG1 &arg1Dir_2, const ARG1 &arg1, const ARG2 &arg2) override;
45 #ifdef PARDER2PARDER2
46 DDRetDDArg2 parDer2ParDer2(const ARG1 &arg1, const ARG2 &arg2) override;
47 #endif
48 #ifdef PARDER2
49 DRetDArg2 parDer2DirDer2(const ARG2 &arg2Dir, const ARG1 &arg1, const ARG2 &arg2) override;
50 #endif
51 DRetDDir2 dirDer2DirDer2(const ARG2 &arg2Dir_1, const ARG2 &arg2Dir_2, const ARG1 &arg1, const ARG2 &arg2) override;
52 #ifdef PARDER1PARDER2
53 DDRetDArg1DArg2 parDer1ParDer2(const ARG1 &arg1, const ARG2 &arg2) override;
54 #endif
55 #ifdef PARDER1
56 DRetDArg1 parDer1DirDer2(const ARG2 &arg2Dir, const ARG1 &arg1, const ARG2 &arg2) override;
57 #endif
58 DRetDDir2 dirDer2DirDer1(const ARG2 &arg2Dir, const ARG1 &arg1Dir, const ARG1 &arg1, const ARG2 &arg2) override;
59 #ifdef PARDER2
60 DRetDArg2 parDer2DirDer1(const ARG1 &arg1Dir, const ARG1 &arg1, const ARG2 &arg2) override;
61 #endif
62 bool constParDer1() const override;
63 bool constParDer2() const override;
64
65 protected:
66
67 Arg1S arg1S;
68 Arg2S arg2S;
69 Arg1S argDir1S;
70 Arg1S argDir1S_2;
71 Arg2S argDir2S;
72 Arg2S argDir2S_2;
73 RetS retS;
74 std::unique_ptr<Eval<decltype(retS)>> retSEval;
75 #ifdef PARDER1
76 std::unique_ptr<Eval<typename ReplaceAT<DRetDArg1, SymbolicExpression>::Type>> pd1Eval;
77 #endif
78 std::unique_ptr<Eval<typename ReplaceAT<DRetDDir1, SymbolicExpression>::Type>> dd1Eval;
79 #ifdef PARDER2
80 std::unique_ptr<Eval<typename ReplaceAT<DRetDArg2, SymbolicExpression>::Type>> pd2Eval;
81 #endif
82 std::unique_ptr<Eval<typename ReplaceAT<DRetDDir2, SymbolicExpression>::Type>> dd2Eval;
83 #ifdef PARDER1PARDER1
84 std::unique_ptr<Eval<typename ReplaceAT<DDRetDDArg1, SymbolicExpression>::Type>> pd1pd1Eval;
85 #endif
86 #ifdef PARDER1
87 std::unique_ptr<Eval<typename ReplaceAT<DRetDArg1, SymbolicExpression>::Type>> pd1dd1Eval;
88 #endif
89 std::unique_ptr<Eval<typename ReplaceAT<DRetDDir1, SymbolicExpression>::Type>> dd1dd1Eval;
90 #ifdef PARDER2PARDER2
91 std::unique_ptr<Eval<typename ReplaceAT<DDRetDDArg2, SymbolicExpression>::Type>> pd2pd2Eval;
92 #endif
93 #ifdef PARDER2
94 std::unique_ptr<Eval<typename ReplaceAT<DRetDArg2, SymbolicExpression>::Type>> pd2dd2Eval;
95 #endif
96 std::unique_ptr<Eval<typename ReplaceAT<DRetDDir2, SymbolicExpression>::Type>> dd2dd2Eval;
97 #ifdef PARDER1PARDER2
98 std::unique_ptr<Eval<typename ReplaceAT<DDRetDArg1DArg2, SymbolicExpression>::Type>> pd1pd2Eval;
99 #endif
100 #ifdef PARDER1
101 std::unique_ptr<Eval<typename ReplaceAT<DRetDArg1, SymbolicExpression>::Type>> pd1dd2Eval;
102 #endif
103 std::unique_ptr<Eval<typename ReplaceAT<DRetDDir2, SymbolicExpression>::Type>> dd2dd1Eval;
104 #ifdef PARDER2
105 std::unique_ptr<Eval<typename ReplaceAT<DRetDArg2, SymbolicExpression>::Type>> pd2dd1Eval;
106 #endif
107 bool isParDer1Const = false;
108 bool isParDer2Const = false;
109 };
110
111 template<TEMPLATE>
112 SymbolicFunction<RET(ARG1, ARG2)>::SymbolicFunction() {
113 #ifdef PARDER
114 isParDer1Const=false;
115 isParDer2Const=false;
116 #endif
117 }
118
119 template<TEMPLATE>
120 SymbolicFunction<RET(ARG1, ARG2)>::SymbolicFunction(const Arg1S &arg1S_, const Arg2S &arg2S_, const RetS &retS_) :
121 arg1S(arg1S_), arg2S(arg2S_), retS(retS_) {
122 #ifdef PARDER
123 isParDer1Const=false;
124 isParDer2Const=false;
125 #endif
126 init();
127 }
128
129 template<TEMPLATE>
130 void SymbolicFunction<RET(ARG1, ARG2)>::setIndependentVariable1(const Arg1S &arg1S_) {
131 arg1S<<=arg1S_;
132 }
133
134 template<TEMPLATE>
135 void SymbolicFunction<RET(ARG1, ARG2)>::setIndependentVariable2(const Arg2S &arg2S_) {
136 arg2S<<=arg2S_;
137 }
138
139 template<TEMPLATE>
140 void SymbolicFunction<RET(ARG1, ARG2)>::setDependentFunction(const RetS &retS_) {
141 retS<<=retS_;
142 }
143
144 template<TEMPLATE>
145 typename SymbolicFunction<RET(ARG1, ARG2)>::Arg1S& SymbolicFunction<RET(ARG1, ARG2)>::getIndependentVariable1() {
146 return arg1S;
147 }
148
149 template<TEMPLATE>
150 typename SymbolicFunction<RET(ARG1, ARG2)>::Arg2S& SymbolicFunction<RET(ARG1, ARG2)>::getIndependentVariable2() {
151 return arg2S;
152 }
153
154 template<TEMPLATE>
155 typename SymbolicFunction<RET(ARG1, ARG2)>::RetS& SymbolicFunction<RET(ARG1, ARG2)>::getDependentFunction() {
156 return retS;
157 }
158
159 template<TEMPLATE>
160 void SymbolicFunction<RET(ARG1, ARG2)>::init() {
161 Helper<Arg1S>::initIndep(argDir1S, Helper<Arg1S>::size1(arg1S));
162 Helper<Arg1S>::initIndep(argDir1S, Helper<Arg1S>::size1(arg1S));
163 Helper<Arg1S>::initIndep(argDir1S_2, Helper<Arg1S>::size1(arg1S));
164 Helper<Arg2S>::initIndep(argDir2S, Helper<Arg2S>::size1(arg2S));
165 Helper<Arg2S>::initIndep(argDir2S, Helper<Arg2S>::size1(arg2S));
166 Helper<Arg2S>::initIndep(argDir2S_2, Helper<Arg2S>::size1(arg2S));
167 retSEval.reset(new Eval<decltype(retS)>{retS});
168 #ifdef PARDER1
169 pd1Eval.reset(new Eval<typename ReplaceAT<DRetDArg1, SymbolicExpression>::Type>{fmatvec::parDer(retS, arg1S)});
170 #endif
171 dd1Eval.reset(new Eval<typename ReplaceAT<DRetDDir1, SymbolicExpression>::Type>{fmatvec::dirDer(retS, argDir1S*1, arg1S)});
172 #ifdef PARDER2
173 pd2Eval.reset(new Eval<typename ReplaceAT<DRetDArg2, SymbolicExpression>::Type>{fmatvec::parDer(retS, arg2S)});
174 #endif
175 dd2Eval.reset(new Eval<typename ReplaceAT<DRetDDir2, SymbolicExpression>::Type>{fmatvec::dirDer(retS, argDir2S*1, arg2S)});
176 #ifdef PARDER1PARDER1
177 pd1pd1Eval.reset(new Eval<typename ReplaceAT<DDRetDDArg1, SymbolicExpression>::Type>{fmatvec::parDer(fmatvec::parDer(retS, arg1S), arg1S)});
178 #endif
179 #ifdef PARDER1
180 pd1dd1Eval.reset(new Eval<typename ReplaceAT<DRetDArg1, SymbolicExpression>::Type>{fmatvec::dirDer(fmatvec::parDer(retS, arg1S), argDir1S*1, arg1S)});
181 #endif
182 dd1dd1Eval.reset(new Eval<typename ReplaceAT<DRetDDir1, SymbolicExpression>::Type>{fmatvec::dirDer(fmatvec::dirDer(retS, argDir1S*1, arg1S), argDir1S_2*1, arg1S)});
183 #ifdef PARDER2PARDER2
184 pd2pd2Eval.reset(new Eval<typename ReplaceAT<DDRetDDArg2, SymbolicExpression>::Type>{fmatvec::parDer(fmatvec::parDer(retS, arg2S), arg2S)});
185 #endif
186 #ifdef PARDER2
187 pd2dd2Eval.reset(new Eval<typename ReplaceAT<DRetDArg2, SymbolicExpression>::Type>{fmatvec::dirDer(fmatvec::parDer(retS, arg2S), argDir2S*1, arg2S)});
188 #endif
189 dd2dd2Eval.reset(new Eval<typename ReplaceAT<DRetDDir2, SymbolicExpression>::Type>{fmatvec::dirDer(fmatvec::dirDer(retS, argDir2S*1, arg2S), argDir2S_2*1, arg2S)});
190 #ifdef PARDER1PARDER2
191 pd1pd2Eval.reset(new Eval<typename ReplaceAT<DDRetDArg1DArg2, SymbolicExpression>::Type>{fmatvec::parDer(fmatvec::parDer(retS, arg1S), arg2S)});
192 #endif
193 #ifdef PARDER1
194 pd1dd2Eval.reset(new Eval<typename ReplaceAT<DRetDArg1, SymbolicExpression>::Type>{fmatvec::dirDer(fmatvec::parDer(retS, arg1S), argDir2S*1, arg2S)});
195 #endif
196 dd2dd1Eval.reset(new Eval<typename ReplaceAT<DRetDDir2, SymbolicExpression>::Type>{fmatvec::dirDer(fmatvec::dirDer(retS, argDir2S*1, arg2S), argDir1S*1, arg1S)});
197 #ifdef PARDER2
198 pd2dd1Eval.reset(new Eval<typename ReplaceAT<DRetDArg2, SymbolicExpression>::Type>{fmatvec::dirDer(fmatvec::parDer(retS, arg2S), argDir1S*1, arg1S)});
199 #endif
200 }
201
202 template<TEMPLATE>
203 std::pair<int, int> SymbolicFunction<RET(ARG1, ARG2)>::getRetSize() const {
204 return std::make_pair(Helper<RetS>::size1(retS), Helper<RetS>::size2(retS));
205 }
206
207 template<TEMPLATE>
208 int SymbolicFunction<RET(ARG1, ARG2)>::getArg1Size() const {
209 return Helper<Arg1S>::size1(arg1S);
210 }
211
212 template<TEMPLATE>
213 int SymbolicFunction<RET(ARG1, ARG2)>::getArg2Size() const {
214 return Helper<Arg2S>::size1(arg2S);
215 }
216
217 template<TEMPLATE>
218 RET SymbolicFunction<RET(ARG1, ARG2)>::operator()(const ARG1 &arg1, const ARG2 &arg2) {
219 arg1S^=arg1;
220 arg2S^=arg2;
221 return (*retSEval)();
222 }
223
224 #ifdef PARDER1
225 template<TEMPLATE>
226 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer1(const ARG1 &arg1, const ARG2 &arg2) -> DRetDArg1 {
227 arg1S^=arg1;
228 arg2S^=arg2;
229 return (*pd1Eval)();
230 }
231 #endif
232
233 template<TEMPLATE>
234 auto SymbolicFunction<RET(ARG1, ARG2)>::dirDer1(const ARG1 &arg1Dir, const ARG1 &arg1, const ARG2 &arg2) -> DRetDDir1 {
235 argDir1S^=arg1Dir;
236 arg1S^=arg1;
237 arg2S^=arg2;
238 return (*dd1Eval)();
239 }
240
241 #ifdef PARDER2
242 template<TEMPLATE>
243 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer2(const ARG1 &arg1, const ARG2 &arg2) -> DRetDArg2 {
244 arg1S^=arg1;
245 arg2S^=arg2;
246 return (*pd2Eval)();
247 }
248 #endif
249
250 template<TEMPLATE>
251 auto SymbolicFunction<RET(ARG1, ARG2)>::dirDer2(const ARG2 &arg2Dir, const ARG1 &arg1, const ARG2 &arg2) -> DRetDDir2 {
252 argDir2S^=arg2Dir;
253 arg1S^=arg1;
254 arg2S^=arg2;
255 return (*dd2Eval)();
256 }
257
258 #ifdef PARDER1PARDER1
259 template<TEMPLATE>
260 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer1ParDer1(const ARG1 &arg1, const ARG2 &arg2) -> DDRetDDArg1 {
261 arg1S^=arg1;
262 arg2S^=arg2;
263 return (*pd1pd1Eval)();
264 }
265 #endif
266
267 #ifdef PARDER1
268 template<TEMPLATE>
269 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer1DirDer1(const ARG1 &arg1Dir, const ARG1 &arg1, const ARG2 &arg2) -> DRetDArg1 {
270 argDir1S^=arg1Dir;
271 arg1S^=arg1;
272 arg2S^=arg2;
273 return (*pd1dd1Eval)();
274 }
275 #endif
276
277 template<TEMPLATE>
278 auto SymbolicFunction<RET(ARG1, ARG2)>::dirDer1DirDer1(const ARG1 &arg1Dir_1, const ARG1 &arg1Dir_2, const ARG1 &arg1, const ARG2 &arg2) -> DRetDDir1 {
279 argDir1S^=arg1Dir_1;
280 argDir1S_2^=arg1Dir_2;
281 arg1S^=arg1;
282 arg2S^=arg2;
283 return (*dd1dd1Eval)();
284 }
285
286 #ifdef PARDER2PARDER2
287 template<TEMPLATE>
288 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer2ParDer2(const ARG1 &arg1, const ARG2 &arg2) -> DDRetDDArg2 {
289 arg1S^=arg1;
290 arg2S^=arg2;
291 return (*pd2pd2Eval)();
292 }
293 #endif
294
295 #ifdef PARDER2
296 template<TEMPLATE>
297 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer2DirDer2(const ARG2 &arg2Dir, const ARG1 &arg1, const ARG2 &arg2) -> DRetDArg2 {
298 argDir2S^=arg2Dir;
299 arg1S^=arg1;
300 arg2S^=arg2;
301 return (*pd2dd2Eval)();
302 }
303 #endif
304
305 template<TEMPLATE>
306 auto SymbolicFunction<RET(ARG1, ARG2)>::dirDer2DirDer2(const ARG2 &arg2Dir_1, const ARG2 &arg2Dir_2, const ARG1 &arg1, const ARG2 &arg2) -> DRetDDir2 {
307 argDir2S^=arg2Dir_1;
308 argDir2S_2^=arg2Dir_2;
309 arg1S^=arg1;
310 arg2S^=arg2;
311 return (*dd2dd2Eval)();
312 }
313
314 #ifdef PARDER1PARDER2
315 template<TEMPLATE>
316 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer1ParDer2(const ARG1 &arg1, const ARG2 &arg2) -> DDRetDArg1DArg2 {
317 arg1S^=arg1;
318 arg2S^=arg2;
319 return (*pd1pd2Eval)();
320 }
321 #endif
322
323 #ifdef PARDER1
324 template<TEMPLATE>
325 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer1DirDer2(const ARG2 &arg2Dir, const ARG1 &arg1, const ARG2 &arg2) -> DRetDArg1 {
326 argDir2S^=arg2Dir;
327 arg1S^=arg1;
328 arg2S^=arg2;
329 return (*pd1dd2Eval)();
330 }
331 #endif
332
333 template<TEMPLATE>
334 auto SymbolicFunction<RET(ARG1, ARG2)>::dirDer2DirDer1(const ARG2 &arg2Dir, const ARG1 &arg1Dir, const ARG1 &arg1, const ARG2 &arg2) -> DRetDDir2 {
335 argDir2S^=arg2Dir;
336 argDir1S^=arg1Dir;
337 arg1S^=arg1;
338 arg2S^=arg2;
339 return (*dd2dd1Eval)();
340 }
341
342 #ifdef PARDER2
343 template<TEMPLATE>
344 auto SymbolicFunction<RET(ARG1, ARG2)>::parDer2DirDer1(const ARG1 &arg1Dir, const ARG1 &arg1, const ARG2 &arg2) -> DRetDArg2 {
345 argDir1S^=arg1Dir;
346 arg1S^=arg1;
347 arg2S^=arg2;
348 return (*pd2dd1Eval)();
349 }
350 #endif
351
352 template<TEMPLATE>
353 bool SymbolicFunction<RET(ARG1, ARG2)>::constParDer1() const {
354 return isParDer1Const;
355 }
356
357 template<TEMPLATE>
358 bool SymbolicFunction<RET(ARG1, ARG2)>::constParDer2() const {
359 return isParDer2Const;
360 }
fmatvec::parDer
SymbolicExpression parDer(const SymbolicExpression &dep, const IndependentVariable &indep)
Definition: ast.cc:299