fmatvec  0.0.0
symbolic_function2_temp.h
1template<TEMPLATE>
2class 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
111template<TEMPLATE>
112SymbolicFunction<RET(ARG1, ARG2)>::SymbolicFunction() {
113#ifdef PARDER
114 isParDer1Const=false;
115 isParDer2Const=false;
116#endif
117}
118
119template<TEMPLATE>
120SymbolicFunction<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
129template<TEMPLATE>
130void SymbolicFunction<RET(ARG1, ARG2)>::setIndependentVariable1(const Arg1S &arg1S_) {
131 arg1S<<=arg1S_;
132}
133
134template<TEMPLATE>
135void SymbolicFunction<RET(ARG1, ARG2)>::setIndependentVariable2(const Arg2S &arg2S_) {
136 arg2S<<=arg2S_;
137}
138
139template<TEMPLATE>
140void SymbolicFunction<RET(ARG1, ARG2)>::setDependentFunction(const RetS &retS_) {
141 retS<<=retS_;
142}
143
144template<TEMPLATE>
145typename SymbolicFunction<RET(ARG1, ARG2)>::Arg1S& SymbolicFunction<RET(ARG1, ARG2)>::getIndependentVariable1() {
146 return arg1S;
147}
148
149template<TEMPLATE>
150typename SymbolicFunction<RET(ARG1, ARG2)>::Arg2S& SymbolicFunction<RET(ARG1, ARG2)>::getIndependentVariable2() {
151 return arg2S;
152}
153
154template<TEMPLATE>
155typename SymbolicFunction<RET(ARG1, ARG2)>::RetS& SymbolicFunction<RET(ARG1, ARG2)>::getDependentFunction() {
156 return retS;
157}
158
159template<TEMPLATE>
160void 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
202template<TEMPLATE>
203std::pair<int, int> SymbolicFunction<RET(ARG1, ARG2)>::getRetSize() const {
204 return std::make_pair(Helper<RetS>::size1(retS), Helper<RetS>::size2(retS));
205}
206
207template<TEMPLATE>
208int SymbolicFunction<RET(ARG1, ARG2)>::getArg1Size() const {
209 return Helper<Arg1S>::size1(arg1S);
210}
211
212template<TEMPLATE>
213int SymbolicFunction<RET(ARG1, ARG2)>::getArg2Size() const {
214 return Helper<Arg2S>::size1(arg2S);
215}
216
217template<TEMPLATE>
218RET 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
225template<TEMPLATE>
226auto 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
233template<TEMPLATE>
234auto 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
242template<TEMPLATE>
243auto 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
250template<TEMPLATE>
251auto 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
259template<TEMPLATE>
260auto 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
268template<TEMPLATE>
269auto 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
277template<TEMPLATE>
278auto 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
287template<TEMPLATE>
288auto 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
296template<TEMPLATE>
297auto 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
305template<TEMPLATE>
306auto 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
315template<TEMPLATE>
316auto 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
324template<TEMPLATE>
325auto 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
333template<TEMPLATE>
334auto 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
343template<TEMPLATE>
344auto 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
352template<TEMPLATE>
353bool SymbolicFunction<RET(ARG1, ARG2)>::constParDer1() const {
354 return isParDer1Const;
355}
356
357template<TEMPLATE>
358bool SymbolicFunction<RET(ARG1, ARG2)>::constParDer2() const {
359 return isParDer2Const;
360}
SymbolicExpression parDer(const SymbolicExpression &dep, const IndependentVariable &indep)
Definition: ast.cc:299