FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
lambda_function.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8#include <kernel/analytic/function.hpp>
10
11namespace FEAT
12{
13 namespace Analytic
14 {
16 namespace Intern
17 {
30 template<typename F_>
31 struct LambdaHelper
32 {
34 typedef F_ Type;
36 static constexpr bool have = true;
38 F_ f;
40 explicit LambdaHelper(F_&& f_) : f(std::forward<F_>(f_)) {}
41 };
42
46 template<>
47 struct LambdaHelper<void>
48 {
50 typedef void Type;
52 static constexpr bool have = false;
54 LambdaHelper() {}
55 };
56
88 template<typename LambdaSet_, int dim_, typename DT_, typename VT_, typename GT_, bool have_grad_>
89 class LambdaGradHelper
90 {
91 public:
93 LambdaSet_& lambda_set;
94
95 explicit LambdaGradHelper(LambdaSet_& lambda_set_, DT_, int) :
96 lambda_set(lambda_set_)
97 {
98 }
99
101 void eval_grad(Tiny::Vector<DT_, 1>& grad, const Tiny::Vector<DT_, 1>& p)
102 {
103 grad[0] = lambda_set.dx.f(p[0]);
104 }
105
107 void eval_grad(Tiny::Vector<DT_, 2>& grad, const Tiny::Vector<DT_, 2>& p)
108 {
109 grad[0] = lambda_set.dx.f(p[0], p[1]);
110 grad[1] = lambda_set.dy.f(p[0], p[1]);
111 }
112
114 void eval_grad(Tiny::Vector<DT_, 3>& grad, const Tiny::Vector<DT_, 3>& p)
115 {
116 grad[0] = lambda_set.dx.f(p[0], p[1], p[2]);
117 grad[1] = lambda_set.dy.f(p[0], p[1], p[2]);
118 grad[2] = lambda_set.dz.f(p[0], p[1], p[2]);
119 }
120
122 void eval_grad(Tiny::Matrix<DT_, 2, 2>& grad, const Tiny::Vector<DT_, 2>& p)
123 {
124 grad[0][0] = lambda_set.dx1.f(p[0], p[1]);
125 grad[0][1] = lambda_set.dy1.f(p[0], p[1]);
126 grad[1][0] = lambda_set.dx2.f(p[0], p[1]);
127 grad[1][1] = lambda_set.dy2.f(p[0], p[1]);
128 }
129
131 void eval_grad(Tiny::Matrix<DT_, 3, 3>& grad, const Tiny::Vector<DT_, 3>& p)
132 {
133 grad[0][0] = lambda_set.dx1.f(p[0], p[1], p[2]);
134 grad[0][1] = lambda_set.dy1.f(p[0], p[1], p[2]);
135 grad[0][2] = lambda_set.dz1.f(p[0], p[1], p[2]);
136 grad[1][0] = lambda_set.dx2.f(p[0], p[1], p[2]);
137 grad[1][1] = lambda_set.dy2.f(p[0], p[1], p[2]);
138 grad[1][2] = lambda_set.dz2.f(p[0], p[1], p[2]);
139 grad[2][0] = lambda_set.dx3.f(p[0], p[1], p[2]);
140 grad[2][1] = lambda_set.dy3.f(p[0], p[1], p[2]);
141 grad[2][2] = lambda_set.dz3.f(p[0], p[1], p[2]);
142 }
143 }; // class LambdaGradHelper<...> (explicit formulae)
144
154 template<typename LambdaSet_, int dim_, typename DT_, typename VT_, typename GT_>
155 class LambdaGradHelper<LambdaSet_, dim_, DT_, VT_, GT_, false>
156 {
157 public:
159 LambdaSet_& lambda_set;
161 const DT_ initial_h;
163 const std::size_t max_steps;
164
165 explicit LambdaGradHelper(LambdaSet_& lambda_set_, DT_ initial_h_, int max_steps_) :
166 lambda_set(lambda_set_),
167 initial_h(initial_h_),
168 max_steps(std::size_t(max_steps_))
169 {
170 }
171
173 void eval_grad(GT_& grad, const Tiny::Vector<DT_, dim_>& point)
174 {
175 // first, create a mutable copy of our point
176 Tiny::Vector<DT_, dim_> v(point);
177
179 std::vector<GT_> gradex(max_steps);
180
181 // next, choose the initial h
182 DT_ h(initial_h);
183
184 // evaluate gradient
185 eval_grad_diff_quot(gradex[0], v, h);
186
187 // Now comes the Richardson extrapolation loop
188 const std::size_t n(gradex.size()-1);
189 DT_ def(Math::huge<DT_>());
190 for(std::size_t i(0); i < n; ++i)
191 {
192 // evaluate next gradient
193 eval_grad_diff_quot(gradex[i+1], v, h *= DT_(0.5));
194
195 // initialize scaling factor
196 DT_ q = DT_(1);
197
198 // perform extrapolation steps except for the last one
199 for(std::size_t k(i); k > std::size_t(0); --k)
200 {
201 q *= DT_(4);
202 (gradex[k] -= q*gradex[k+1]) *= DT_(1) / (DT_(1) - q);
203 }
204
205 // compute and check our defect
206 DT_ d = def_norm_sqr(gradex[1], gradex[0]);
207 if(def <= d)
208 {
209 // The defect has increased, so we return the previous extrapolation result
210 break;
211 }
212
213 // remember current defect
214 def = d;
215
216 // perform last extrapolation step
217 q *= DT_(4);
218 (gradex[0] -= q*gradex[1]) *= DT_(1) / (DT_(1) - q);
219 }
220
221 // return our extrapolated gradient
222 grad = gradex.front();
223 }
224
226 template<int n_, int s_>
227 static DT_ def_norm_sqr(const Tiny::Vector<DT_, n_, s_>& x, const Tiny::Vector<DT_, n_, s_>& y)
228 {
229 return (x - y).norm_euclid_sqr();
230 }
231
233 template<int m_, int n_, int sm_, int sn_>
234 static DT_ def_norm_sqr(
235 const Tiny::Matrix<DT_, m_, n_, sm_, sn_>& x,
236 const Tiny::Matrix<DT_, m_, n_, sm_, sn_>& y)
237 {
238 return (x - y).norm_hessian_sqr();
239 }
240
241 // compute scalar difference quotient
242 static void set_diff_quot(Tiny::Vector<DT_, dim_>& x, int i, const VT_& vr, const VT_& vl, const DT_ denom)
243 {
244 x[i] = denom * (vr - vl);
245 }
246
247 // compute vector difference quotient
248 static void set_diff_quot(Tiny::Matrix<DT_, dim_, dim_>& x, int i, const VT_& vr, const VT_& vl, const DT_ denom)
249 {
250 for(int k(0); k < dim_; ++k)
251 x[k][i] = denom * (vr[k] - vl[k]);
252 }
253
255 void eval_grad_diff_quot(GT_& x, Tiny::Vector<DT_, dim_>& v, const DT_ h)
256 {
257 // difference quotient denominator
258 const DT_ denom = DT_(1) / (DT_(2) * h);
259 VT_ vr, vl;
260
261 // loop over all dimensions
262 for(int i(0); i < dim_; ++i)
263 {
264 // backup coordinate i
265 const DT_ vi(v[i]);
266
267 // evaluate f(v + h*e_i)
268 v[i] = vi + h;
269 vr = lambda_set.eval_value(v);
270
271 // evaluate f(v - h*e_i)
272 v[i] = vi - h;
273 vl = lambda_set.eval_value(v);
274
275 // compute difference quotient
276 set_diff_quot(x, i, vr, vl, denom);
277
278 // restore coord
279 v[i] = vi;
280 }
281 }
282 }; // class LambdaGradHelper<...> (Richardson extrapolation)
283
315 template<typename LambdaSet_, int dim_, typename DT_, typename VT_, typename HT_, bool have_hess_>
316 class LambdaHessHelper
317 {
318 public:
320 LambdaSet_& lambda_set;
321
322 explicit LambdaHessHelper(LambdaSet_& lambda_set_, DT_, int) :
323 lambda_set(lambda_set_)
324 {
325 }
326
328 void eval_hess(Tiny::Matrix<DT_, 1, 1>& hess, const Tiny::Vector<DT_, 1>& p)
329 {
330 hess[0][0] = lambda_set.dxx.f(p[0]);
331 }
332
334 void eval_hess(Tiny::Matrix<DT_, 2, 2>& hess, const Tiny::Vector<DT_, 2>& p)
335 {
336 hess[0][0] = lambda_set.dxx.f(p[0], p[1]);
337 hess[1][1] = lambda_set.dyy.f(p[0], p[1]);
338 hess[0][1] = hess[1][0] = lambda_set.dxy.f(p[0], p[1]);
339 }
340
342 void eval_hess(Tiny::Matrix<DT_, 3, 3>& hess, const Tiny::Vector<DT_, 3>& p)
343 {
344 hess[0][0] = lambda_set.dxx.f(p[0], p[1], p[2]);
345 hess[1][1] = lambda_set.dyy.f(p[0], p[1], p[2]);
346 hess[2][2] = lambda_set.dzz.f(p[0], p[1], p[2]);
347 hess[0][1] = hess[1][0] = lambda_set.dxy.f(p[0], p[1], p[2]);
348 hess[1][2] = hess[2][1] = lambda_set.dyz.f(p[0], p[1], p[2]);
349 hess[2][0] = hess[0][2] = lambda_set.dzx.f(p[0], p[1], p[2]);
350 }
351
353 void eval_hess(Tiny::Tensor3<DT_, 2, 2, 2>& hess, const Tiny::Vector<DT_, 2>& p)
354 {
355 hess[0][0][0] = lambda_set.dxx1.f(p[0], p[1]);
356 hess[0][1][1] = lambda_set.dyy1.f(p[0], p[1]);
357 hess[0][0][1] = hess[0][1][0] = lambda_set.dxy1.f(p[0], p[1]);
358 hess[1][0][0] = lambda_set.dxx2.f(p[0], p[1]);
359 hess[1][1][1] = lambda_set.dyy2.f(p[0], p[1]);
360 hess[1][0][1] = hess[1][1][0] = lambda_set.dxy2.f(p[0], p[1]);
361 }
362
364 void eval_hess(Tiny::Tensor3<DT_, 3, 3, 3>& hess, const Tiny::Vector<DT_, 3>& p)
365 {
366 hess[0][0][0] = lambda_set.dxx1.f(p[0], p[1], p[2]);
367 hess[0][1][1] = lambda_set.dyy1.f(p[0], p[1], p[2]);
368 hess[0][2][2] = lambda_set.dzz1.f(p[0], p[1], p[2]);
369 hess[0][0][1] = hess[0][1][0] = lambda_set.dxy1.f(p[0], p[1], p[2]);
370 hess[0][1][2] = hess[0][2][1] = lambda_set.dyz1.f(p[0], p[1], p[2]);
371 hess[0][2][0] = hess[0][0][2] = lambda_set.dzx1.f(p[0], p[1], p[2]);
372 hess[1][0][0] = lambda_set.dxx2.f(p[0], p[1], p[2]);
373 hess[1][1][1] = lambda_set.dyy2.f(p[0], p[1], p[2]);
374 hess[1][2][2] = lambda_set.dzz2.f(p[0], p[1], p[2]);
375 hess[1][0][1] = hess[1][1][0] = lambda_set.dxy2.f(p[0], p[1], p[2]);
376 hess[1][1][2] = hess[1][2][1] = lambda_set.dyz2.f(p[0], p[1], p[2]);
377 hess[1][2][0] = hess[1][0][2] = lambda_set.dzx2.f(p[0], p[1], p[2]);
378 hess[2][0][0] = lambda_set.dxx3.f(p[0], p[1], p[2]);
379 hess[2][1][1] = lambda_set.dyy3.f(p[0], p[1], p[2]);
380 hess[2][2][2] = lambda_set.dzz3.f(p[0], p[1], p[2]);
381 hess[2][0][1] = hess[2][1][0] = lambda_set.dxy3.f(p[0], p[1], p[2]);
382 hess[2][1][2] = hess[2][2][1] = lambda_set.dyz3.f(p[0], p[1], p[2]);
383 hess[2][2][0] = hess[2][0][2] = lambda_set.dzx3.f(p[0], p[1], p[2]);
384 }
385 }; // class LambdaHessHelper<...> (explicit 2D formula)
386
396 template<typename LambdaSet_, int dim_, typename DT_, typename VT_, typename HT_>
397 class LambdaHessHelper<LambdaSet_, dim_, DT_, VT_, HT_, false>
398 {
399 public:
400 LambdaSet_& lambda_set;
401 const DT_ initial_h;
402 const std::size_t max_steps;
403
404 explicit LambdaHessHelper(LambdaSet_& lambda_set_, DT_ initial_h_, int max_steps_) :
405 lambda_set(lambda_set_),
406 initial_h(initial_h_),
407 max_steps(std::size_t(max_steps_))
408 {
409 }
410
411 void eval_hess(HT_& hess, const Tiny::Vector<DT_, dim_>& point)
412 {
413 // first, create a mutable copy of our point
414 Tiny::Vector<DT_, dim_> v(point);
415
417 std::vector<HT_> hessex(max_steps);
418
419 // next, choose the initial h
420 DT_ h(initial_h);
421
422 // evaluate hessian
423 eval_hess_diff_quot(hessex[0], v, h);
424
425 // Now comes the Richardson extrapolation loop
426 const std::size_t n(hessex.size()-1);
427 DT_ def(Math::huge<DT_>());
428 for(std::size_t i(0); i < n; ++i)
429 {
430 // evaluate next hessian
431 eval_hess_diff_quot(hessex[i+1], v, h *= DT_(0.5));
432
433 // initialize scaling factor
434 DT_ q = DT_(1);
435
436 // perform extrapolation steps except for the last one
437 for(std::size_t k(i); k > std::size_t(0); --k)
438 {
439 q *= DT_(4);
440 (hessex[k] -= q*hessex[k+1]) *= DT_(1) / (DT_(1) - q);
441 }
442
443 // compute and check our defect
444 DT_ d = def_norm_sqr(hessex[1], hessex[0]);
445 if(def <= d)
446 {
447 // The defect has increased, so we return the previous extrapolation result
448 break;
449 }
450
451 // remember current defect
452 def = d;
453
454 // perform last extrapolation step
455 q *= DT_(4);
456 (hessex[0] -= q*hessex[1]) *= DT_(1) / (DT_(1) - q);
457 }
458
459 // return our extrapolated hessian
460 hess = hessex.front();
461 }
462
464 template<int m_, int n_, int sm_, int sn_>
465 static DT_ def_norm_sqr(
466 const Tiny::Matrix<DT_, m_, n_, sm_, sn_>& x,
467 const Tiny::Matrix<DT_, m_, n_, sm_, sn_>& y)
468 {
469 return (x - y).norm_hessian_sqr();
470 }
471
473 template<int l_, int m_, int n_, int sl_, int sm_, int sn_>
474 static DT_ def_norm_sqr(
475 const Tiny::Tensor3<DT_, l_, m_, n_, sl_, sm_, sn_>& x,
476 const Tiny::Tensor3<DT_, l_, m_, n_, sl_, sm_, sn_>& y)
477 {
478 DT_ r(DT_(0));
479 for(int i(0); i < l_; ++i)
480 {
481 for(int j(0); j < m_; ++j)
482 {
483 for(int k(0); k < n_; ++k)
484 {
485 r += Math::sqr(x(i,j,k) - y(i,j,k));
486 }
487 }
488 }
489 return r;
490 }
491
492 // compute scalar difference quotient for i == j
493 static void set_diff_quot(Tiny::Matrix<DT_, dim_, dim_>& x, int i, const VT_& vr, const VT_& vl, const VT_& vc, const DT_ denom)
494 {
495 x[i][i] = denom * (vr + vl - DT_(2)*vc);
496 }
497
498 // compute scalar difference quotient for i != j
499 static void set_diff_quot(Tiny::Matrix<DT_, dim_, dim_>& x, int i, int j, const VT_& vne, const VT_& vsw, const VT_& vnw, const VT_& vse, const DT_ denom)
500 {
501 x[i][j] = x[j][i] = denom * ((vne + vsw) - (vnw + vse));
502 }
503
504 // compute vector difference quotient for i == j
505 static void set_diff_quot(Tiny::Tensor3<DT_, dim_, dim_, dim_>& x, int i, const VT_& vr, const VT_& vl, const VT_& vc, const DT_ denom)
506 {
507 for(int k(0); k < dim_; ++k)
508 x[k][i][i] = denom * (vr[k] + vl[k] - DT_(2)*vc[k]);
509 }
510
511 // compute vector difference quotient for i != j
512 static void set_diff_quot(Tiny::Tensor3<DT_, dim_, dim_, dim_>& x, int i, int j, const VT_& vne, const VT_& vsw, const VT_& vnw, const VT_& vse, const DT_ denom)
513 {
514 for(int k(0); k < dim_; ++k)
515 x[k][i][j] = x[k][j][i] = denom * ((vne[k] + vsw[k]) - (vnw[k] + vse[k]));
516 }
517
519 void eval_hess_diff_quot(HT_& x, Tiny::Vector<DT_, dim_>& v, const DT_ h)
520 {
521 // difference quotient denominators
522 const DT_ denom1 = DT_(1) / (h * h);
523 const DT_ denom2 = DT_(1) / (DT_(4) * h * h);
524 VT_ vc, vr, vl, vne, vnw, vse, vsw;
525
526 // evaluate at point
527 vc = lambda_set.eval_value(v);
528
529 // loop over all dimensions
530 for(int i(0); i < dim_; ++i)
531 {
532 // backup coord
533 const DT_ vi(v[i]);
534
535 // eval f(x + h*e_i)
536 v[i] = vi + h;
537 vr = lambda_set.eval_value(v);
538
539 // eval f(x-h)
540 v[i] = vi - h;
541 vl = lambda_set.eval_value(v);
542
543 // compute difference quotient
544 set_diff_quot(x, i, vr, vl, vc, denom1);
545
546 // now the mixed derivatives
547 for(int j(i+1); j < dim_; ++j)
548 {
549 // backup coord
550 const DT_ vj(v[j]);
551
552 // we need four points here:
553 // north-east: f(v + h*e_i + h*e_j)
554 v[i] = vi + h;
555 v[j] = vj + h;
556 vne = lambda_set.eval_value(v);
557
558 // north-west: f(v - h*e_i + h*e_j)
559 v[i] = vi - h;
560 v[j] = vj + h;
561 vnw = lambda_set.eval_value(v);
562
563 // south-east: f(v + h*e_i - h*e_j)
564 v[i] = vi + h;
565 v[j] = vj - h;
566 vse = lambda_set.eval_value(v);
567
568 // south-west: f(v - h*e_i - h*e_j)
569 v[i] = vi - h;
570 v[j] = vj - h;
571 vsw = lambda_set.eval_value(v);
572
573 // combine into difference quotient
574 set_diff_quot(x, i, j, vne, vsw, vnw, vse, denom2);
575
576 // restore coord
577 v[j] = vj;
578 }
579
580 // restore coord
581 v[i] = vi;
582 }
583 }
584 }; // class LambdaHessHelper<...> (Richardson extrapolation)
585
607 template<typename LambdaSet_, typename Traits_, bool have_grad, bool have_hess>
608 class LambdaFunctionEvaluator :
609 public Analytic::Function::Evaluator<Traits_>
610 {
611 public:
612 static constexpr int domain_dim = Traits_::domain_dim;
613 typedef typename Traits_::DataType DataType;
614 typedef typename Traits_::PointType PointType;
615 typedef typename Traits_::ValueType ValueType;
616 typedef typename Traits_::GradientType GradientType;
617 typedef typename Traits_::HessianType HessianType;
618
620 LambdaSet_ lambda_set;
621
623 Intern::LambdaGradHelper<LambdaSet_, domain_dim, DataType, ValueType, GradientType, have_grad> grad_helper;
624
626 Intern::LambdaHessHelper<LambdaSet_, domain_dim, DataType, ValueType, HessianType, have_hess> hess_helper;
627
628 public:
629 template<typename LambdaFunction_>
630 explicit LambdaFunctionEvaluator(const LambdaFunction_& function) :
631 lambda_set(function.lambda_set),
632 grad_helper(lambda_set, DataType(function.initial_h_grad), function.max_steps_grad),
633 hess_helper(lambda_set, DataType(function.initial_h_hess), function.max_steps_hess)
634 {
635 }
636
638 ValueType value(const PointType& point)
639 {
640 return lambda_set.eval_value(point);
641 }
642
644 GradientType gradient(const PointType& point)
645 {
646 GradientType grad;
647 grad_helper.eval_grad(grad, point);
648 return grad;
649 }
650
652 HessianType hessian(const PointType& point)
653 {
654 HessianType hess;
655 hess_helper.eval_hess(hess, point);
656 return hess;
657 }
658 }; // class LambdaFunctionEvaluator<...>
659 } // namespace Intern
661
672 template<typename LambdaValue_, typename LambdaDx_ = void, typename LambdaDxx_ = void>
674 public Analytic::Function
675 {
676 public:
678 static constexpr int domain_dim = 1;
681
683 static constexpr bool have_value = Intern::LambdaHelper<LambdaValue_>::have;
685 static constexpr bool have_grad = Intern::LambdaHelper<LambdaDx_>::have;
687 static constexpr bool have_hess = Intern::LambdaHelper<LambdaDxx_>::have;
688
690 static_assert(have_value, "LambdaScalarFunction1D needs at least the function value formula");
691
693 static constexpr bool can_value = true;
695 static constexpr bool can_grad = true;
697 static constexpr bool can_hess = true;
698
707 {
708 public:
710 Intern::LambdaHelper<LambdaValue_> value;
712 Intern::LambdaHelper<LambdaDx_> dx;
714 Intern::LambdaHelper<LambdaDxx_> dxx;
716 const Intern::LambdaHelper<void> dy;
718 const Intern::LambdaHelper<void> dz;
720 const Intern::LambdaHelper<void> dyy;
722 const Intern::LambdaHelper<void> dzz;
724 const Intern::LambdaHelper<void> dxy;
726 const Intern::LambdaHelper<void> dyz;
728 const Intern::LambdaHelper<void> dzx;
729
731 explicit LambdaSet(LambdaValue_&& value_) :
732 value(std::forward<LambdaValue_>(value_))
733 {
734 }
735
737 template<typename LDx_>
738 explicit LambdaSet(LambdaValue_&& value_, LDx_&& dx_) :
739 value(std::forward<LambdaValue_>(value_)),
740 dx(std::forward<LDx_>(dx_))
741 {
742 }
743
745 template<typename LDx_, typename LDxx_>
746 explicit LambdaSet(LambdaValue_&& value_, LDx_&& dx_, LDxx_&& dxx_) :
747 value(std::forward<LambdaValue_>(value_)),
748 dx(std::forward<LDx_>(dx_)),
749 dxx(std::forward<LDxx_>(dxx_))
750 {
751 }
752
754 template<typename DT_>
756 {
757 return value.f(v[0]);
758 }
759 }; // class LambdaSet
760
763
765 template<typename Traits_>
766 using Evaluator = Intern::LambdaFunctionEvaluator<LambdaSet, Traits_, have_grad, have_hess>;
767
776
783 template<typename... Lambdas_>
784 explicit LambdaScalarFunction1D(Lambdas_&&... lambdas) :
785 lambda_set(std::forward<Lambdas_>(lambdas)...)
786 {
787 }
788 }; // LambdaScalarFunction1D
789
801 template<typename LambdaValue_>
803 {
804 return LambdaScalarFunction1D<LambdaValue_>(std::forward<LambdaValue_>(value));
805 }
806
821 template<typename LambdaValue_, typename LambdaDx_>
823 {
825 std::forward<LambdaValue_>(value), std::forward<LambdaDx_>(dx));
826 }
827
845 template<typename LambdaValue_, typename LambdaDx_, typename LambdaDxx_>
847 LambdaValue_&& value, LambdaDx_&& dx, LambdaDxx_&& dxx)
848 {
850 std::forward<LambdaValue_>(value), std::forward<LambdaDx_>(dx), std::forward<LambdaDxx_>(dxx));
851 }
852
863 template<typename LambdaValue_,
864 typename LambdaDx_ = void, typename LambdaDy_ = void,
865 typename LambdaDxx_ = void, typename LambdaDyy_ = void, typename LambdaDxy_ = void>
867 public Analytic::Function
868 {
869 public:
871 static constexpr int domain_dim = 2;
874
876 static constexpr bool have_value = Intern::LambdaHelper<LambdaValue_>::have;
878 static constexpr bool have_grad =
879 Intern::LambdaHelper<LambdaDx_>::have &&
880 Intern::LambdaHelper<LambdaDy_>::have;
882 static constexpr bool have_hess =
883 Intern::LambdaHelper<LambdaDxx_>::have &&
884 Intern::LambdaHelper<LambdaDyy_>::have &&
885 Intern::LambdaHelper<LambdaDxy_>::have;
886
888 static_assert(have_value, "LambdaScalarFunction2D needs at least the function value formula");
889
891 static constexpr bool can_value = true;
893 static constexpr bool can_grad = true;
895 static constexpr bool can_hess = true;
896
905 {
906 public:
908 Intern::LambdaHelper<LambdaValue_> value;
910 Intern::LambdaHelper<LambdaDx_> dx;
912 Intern::LambdaHelper<LambdaDy_> dy;
914 Intern::LambdaHelper<LambdaDxx_> dxx;
916 Intern::LambdaHelper<LambdaDyy_> dyy;
918 Intern::LambdaHelper<LambdaDxy_> dxy;
920 const Intern::LambdaHelper<void> dz;
922 const Intern::LambdaHelper<void> dzz;
924 const Intern::LambdaHelper<void> dyz;
926 const Intern::LambdaHelper<void> dzx;
927
929 explicit LambdaSet(LambdaValue_&& value_) :
930 value(std::forward<LambdaValue_>(value_))
931 {
932 }
933
935 template<typename LDx_, typename LDy_>
936 explicit LambdaSet(LambdaValue_&& value_, LDx_&& dx_, LDy_&& dy_) :
937 value(std::forward<LambdaValue_>(value_)),
938 dx(std::forward<LDx_>(dx_)),
939 dy(std::forward<LDy_>(dy_))
940 {
941 }
942
944 template<typename LDx_, typename LDy_, typename LDxx_, typename LDyy_, typename LDxy_>
945 explicit LambdaSet(LambdaValue_&& value_, LDx_&& dx_, LDy_&& dy_, LDxx_&& dxx_, LDyy_&& dyy_, LDxy_&& dxy_) :
946 value(std::forward<LambdaValue_>(value_)),
947 dx(std::forward<LDx_>(dx_)),
948 dy(std::forward<LDy_>(dy_)),
949 dxx(std::forward<LDxx_>(dxx_)),
950 dyy(std::forward<LDyy_>(dyy_)),
951 dxy(std::forward<LDxy_>(dxy_))
952 {
953 }
954
956 template<typename DT_>
958 {
959 return value.f(v[0], v[1]);
960 }
961 }; // class LambdaSet
962
965
967 template<typename Traits_>
968 using Evaluator = Intern::LambdaFunctionEvaluator<LambdaSet, Traits_, have_grad, have_hess>;
969
978
985 template<typename... Lambdas_>
986 explicit LambdaScalarFunction2D(Lambdas_&&... lambdas) :
987 lambda_set(std::forward<Lambdas_>(lambdas)...)
988 {
989 }
990 }; // LambdaScalarFunction2D
991
1003 template<typename LambdaValue_>
1005 {
1006 return LambdaScalarFunction2D<LambdaValue_>(std::forward<LambdaValue_>(value));
1007 }
1008
1023 template<typename LambdaValue_, typename LambdaDx_, typename LambdaDy_>
1025 LambdaValue_&& value, LambdaDx_&& dx, LambdaDy_&& dy)
1026 {
1028 std::forward<LambdaValue_>(value), std::forward<LambdaDx_>(dx), std::forward<LambdaDy_>(dy));
1029 }
1030
1048 template<typename LambdaValue_, typename LambdaDx_, typename LambdaDy_,
1049 typename LambdaDxx_, typename LambdaDyy_, typename LambdaDxy_>
1051 LambdaValue_&& value, LambdaDx_&& dx, LambdaDy_&& dy, LambdaDxx_&& dxx, LambdaDyy_&& dyy, LambdaDxy_&& dxy)
1052 {
1054 std::forward<LambdaValue_>(value), std::forward<LambdaDx_>(dx), std::forward<LambdaDy_>(dy),
1055 std::forward<LambdaDxx_>(dxx), std::forward<LambdaDyy_>(dyy),std::forward<LambdaDxy_>(dxy));
1056 }
1057
1068 template<typename LambdaValue_,
1069 typename LambdaDx_ = void, typename LambdaDy_ = void, typename LambdaDz_ = void,
1070 typename LambdaDxx_ = void, typename LambdaDyy_ = void, typename LambdaDzz_ = void,
1071 typename LambdaDxy_ = void, typename LambdaDyz_ = void, typename LambdaDzx_ = void>
1073 public Analytic::Function
1074 {
1075 public:
1077 static constexpr int domain_dim = 3;
1080
1082 static constexpr bool have_value = Intern::LambdaHelper<LambdaValue_>::have;
1084 static constexpr bool have_grad =
1085 Intern::LambdaHelper<LambdaDx_>::have &&
1086 Intern::LambdaHelper<LambdaDy_>::have &&
1087 Intern::LambdaHelper<LambdaDz_>::have;
1089 static constexpr bool have_hess =
1090 Intern::LambdaHelper<LambdaDxx_>::have &&
1091 Intern::LambdaHelper<LambdaDyy_>::have &&
1092 Intern::LambdaHelper<LambdaDzz_>::have &&
1093 Intern::LambdaHelper<LambdaDxy_>::have &&
1094 Intern::LambdaHelper<LambdaDyz_>::have &&
1095 Intern::LambdaHelper<LambdaDzx_>::have;
1096
1098 static_assert(have_value, "LambdaScalarFunction3D needs at least the function value formula");
1099
1101 static constexpr bool can_value = true;
1103 static constexpr bool can_grad = true;
1105 static constexpr bool can_hess = true;
1106
1115 {
1116 public:
1118 Intern::LambdaHelper<LambdaValue_> value;
1120 Intern::LambdaHelper<LambdaDx_> dx;
1122 Intern::LambdaHelper<LambdaDy_> dy;
1124 Intern::LambdaHelper<LambdaDz_> dz;
1126 Intern::LambdaHelper<LambdaDxx_> dxx;
1128 Intern::LambdaHelper<LambdaDyy_> dyy;
1130 Intern::LambdaHelper<LambdaDzz_> dzz;
1132 Intern::LambdaHelper<LambdaDxy_> dxy;
1134 Intern::LambdaHelper<LambdaDyz_> dyz;
1136 Intern::LambdaHelper<LambdaDzx_> dzx;
1137
1139 explicit LambdaSet(LambdaValue_&& value_) :
1140 value(std::forward<LambdaValue_>(value_))
1141 {
1142 }
1143
1145 template<typename LDx_, typename LDy_, typename LDz_>
1146 explicit LambdaSet(LambdaValue_&& value_, LDx_&& dx_, LDy_&& dy_, LDz_&& dz_) :
1147 value(std::forward<LambdaValue_>(value_)),
1148 dx(std::forward<LDx_>(dx_)),
1149 dy(std::forward<LDy_>(dy_)),
1150 dz(std::forward<LDz_>(dz_))
1151 {
1152 }
1153
1155 template<typename LDx_, typename LDy_, typename LDz_,
1156 typename LDxx_, typename LDyy_, typename LDzz_, typename LDxy_, typename LDyz_, typename LDzx_>
1157 explicit LambdaSet(LambdaValue_&& value_, LDx_&& dx_, LDy_&& dy_, LDz_&& dz_,
1158 LDxx_&& dxx_, LDyy_&& dyy_, LDzz_&& dzz_, LDxy_&& dxy_, LDyz_&& dyz_, LDzx_&& dzx_) :
1159 value(std::forward<LambdaValue_>(value_)),
1160 dx(std::forward<LDx_>(dx_)),
1161 dy(std::forward<LDy_>(dy_)),
1162 dz(std::forward<LDz_>(dz_)),
1163 dxx(std::forward<LDxx_>(dxx_)),
1164 dyy(std::forward<LDyy_>(dyy_)),
1165 dzz(std::forward<LDzz_>(dzz_)),
1166 dxy(std::forward<LDxy_>(dxy_)),
1167 dyz(std::forward<LDyz_>(dyz_)),
1168 dzx(std::forward<LDzx_>(dzx_))
1169 {
1170 }
1171
1173 template<typename DT_>
1175 {
1176 return value.f(v[0], v[1], v[2]);
1177 }
1178 }; // class LambdaSet
1179
1182
1184 template<typename Traits_>
1185 using Evaluator = Intern::LambdaFunctionEvaluator<LambdaSet, Traits_, have_grad, have_hess>;
1186
1195
1202 template<typename... Lambdas_>
1203 explicit LambdaScalarFunction3D(Lambdas_&&... lambdas) :
1204 lambda_set(std::forward<Lambdas_>(lambdas)...)
1205 {
1206 }
1207 }; // LambdaScalarFunction3D
1208
1220 template<typename LambdaValue_>
1222 {
1223 return LambdaScalarFunction3D<LambdaValue_>(std::forward<LambdaValue_>(value));
1224 }
1225
1240 template<typename LambdaValue_, typename LambdaDx_, typename LambdaDy_, typename LambdaDz_>
1242 LambdaValue_&& value, LambdaDx_&& dx, LambdaDy_&& dy, LambdaDz_&& dz)
1243 {
1245 std::forward<LambdaValue_>(value), std::forward<LambdaDx_>(dx), std::forward<LambdaDy_>(dy), std::forward<LambdaDz_>(dz));
1246 }
1247
1265 template<typename LambdaValue_, typename LambdaDx_, typename LambdaDy_, typename LambdaDz_,
1266 typename LambdaDxx_, typename LambdaDyy_, typename LambdaDzz_,
1267 typename LambdaDxy_, typename LambdaDyz_, typename LambdaDzx_>
1268 LambdaScalarFunction3D<LambdaValue_, LambdaDx_, LambdaDy_, LambdaDz_,
1269 LambdaDxx_, LambdaDyy_, LambdaDzz_, LambdaDxy_, LambdaDyz_, LambdaDzx_> create_lambda_function_scalar_3d(
1270 LambdaValue_&& value, LambdaDx_&& dx, LambdaDy_&& dy, LambdaDz_&& dz,
1271 LambdaDxx_&& dxx, LambdaDyy_&& dyy, LambdaDzz_&& dzz, LambdaDxy_&& dxy, LambdaDyz_&& dyz, LambdaDzx_&& dzx)
1272 {
1273 return LambdaScalarFunction3D<LambdaValue_, LambdaDx_, LambdaDy_, LambdaDz_,
1274 LambdaDxx_, LambdaDyy_, LambdaDzz_, LambdaDxy_, LambdaDyz_, LambdaDzx_>(
1275 std::forward<LambdaValue_>(value), std::forward<LambdaDx_>(dx), std::forward<LambdaDy_>(dy), std::forward<LambdaDz_>(dz),
1276 std::forward<LambdaDxx_>(dxx), std::forward<LambdaDyy_>(dyy), std::forward<LambdaDzz_>(dzz),
1277 std::forward<LambdaDxy_>(dxy), std::forward<LambdaDyz_>(dyz), std::forward<LambdaDzx_>(dzx));
1278 }
1279
1292 template<typename Callable_>
1294 {
1295 public:
1297 static constexpr int domain_dim = 2;
1300 typedef typename std::invoke_result_t<Callable_, Tiny::Vector<double,domain_dim>>::DataType CallableInnerType;
1301
1303 static constexpr bool can_value = true;
1305 static constexpr bool can_grad = false;
1307 static constexpr bool can_hess = false;
1308
1309 Callable_ call_func;
1310
1311 SimplifiedLambdaVectorFunction2D(Callable_&& call_func_) :
1312 call_func(std::move(call_func_))
1313 {
1314 }
1315
1316 SimplifiedLambdaVectorFunction2D(const Callable_& call_func_) :
1317 call_func(call_func_)
1318 {
1319 }
1320
1321 template<typename EvalTraits_>
1323 public Analytic::Function::Evaluator<EvalTraits_>
1324 {
1325 public:
1327 typedef typename EvalTraits_::DataType DataType;
1329 typedef typename EvalTraits_::PointType PointType;
1331 typedef typename EvalTraits_::ValueType ValueType;
1332
1333 typedef typename SimplifiedLambdaVectorFunction2D::CallableInnerType InnerType;
1334 static constexpr int domain_dim = SimplifiedLambdaVectorFunction2D::domain_dim;
1336
1337 Callable_ call_func;
1338
1339 public:
1340 explicit Evaluator(const SimplifiedLambdaVectorFunction2D& function) :
1341 call_func(function.call_func)
1342 {
1343 }
1344
1345 ValueType value(const PointType& point)
1346 {
1347 return ValueType::convert(call_func(InnerPointType::convert(point)));
1348 }
1349
1350 }; // class SimplifiedVectorFunction2D::Evaluator<...>
1351 }; // class SimplifiedVectorFuntion2D
1352
1368 template<typename Callable_>
1370 {
1371 public:
1373 static constexpr int domain_dim = 3;
1376
1378 static constexpr bool can_value = true;
1380 static constexpr bool can_grad = false;
1382 static constexpr bool can_hess = false;
1383
1384 Callable_ call_func;
1385
1386 SimplifiedLambdaVectorFunction3D(Callable_&& call_func_) :
1387 call_func(std::move(call_func_))
1388 {
1389 }
1390
1391 SimplifiedLambdaVectorFunction3D(const Callable_& call_func_) :
1392 call_func(call_func_)
1393 {
1394 }
1395
1396 template<typename EvalTraits_>
1398 public Analytic::Function::Evaluator<EvalTraits_>
1399 {
1400 public:
1402 typedef typename EvalTraits_::DataType DataType;
1404 typedef typename EvalTraits_::PointType PointType;
1406 typedef typename EvalTraits_::ValueType ValueType;
1407 static constexpr int domain_dim = SimplifiedLambdaVectorFunction3D::domain_dim;
1408
1409 // typedef typename std::invoke_result_t<Callable_, Tiny::Vector<DataType,domain_dim>>::DataType CallableInnerType;
1410
1411 // typedef CallableInnerType InnerType;
1412
1414
1415 Callable_ call_func;
1416
1417 public:
1418 explicit Evaluator(const SimplifiedLambdaVectorFunction3D& function) :
1419 call_func(function.call_func)
1420 {
1421 }
1422
1423 ValueType value(const PointType& point)
1424 {
1425 // required ? probably not...
1426 // return ValueType::convert(call_func(InnerPointType::convert(point)));
1427 return call_func(point);
1428 }
1429 }; // class SimplifiedVectorFunction3D::Evaluator<...>
1430 }; // class SimplifiedVectorFuntion3D
1431
1442 template<typename LambdaValue1_, typename LambdaValue2_,
1443 typename LambdaDx1_ = void, typename LambdaDx2_ = void,
1444 typename LambdaDy1_ = void, typename LambdaDy2_ = void,
1445 typename LambdaDxx1_ = void, typename LambdaDxx2_ = void,
1446 typename LambdaDyy1_ = void, typename LambdaDyy2_ = void,
1447 typename LambdaDxy1_ = void, typename LambdaDxy2_ = void>
1449 public Analytic::Function
1450 {
1451 public:
1453 static constexpr int domain_dim = 2;
1456
1458 static constexpr bool have_value =
1459 Intern::LambdaHelper<LambdaValue1_>::have &&
1460 Intern::LambdaHelper<LambdaValue2_>::have;
1462 static constexpr bool have_grad =
1463 Intern::LambdaHelper<LambdaDx1_>::have &&
1464 Intern::LambdaHelper<LambdaDx2_>::have &&
1465 Intern::LambdaHelper<LambdaDy1_>::have &&
1466 Intern::LambdaHelper<LambdaDy2_>::have;
1468 static constexpr bool have_hess =
1469 Intern::LambdaHelper<LambdaDxx1_>::have &&
1470 Intern::LambdaHelper<LambdaDxx2_>::have &&
1471 Intern::LambdaHelper<LambdaDyy1_>::have &&
1472 Intern::LambdaHelper<LambdaDyy2_>::have &&
1473 Intern::LambdaHelper<LambdaDxy1_>::have &&
1474 Intern::LambdaHelper<LambdaDxy2_>::have;
1475
1477 static_assert(have_value, "LambdaVectorFunction2D needs at least the function value formula");
1478
1480 static constexpr bool can_value = true;
1482 static constexpr bool can_grad = true;
1484 static constexpr bool can_hess = true;
1485
1494 {
1495 public:
1497 Intern::LambdaHelper<LambdaValue1_> value1;
1498 Intern::LambdaHelper<LambdaValue2_> value2;
1499 Intern::LambdaHelper<void> value3;
1501 Intern::LambdaHelper<LambdaDx1_> dx1;
1502 Intern::LambdaHelper<LambdaDx2_> dx2;
1503 Intern::LambdaHelper<void> dx3;
1505 Intern::LambdaHelper<LambdaDy1_> dy1;
1506 Intern::LambdaHelper<LambdaDy2_> dy2;
1507 Intern::LambdaHelper<void> dy3;
1509 Intern::LambdaHelper<void> dz1;
1510 Intern::LambdaHelper<void> dz2;
1511 Intern::LambdaHelper<void> dz3;
1513 Intern::LambdaHelper<LambdaDxx1_> dxx1;
1514 Intern::LambdaHelper<LambdaDxx2_> dxx2;
1515 Intern::LambdaHelper<void> dxx3;
1517 Intern::LambdaHelper<LambdaDyy1_> dyy1;
1518 Intern::LambdaHelper<LambdaDyy2_> dyy2;
1519 Intern::LambdaHelper<void> dyy3;
1521 Intern::LambdaHelper<void> dzz1;
1522 Intern::LambdaHelper<void> dzz2;
1523 Intern::LambdaHelper<void> dzz3;
1525 Intern::LambdaHelper<LambdaDxy1_> dxy1;
1526 Intern::LambdaHelper<LambdaDxy2_> dxy2;
1527 Intern::LambdaHelper<void> dxy3;
1529 Intern::LambdaHelper<void> dyz1;
1530 Intern::LambdaHelper<void> dyz2;
1531 Intern::LambdaHelper<void> dyz3;
1533 Intern::LambdaHelper<void> dzx1;
1534 Intern::LambdaHelper<void> dzx2;
1535 Intern::LambdaHelper<void> dzx3;
1536
1538 explicit LambdaSet(LambdaValue1_&& value1_, LambdaValue2_&& value2_) :
1539 value1(std::forward<LambdaValue1_>(value1_)),
1540 value2(std::forward<LambdaValue2_>(value2_))
1541 {
1542 }
1543
1545 template<
1546 typename LDx1_, typename LDx2_,
1547 typename LDy1_, typename LDy2_>
1548 explicit LambdaSet(LambdaValue1_&& value1_, LambdaValue2_&& value2_,
1549 LDx1_&& dx1_, LDx2_&& dx2_, LDy1_&& dy1_, LDy2_&& dy2_) :
1550 value1(std::forward<LambdaValue1_>(value1_)),
1551 value2(std::forward<LambdaValue2_>(value2_)),
1552 dx1(std::forward<LDx1_>(dx1_)), dx2(std::forward<LDx2_>(dx2_)),
1553 dy1(std::forward<LDy1_>(dy1_)), dy2(std::forward<LDy2_>(dy2_))
1554 {
1555 }
1556
1558 template<
1559 typename LDx1_, typename LDx2_,
1560 typename LDy1_, typename LDy2_,
1561 typename LDxx1_, typename LDxx2_,
1562 typename LDyy1_, typename LDyy2_,
1563 typename LDxy1_, typename LDxy2_>
1564 explicit LambdaSet(LambdaValue1_&& value1_, LambdaValue2_&& value2_,
1565 LDx1_&& dx1_, LDx2_&& dx2_,
1566 LDy1_&& dy1_, LDy2_&& dy2_,
1567 LDxx1_&& dxx1_, LDxx2_&& dxx2_,
1568 LDyy1_&& dyy1_, LDyy2_&& dyy2_,
1569 LDxy1_&& dxy1_, LDxy2_&& dxy2_) :
1570 value1(std::forward<LambdaValue1_>(value1_)),
1571 value2(std::forward<LambdaValue2_>(value2_)),
1572 dx1(std::forward<LDx1_>(dx1_)), dx2(std::forward<LDx2_>(dx2_)),
1573 dy1(std::forward<LDy1_>(dy1_)), dy2(std::forward<LDy2_>(dy2_)),
1574 dxx1(std::forward<LDxx1_>(dxx1_)), dxx2(std::forward<LDxx2_>(dxx2_)),
1575 dyy1(std::forward<LDyy1_>(dyy1_)), dyy2(std::forward<LDyy2_>(dyy2_)),
1576 dxy1(std::forward<LDxy1_>(dxy1_)), dxy2(std::forward<LDxy2_>(dxy2_))
1577 {
1578 }
1579
1581 template<typename DT_>
1583 {
1584 return Tiny::Vector<DT_, 2>({value1.f(v[0], v[1]), value2.f(v[0], v[1])});
1585 }
1586 }; // class LambdaSet
1587
1590
1592 template<typename Traits_>
1593 using Evaluator = Intern::LambdaFunctionEvaluator<LambdaSet, Traits_, have_grad, have_hess>;
1594
1603
1610 template<typename... Lambdas_>
1611 explicit LambdaVectorFunction2D(Lambdas_&&... lambdas) :
1612 lambda_set(std::forward<Lambdas_>(lambdas)...)
1613 {
1614 }
1615 }; // LambdaVectorFunction2D
1616
1628 template<typename LambdaValue1_, typename LambdaValue2_>
1629 LambdaVectorFunction2D<LambdaValue1_, LambdaValue2_>
1630 create_lambda_function_vector_2d(LambdaValue1_&& value1, LambdaValue2_&& value2)
1631 {
1633 std::forward<LambdaValue1_>(value1), std::forward<LambdaValue2_>(value2));
1634 }
1635
1650 template<typename LambdaValue1_, typename LambdaValue2_,
1651 typename LambdaDx1_, typename LambdaDx2_, typename LambdaDy1_, typename LambdaDy2_>
1652 LambdaVectorFunction2D<LambdaValue1_, LambdaValue2_, LambdaDx1_, LambdaDx2_, LambdaDy1_, LambdaDy2_>
1653 create_lambda_function_vector_2d(LambdaValue1_&& value1, LambdaValue2_&& value2,
1654 LambdaDx1_&& dx1, LambdaDx2_&& dx2, LambdaDy1_&& dy1, LambdaDy2_&& dy2)
1655 {
1656 return LambdaVectorFunction2D<LambdaValue1_, LambdaValue2_,
1657 LambdaDx1_, LambdaDx2_, LambdaDy1_, LambdaDy2_>(
1658 std::forward<LambdaValue1_>(value1), std::forward<LambdaValue2_>(value2),
1659 std::forward<LambdaDx1_>(dx1), std::forward<LambdaDx2_>(dx2),
1660 std::forward<LambdaDy1_>(dy1), std::forward<LambdaDy2_>(dy2));
1661 }
1662
1680 template<typename LambdaValue1_, typename LambdaValue2_,
1681 typename LambdaDx1_, typename LambdaDx2_,
1682 typename LambdaDy1_, typename LambdaDy2_,
1683 typename LambdaDxx1_, typename LambdaDxx2_,
1684 typename LambdaDyy1_, typename LambdaDyy2_,
1685 typename LambdaDxy1_, typename LambdaDxy2_>
1686 LambdaVectorFunction2D<LambdaValue1_, LambdaValue2_, LambdaDx1_, LambdaDx2_, LambdaDy1_, LambdaDy2_,
1687 LambdaDxx1_, LambdaDxx2_, LambdaDyy1_, LambdaDyy2_, LambdaDxy1_, LambdaDxy2_>
1688 create_lambda_function_vector_2d(LambdaValue1_&& value1, LambdaValue2_&& value2,
1689 LambdaDx1_&& dx1, LambdaDx2_&& dx2, LambdaDy1_&& dy1, LambdaDy2_&& dy2,
1690 LambdaDxx1_&& dxx1, LambdaDxx2_&& dxx2,
1691 LambdaDyy1_&& dyy1, LambdaDyy2_&& dyy2,
1692 LambdaDxy1_&& dxy1, LambdaDxy2_&& dxy2)
1693 {
1694 return LambdaVectorFunction2D<LambdaValue1_, LambdaValue2_, LambdaDx1_, LambdaDx2_, LambdaDy1_, LambdaDy2_,
1695 LambdaDxx1_, LambdaDxx2_, LambdaDyy1_, LambdaDyy2_, LambdaDxy1_, LambdaDxy2_>(
1696 std::forward<LambdaValue1_>(value1), std::forward<LambdaValue2_>(value2),
1697 std::forward<LambdaDx1_>(dx1), std::forward<LambdaDx2_>(dx2),
1698 std::forward<LambdaDy1_>(dy1), std::forward<LambdaDy2_>(dy2),
1699 std::forward<LambdaDxx1_>(dxx1), std::forward<LambdaDxx2_>(dxx2),
1700 std::forward<LambdaDyy1_>(dyy1), std::forward<LambdaDyy2_>(dyy2),
1701 std::forward<LambdaDxy1_>(dxy1), std::forward<LambdaDxy2_>(dxy2));
1702 }
1703
1714 template<typename LambdaValue1_,typename LambdaValue2_,typename LambdaValue3_,
1715 typename LambdaDx1_ = void, typename LambdaDx2_ = void, typename LambdaDx3_ = void,
1716 typename LambdaDy1_ = void, typename LambdaDy2_ = void, typename LambdaDy3_ = void,
1717 typename LambdaDz1_ = void, typename LambdaDz2_ = void, typename LambdaDz3_ = void,
1718 typename LambdaDxx1_ = void, typename LambdaDxx2_ = void, typename LambdaDxx3_ = void,
1719 typename LambdaDyy1_ = void, typename LambdaDyy2_ = void, typename LambdaDyy3_ = void,
1720 typename LambdaDzz1_ = void, typename LambdaDzz2_ = void, typename LambdaDzz3_ = void,
1721 typename LambdaDxy1_ = void, typename LambdaDxy2_ = void, typename LambdaDxy3_ = void,
1722 typename LambdaDyz1_ = void, typename LambdaDyz2_ = void, typename LambdaDyz3_ = void,
1723 typename LambdaDzx1_ = void, typename LambdaDzx2_ = void, typename LambdaDzx3_ = void
1724 >
1726 public Analytic::Function
1727 {
1728 public:
1730 static constexpr int domain_dim = 3;
1733
1735 static constexpr bool have_value =
1736 Intern::LambdaHelper<LambdaValue1_>::have &&
1737 Intern::LambdaHelper<LambdaValue2_>::have &&
1738 Intern::LambdaHelper<LambdaValue3_>::have;
1740 static constexpr bool have_grad =
1741 Intern::LambdaHelper<LambdaDx1_>::have &&
1742 Intern::LambdaHelper<LambdaDx2_>::have &&
1743 Intern::LambdaHelper<LambdaDx3_>::have &&
1744 Intern::LambdaHelper<LambdaDy1_>::have &&
1745 Intern::LambdaHelper<LambdaDy2_>::have &&
1746 Intern::LambdaHelper<LambdaDy3_>::have &&
1747 Intern::LambdaHelper<LambdaDz1_>::have &&
1748 Intern::LambdaHelper<LambdaDz2_>::have &&
1749 Intern::LambdaHelper<LambdaDz3_>::have;
1751 static constexpr bool have_hess =
1752 Intern::LambdaHelper<LambdaDxx1_>::have &&
1753 Intern::LambdaHelper<LambdaDxx2_>::have &&
1754 Intern::LambdaHelper<LambdaDxx3_>::have &&
1755 Intern::LambdaHelper<LambdaDyy1_>::have &&
1756 Intern::LambdaHelper<LambdaDyy2_>::have &&
1757 Intern::LambdaHelper<LambdaDyy3_>::have &&
1758 Intern::LambdaHelper<LambdaDzz1_>::have &&
1759 Intern::LambdaHelper<LambdaDzz2_>::have &&
1760 Intern::LambdaHelper<LambdaDzz3_>::have &&
1761 Intern::LambdaHelper<LambdaDxy1_>::have &&
1762 Intern::LambdaHelper<LambdaDxy2_>::have &&
1763 Intern::LambdaHelper<LambdaDxy3_>::have &&
1764 Intern::LambdaHelper<LambdaDyz1_>::have &&
1765 Intern::LambdaHelper<LambdaDyz2_>::have &&
1766 Intern::LambdaHelper<LambdaDyz3_>::have &&
1767 Intern::LambdaHelper<LambdaDzx1_>::have &&
1768 Intern::LambdaHelper<LambdaDzx2_>::have &&
1769 Intern::LambdaHelper<LambdaDzx3_>::have;
1770
1772 static_assert(have_value, "LambdaVectorFunction3D needs at least the function value formula");
1773
1775 static constexpr bool can_value = true;
1777 static constexpr bool can_grad = true;
1779 static constexpr bool can_hess = true;
1780
1789 {
1790 public:
1792 Intern::LambdaHelper<LambdaValue1_> value1;
1793 Intern::LambdaHelper<LambdaValue2_> value2;
1794 Intern::LambdaHelper<LambdaValue3_> value3;
1796 Intern::LambdaHelper<LambdaDx1_> dx1;
1797 Intern::LambdaHelper<LambdaDx2_> dx2;
1798 Intern::LambdaHelper<LambdaDx3_> dx3;
1800 Intern::LambdaHelper<LambdaDy1_> dy1;
1801 Intern::LambdaHelper<LambdaDy2_> dy2;
1802 Intern::LambdaHelper<LambdaDy3_> dy3;
1804 Intern::LambdaHelper<LambdaDz1_> dz1;
1805 Intern::LambdaHelper<LambdaDz2_> dz2;
1806 Intern::LambdaHelper<LambdaDz3_> dz3;
1808 Intern::LambdaHelper<LambdaDxx1_> dxx1;
1809 Intern::LambdaHelper<LambdaDxx2_> dxx2;
1810 Intern::LambdaHelper<LambdaDxx3_> dxx3;
1812 Intern::LambdaHelper<LambdaDyy1_> dyy1;
1813 Intern::LambdaHelper<LambdaDyy2_> dyy2;
1814 Intern::LambdaHelper<LambdaDyy3_> dyy3;
1816 Intern::LambdaHelper<LambdaDzz1_> dzz1;
1817 Intern::LambdaHelper<LambdaDzz2_> dzz2;
1818 Intern::LambdaHelper<LambdaDzz3_> dzz3;
1820 Intern::LambdaHelper<LambdaDxy1_> dxy1;
1821 Intern::LambdaHelper<LambdaDxy2_> dxy2;
1822 Intern::LambdaHelper<LambdaDxy3_> dxy3;
1824 Intern::LambdaHelper<LambdaDyz1_> dyz1;
1825 Intern::LambdaHelper<LambdaDyz2_> dyz2;
1826 Intern::LambdaHelper<LambdaDyz3_> dyz3;
1828 Intern::LambdaHelper<LambdaDzx1_> dzx1;
1829 Intern::LambdaHelper<LambdaDzx2_> dzx2;
1830 Intern::LambdaHelper<LambdaDzx3_> dzx3;
1831
1833 explicit LambdaSet(LambdaValue1_&& value1_, LambdaValue2_&& value2_, LambdaValue3_&& value3_) :
1834 value1(std::forward<LambdaValue1_>(value1_)),
1835 value2(std::forward<LambdaValue2_>(value2_)),
1836 value3(std::forward<LambdaValue3_>(value3_))
1837 {
1838 }
1839
1841 template<
1842 typename LDx1_, typename LDx2_, typename LDx3_,
1843 typename LDy1_, typename LDy2_, typename LDy3_,
1844 typename LDz1_, typename LDz2_, typename LDz3_>
1845 explicit LambdaSet(LambdaValue1_&& value1_, LambdaValue2_&& value2_, LambdaValue3_&& value3_,
1846 LDx1_&& dx1_, LDx2_&& dx2_, LDx3_&& dx3_,
1847 LDy1_&& dy1_, LDy2_&& dy2_, LDy3_&& dy3_,
1848 LDz1_&& dz1_, LDz2_&& dz2_, LDz3_&& dz3_) :
1849 value1(std::forward<LambdaValue1_>(value1_)),
1850 value2(std::forward<LambdaValue2_>(value2_)),
1851 value3(std::forward<LambdaValue3_>(value3_)),
1852 dx1(std::forward<LDx1_>(dx1_)), dx2(std::forward<LDx2_>(dx2_)), dx3(std::forward<LDx3_>(dx3_)),
1853 dy1(std::forward<LDy1_>(dy1_)), dy2(std::forward<LDy2_>(dy2_)), dy3(std::forward<LDy3_>(dy3_)),
1854 dz1(std::forward<LDz1_>(dz1_)), dz2(std::forward<LDz2_>(dz2_)), dz3(std::forward<LDz3_>(dz3_))
1855 {
1856 }
1857
1859 template<
1860 typename LDx1_, typename LDx2_, typename LDx3_,
1861 typename LDy1_, typename LDy2_, typename LDy3_,
1862 typename LDz1_, typename LDz2_, typename LDz3_,
1863 typename LDxx1_, typename LDxx2_, typename LDxx3_,
1864 typename LDyy1_, typename LDyy2_, typename LDyy3_,
1865 typename LDzz1_, typename LDzz2_, typename LDzz3_,
1866 typename LDxy1_, typename LDxy2_, typename LDxy3_,
1867 typename LDyz1_, typename LDyz2_, typename LDyz3_,
1868 typename LDzx1_, typename LDzx2_, typename LDzx3_>
1869 explicit LambdaSet(LambdaValue1_&& value1_, LambdaValue2_&& value2_, LambdaValue3_&& value3_,
1870 LDx1_&& dx1_, LDx2_&& dx2_, LDx3_&& dx3_,
1871 LDy1_&& dy1_, LDy2_&& dy2_, LDy3_&& dy3_,
1872 LDz1_&& dz1_, LDz2_&& dz2_, LDz3_&& dz3_,
1873 LDxx1_&& dxx1_, LDxx2_&& dxx2_, LDxx3_&& dxx3_,
1874 LDyy1_&& dyy1_, LDyy2_&& dyy2_, LDyy3_&& dyy3_,
1875 LDzz1_&& dzz1_, LDzz2_&& dzz2_, LDzz3_&& dzz3_,
1876 LDxy1_&& dxy1_, LDxy2_&& dxy2_, LDxy3_&& dxy3_,
1877 LDyz1_&& dyz1_, LDyz2_&& dyz2_, LDyz3_&& dyz3_,
1878 LDzx1_&& dzx1_, LDzx2_&& dzx2_, LDzx3_&& dzx3_) :
1879 value1(std::forward<LambdaValue1_>(value1_)),
1880 value2(std::forward<LambdaValue2_>(value2_)),
1881 value3(std::forward<LambdaValue3_>(value3_)),
1882 dx1(std::forward<LDx1_>(dx1_)), dx2(std::forward<LDx2_>(dx2_)), dx3(std::forward<LDx3_>(dx3_)),
1883 dy1(std::forward<LDy1_>(dy1_)), dy2(std::forward<LDy2_>(dy2_)), dy3(std::forward<LDy3_>(dy3_)),
1884 dz1(std::forward<LDz1_>(dz1_)), dz2(std::forward<LDz2_>(dz2_)), dz3(std::forward<LDz3_>(dz3_)),
1885 dxx1(std::forward<LDxx1_>(dxx1_)), dxx2(std::forward<LDxx2_>(dxx2_)), dxx3(std::forward<LDxx3_>(dxx3_)),
1886 dyy1(std::forward<LDyy1_>(dyy1_)), dyy2(std::forward<LDyy2_>(dyy2_)), dyy3(std::forward<LDyy3_>(dyy3_)),
1887 dzz1(std::forward<LDzz1_>(dzz1_)), dzz2(std::forward<LDzz2_>(dzz2_)), dzz3(std::forward<LDzz3_>(dzz3_)),
1888 dxy1(std::forward<LDxy1_>(dxy1_)), dxy2(std::forward<LDxy2_>(dxy2_)), dxy3(std::forward<LDxy3_>(dxy3_)),
1889 dyz1(std::forward<LDyz1_>(dyz1_)), dyz2(std::forward<LDyz2_>(dyz2_)), dyz3(std::forward<LDyz3_>(dyz3_)),
1890 dzx1(std::forward<LDzx1_>(dzx1_)), dzx2(std::forward<LDzx2_>(dzx2_)), dzx3(std::forward<LDzx3_>(dzx3_))
1891 {
1892 }
1893
1895 template<typename DT_>
1897 {
1898 return Tiny::Vector<DT_, 3>({
1899 value1.f(v[0], v[1], v[2]),
1900 value2.f(v[0], v[1], v[2]),
1901 value3.f(v[0], v[1], v[2])});
1902 }
1903 }; // class LambdaSet
1904
1907
1909 template<typename Traits_>
1910 using Evaluator = Intern::LambdaFunctionEvaluator<LambdaSet, Traits_, have_grad, have_hess>;
1911
1920
1927 template<typename... Lambdas_>
1928 explicit LambdaVectorFunction3D(Lambdas_&&... lambdas) :
1929 lambda_set(std::forward<Lambdas_>(lambdas)...)
1930 {
1931 }
1932 }; // LambdaVectorFunction3D
1933
1945 template<typename LambdaValue1_, typename LambdaValue2_, typename LambdaValue3_>
1946 LambdaVectorFunction3D<LambdaValue1_, LambdaValue2_, LambdaValue3_>
1947 create_lambda_function_vector_3d(LambdaValue1_&& value1, LambdaValue2_&& value2, LambdaValue3_&& value3)
1948 {
1950 std::forward<LambdaValue1_>(value1), std::forward<LambdaValue2_>(value2), std::forward<LambdaValue3_>(value3));
1951 }
1952
1967 template<typename LambdaValue1_, typename LambdaValue2_, typename LambdaValue3_,
1968 typename LambdaDx1_, typename LambdaDx2_, typename LambdaDx3_,
1969 typename LambdaDy1_, typename LambdaDy2_, typename LambdaDy3_,
1970 typename LambdaDz1_, typename LambdaDz2_, typename LambdaDz3_>
1971 LambdaVectorFunction3D<LambdaValue1_, LambdaValue2_, LambdaValue3_,
1972 LambdaDx1_, LambdaDx2_, LambdaDx3_, LambdaDy1_, LambdaDy2_, LambdaDy3_, LambdaDz1_, LambdaDz2_, LambdaDz3_>
1973 create_lambda_function_vector_3d(LambdaValue1_&& value1, LambdaValue2_&& value2, LambdaValue3_&& value3,
1974 LambdaDx1_&& dx1, LambdaDx2_&& dx2, LambdaDx3_&& dx3,
1975 LambdaDy1_&& dy1, LambdaDy2_&& dy2, LambdaDy3_&& dy3,
1976 LambdaDz1_&& dz1, LambdaDz2_&& dz2, LambdaDz3_&& dz3)
1977 {
1978 return LambdaVectorFunction3D<LambdaValue1_, LambdaValue2_, LambdaValue3_,
1979 LambdaDx1_, LambdaDx2_, LambdaDx3_, LambdaDy1_, LambdaDy2_, LambdaDy3_, LambdaDz1_, LambdaDz2_, LambdaDz3_>(
1980 std::forward<LambdaValue1_>(value1), std::forward<LambdaValue2_>(value2), std::forward<LambdaValue3_>(value3),
1981 std::forward<LambdaDx1_>(dx1), std::forward<LambdaDx2_>(dx2), std::forward<LambdaDx3_>(dx3),
1982 std::forward<LambdaDy1_>(dy1), std::forward<LambdaDy2_>(dy2), std::forward<LambdaDy3_>(dy3),
1983 std::forward<LambdaDz1_>(dz1), std::forward<LambdaDz2_>(dz2), std::forward<LambdaDz3_>(dz3));
1984 }
1985
2003 template<typename LambdaValue1_, typename LambdaValue2_, typename LambdaValue3_,
2004 typename LambdaDx1_, typename LambdaDx2_, typename LambdaDx3_,
2005 typename LambdaDy1_, typename LambdaDy2_, typename LambdaDy3_,
2006 typename LambdaDz1_, typename LambdaDz2_, typename LambdaDz3_,
2007 typename LambdaDxx1_, typename LambdaDxx2_, typename LambdaDxx3_,
2008 typename LambdaDyy1_, typename LambdaDyy2_, typename LambdaDyy3_,
2009 typename LambdaDzz1_, typename LambdaDzz2_, typename LambdaDzz3_,
2010 typename LambdaDxy1_, typename LambdaDxy2_, typename LambdaDxy3_,
2011 typename LambdaDyz1_, typename LambdaDyz2_, typename LambdaDyz3_,
2012 typename LambdaDzx1_, typename LambdaDzx2_, typename LambdaDzx3_>
2013 LambdaVectorFunction3D<LambdaValue1_, LambdaValue2_, LambdaValue3_,
2014 LambdaDx1_, LambdaDx2_, LambdaDx3_, LambdaDy1_, LambdaDy2_, LambdaDy3_, LambdaDz1_, LambdaDz2_, LambdaDz3_,
2015 LambdaDxx1_, LambdaDxx2_, LambdaDxx3_, LambdaDyy1_, LambdaDyy2_, LambdaDyy3_, LambdaDzz1_, LambdaDzz2_, LambdaDzz3_,
2016 LambdaDxy1_, LambdaDxy2_, LambdaDxy3_, LambdaDyz1_, LambdaDyz2_, LambdaDyz3_, LambdaDzx1_, LambdaDzx2_, LambdaDzx3_>
2017 create_lambda_function_vector_3d(LambdaValue1_&& value1, LambdaValue2_&& value2, LambdaValue3_&& value3,
2018 LambdaDx1_&& dx1, LambdaDx2_&& dx2, LambdaDx3_&& dx3,
2019 LambdaDy1_&& dy1, LambdaDy2_&& dy2, LambdaDy3_&& dy3,
2020 LambdaDz1_&& dz1, LambdaDz2_&& dz2, LambdaDz3_&& dz3,
2021 LambdaDxx1_&& dxx1, LambdaDxx2_&& dxx2, LambdaDxx3_&& dxx3,
2022 LambdaDyy1_&& dyy1, LambdaDyy2_&& dyy2, LambdaDyy3_&& dyy3,
2023 LambdaDzz1_&& dzz1, LambdaDzz2_&& dzz2, LambdaDzz3_&& dzz3,
2024 LambdaDxy1_&& dxy1, LambdaDxy2_&& dxy2, LambdaDxy3_&& dxy3,
2025 LambdaDyz1_&& dyz1, LambdaDyz2_&& dyz2, LambdaDyz3_&& dyz3,
2026 LambdaDzx1_&& dzx1, LambdaDzx2_&& dzx2, LambdaDzx3_&& dzx3)
2027 {
2028 return LambdaVectorFunction3D<LambdaValue1_, LambdaValue2_, LambdaValue3_,
2029 LambdaDx1_, LambdaDx2_, LambdaDx3_, LambdaDy1_, LambdaDy2_, LambdaDy3_, LambdaDz1_, LambdaDz2_, LambdaDz3_,
2030 LambdaDxx1_, LambdaDxx2_, LambdaDxx3_, LambdaDyy1_, LambdaDyy2_, LambdaDyy3_, LambdaDzz1_, LambdaDzz2_, LambdaDzz3_,
2031 LambdaDxy1_, LambdaDxy2_, LambdaDxy3_, LambdaDyz1_, LambdaDyz2_, LambdaDyz3_, LambdaDzx1_, LambdaDzx2_, LambdaDzx3_>(
2032 std::forward<LambdaValue1_>(value1), std::forward<LambdaValue2_>(value2), std::forward<LambdaValue3_>(value3),
2033 std::forward<LambdaDx1_>(dx1), std::forward<LambdaDx2_>(dx2), std::forward<LambdaDx3_>(dx3),
2034 std::forward<LambdaDy1_>(dy1), std::forward<LambdaDy2_>(dy2), std::forward<LambdaDy3_>(dy3),
2035 std::forward<LambdaDz1_>(dz1), std::forward<LambdaDz2_>(dz2), std::forward<LambdaDz3_>(dz3),
2036 std::forward<LambdaDxx1_>(dxx1), std::forward<LambdaDxx2_>(dxx2), std::forward<LambdaDxx3_>(dxx3),
2037 std::forward<LambdaDyy1_>(dyy1), std::forward<LambdaDyy2_>(dyy2), std::forward<LambdaDyy3_>(dyy3),
2038 std::forward<LambdaDzz1_>(dzz1), std::forward<LambdaDzz2_>(dzz2), std::forward<LambdaDzz3_>(dzz3),
2039 std::forward<LambdaDxy1_>(dxy1), std::forward<LambdaDxy2_>(dxy2), std::forward<LambdaDxy3_>(dxy3),
2040 std::forward<LambdaDyz1_>(dyz1), std::forward<LambdaDyz2_>(dyz2), std::forward<LambdaDyz3_>(dyz3),
2041 std::forward<LambdaDzx1_>(dzx1), std::forward<LambdaDzx2_>(dzx2), std::forward<LambdaDzx3_>(dzx3));
2042 }
2043 } // namespace Analytic
2044} // namespace FEAT
Analytic Function Evaluator base-class template.
Definition: function.hpp:157
Analytic Function interface.
Definition: function.hpp:112
Lambda function set container class.
Intern::LambdaHelper< LambdaValue_ > value
the lambda for the function value
LambdaSet(LambdaValue_ &&value_)
constructor for values only
const Intern::LambdaHelper< void > dz
dummy helper for Z-derivative
const Intern::LambdaHelper< void > dxy
dummy helper for XY-derivative
LambdaSet(LambdaValue_ &&value_, LDx_ &&dx_, LDxx_ &&dxx_)
constructor for values, gradients and hessians
const Intern::LambdaHelper< void > dy
dummy helper for Y-derivative
LambdaSet(LambdaValue_ &&value_, LDx_ &&dx_)
constructor for values and gradients
Intern::LambdaHelper< LambdaDx_ > dx
the lambda for the X-derivative
DT_ eval_value(const Tiny::Vector< DT_, 1 > &v) const
function value evaluation function
Intern::LambdaHelper< LambdaDxx_ > dxx
the lambda for the XX-derivative
const Intern::LambdaHelper< void > dyz
dummy helper for YZ-derivative
const Intern::LambdaHelper< void > dzz
dummy helper for ZZ-derivative
const Intern::LambdaHelper< void > dzx
dummy helper for ZX-derivative
const Intern::LambdaHelper< void > dyy
dummy helper for YY-derivative
Analytic 1D scalar lambda expression function implementation.
static constexpr bool can_value
nothing makes sense if we cannot compute function values
static constexpr bool have_value
we can compute values if LambdaValue_ is not void
Intern::LambdaFunctionEvaluator< LambdaSet, Traits_, have_grad, have_hess > Evaluator
evaluator class template is outsourced
Real initial_h_hess
initial H for hessian Richardson extrapolation
LambdaScalarFunction1D(Lambdas_ &&... lambdas)
Constructor.
LambdaSet lambda_set
the actual lambda set for this function
Real initial_h_grad
initial H for gradient Richardson extrapolation
static constexpr bool can_hess
we can always compute hessians (either directly or by Richardson extrapolation)
Analytic::Image::Scalar ImageType
this is a a scalar function
static constexpr bool have_grad
we can compute gradients if LambdaDx_ and LambdaDy_ are not void
int max_steps_grad
maximum number of gradient Richardson extrapolation steps
static constexpr bool can_grad
we can always compute gradients (either directly or by Richardson extrapolation)
static constexpr bool have_hess
we can compute hessians if LambdaDxx_, LambdaDyy_ and LambdaDxy_ are not void
static constexpr int domain_dim
this is a 1D function
int max_steps_hess
maximum number of hessian Richardson extrapolation steps
Lambda function set container class.
const Intern::LambdaHelper< void > dyz
dummy helper for YZ-derivative
LambdaSet(LambdaValue_ &&value_)
constructor for values only
const Intern::LambdaHelper< void > dz
dummy helper for Z-derivative
const Intern::LambdaHelper< void > dzx
dummy helper for ZX-derivative
Intern::LambdaHelper< LambdaValue_ > value
the lambda for the function value
DT_ eval_value(const Tiny::Vector< DT_, 2 > &v) const
function value evaluation function
Intern::LambdaHelper< LambdaDx_ > dx
the lambda for the X-derivative
Intern::LambdaHelper< LambdaDxy_ > dxy
the lambda for the XY-derivative
LambdaSet(LambdaValue_ &&value_, LDx_ &&dx_, LDy_ &&dy_)
constructor for values and gradients
Intern::LambdaHelper< LambdaDy_ > dy
the lambda for the Y-derivative
Intern::LambdaHelper< LambdaDyy_ > dyy
the lambda for the YY-derivative
const Intern::LambdaHelper< void > dzz
dummy helper for ZZ-derivative
LambdaSet(LambdaValue_ &&value_, LDx_ &&dx_, LDy_ &&dy_, LDxx_ &&dxx_, LDyy_ &&dyy_, LDxy_ &&dxy_)
constructor for values, gradients and hessians
Intern::LambdaHelper< LambdaDxx_ > dxx
the lambda for the XX-derivative
Analytic scalar 2D lambda expression function implementation.
static constexpr bool can_value
nothing makes sense if we cannot compute function values
static constexpr bool have_hess
we can compute hessians if LambdaDxx_, LambdaDyy_ and LambdaDxy_ are not void
int max_steps_grad
maximum number of gradient Richardson extrapolation steps
static constexpr bool have_value
we can compute values if LambdaValue_ is not void
Real initial_h_grad
initial H for gradient Richardson extrapolation
LambdaScalarFunction2D(Lambdas_ &&... lambdas)
Constructor.
static constexpr bool can_hess
we can always compute hessians (either directly or by Richardson extrapolation)
static constexpr bool have_grad
we can compute gradients if LambdaDx_ and LambdaDy_ are not void
LambdaSet lambda_set
the actual lambda set for this function
Real initial_h_hess
initial H for hessian Richardson extrapolation
Analytic::Image::Scalar ImageType
this is a a scalar function
int max_steps_hess
maximum number of hessian Richardson extrapolation steps
static constexpr bool can_grad
we can always compute gradients (either directly or by Richardson extrapolation)
Intern::LambdaFunctionEvaluator< LambdaSet, Traits_, have_grad, have_hess > Evaluator
evaluator class template is outsourced
static constexpr int domain_dim
this is a 2D function
Intern::LambdaHelper< LambdaDzx_ > dzx
the lambda for the ZX-derivative
Intern::LambdaHelper< LambdaDyy_ > dyy
the lambda for the YY-derivative
LambdaSet(LambdaValue_ &&value_, LDx_ &&dx_, LDy_ &&dy_, LDz_ &&dz_)
constructor for values and gradients
Intern::LambdaHelper< LambdaDxy_ > dxy
the lambda for the XY-derivative
Intern::LambdaHelper< LambdaDzz_ > dzz
the lambda for the ZZ-derivative
Intern::LambdaHelper< LambdaDyz_ > dyz
the lambda for the YZ-derivative
LambdaSet(LambdaValue_ &&value_, LDx_ &&dx_, LDy_ &&dy_, LDz_ &&dz_, LDxx_ &&dxx_, LDyy_ &&dyy_, LDzz_ &&dzz_, LDxy_ &&dxy_, LDyz_ &&dyz_, LDzx_ &&dzx_)
constructor for values, gradients and hessians
Intern::LambdaHelper< LambdaDy_ > dy
the lambda for the Y-derivative
Intern::LambdaHelper< LambdaDz_ > dz
the lambda for the Z-derivative
Intern::LambdaHelper< LambdaDxx_ > dxx
the lambda for the XX-derivative
Intern::LambdaHelper< LambdaDx_ > dx
the lambda for the X-derivative
Intern::LambdaHelper< LambdaValue_ > value
the lambda for the function value
LambdaSet(LambdaValue_ &&value_)
constructor for values only
DT_ eval_value(const Tiny::Vector< DT_, 3 > &v) const
function value evaluation function
Analytic 3D scalar lambda expression function implementation.
static constexpr int domain_dim
this is a 3D function
Analytic::Image::Scalar ImageType
this is a a scalar function
static constexpr bool have_value
we can compute values if LambdaValue_ is not void
LambdaScalarFunction3D(Lambdas_ &&... lambdas)
Constructor.
LambdaSet lambda_set
the actual lambda set for this function
Real initial_h_grad
initial H for gradient Richardson extrapolation
int max_steps_hess
maximum number of hessian Richardson extrapolation steps
static constexpr bool can_hess
we can always compute hessians (either directly or by Richardson extrapolation)
Intern::LambdaFunctionEvaluator< LambdaSet, Traits_, have_grad, have_hess > Evaluator
evaluator class template is outsourced
static constexpr bool have_hess
are all second order lambdas given?
int max_steps_grad
maximum number of gradient Richardson extrapolation steps
static constexpr bool can_value
nothing makes sense if we cannot compute function values
static constexpr bool can_grad
we can always compute gradients (either directly or by Richardson extrapolation)
static constexpr bool have_grad
are all first order lambdas given?
Real initial_h_hess
initial H for hessian Richardson extrapolation
Intern::LambdaHelper< void > dyz1
the lambdas for the YZ-derivatives
LambdaSet(LambdaValue1_ &&value1_, LambdaValue2_ &&value2_, LDx1_ &&dx1_, LDx2_ &&dx2_, LDy1_ &&dy1_, LDy2_ &&dy2_)
constructor for values and gradients
Intern::LambdaHelper< LambdaDyy1_ > dyy1
the lambdas for the YY-derivatives
Tiny::Vector< DT_, 2 > eval_value(const Tiny::Vector< DT_, 2 > &v) const
function value evaluation function
Intern::LambdaHelper< LambdaDx1_ > dx1
the lambdas for the X-derivatives
Intern::LambdaHelper< void > dzz1
the lambdas for the ZZ-derivatives
LambdaSet(LambdaValue1_ &&value1_, LambdaValue2_ &&value2_, LDx1_ &&dx1_, LDx2_ &&dx2_, LDy1_ &&dy1_, LDy2_ &&dy2_, LDxx1_ &&dxx1_, LDxx2_ &&dxx2_, LDyy1_ &&dyy1_, LDyy2_ &&dyy2_, LDxy1_ &&dxy1_, LDxy2_ &&dxy2_)
constructor for values, gradients and hessians
Intern::LambdaHelper< void > dz1
the lambdas for the Z-derivatives
Intern::LambdaHelper< LambdaDy1_ > dy1
the lambdas for the Y-derivatives
LambdaSet(LambdaValue1_ &&value1_, LambdaValue2_ &&value2_)
constructor for values only
Intern::LambdaHelper< LambdaDxy1_ > dxy1
the lambdas for the XY-derivatives
Intern::LambdaHelper< void > dzx1
the lambdas for the ZX-derivatives
Intern::LambdaHelper< LambdaDxx1_ > dxx1
the lambdas for the XX-derivatives
Intern::LambdaHelper< LambdaValue1_ > value1
the lambdas for the function values
Analytic 2D vector-valued lambda expression function implementation.
static constexpr bool can_value
nothing makes sense if we cannot compute function values
static constexpr bool have_grad
are all first order lambdas given?
Intern::LambdaFunctionEvaluator< LambdaSet, Traits_, have_grad, have_hess > Evaluator
evaluator class template is outsourced
static constexpr bool can_hess
we can always compute hessians (either directly or by Richardson extrapolation)
Real initial_h_hess
initial H for hessian Richardson extrapolation
LambdaVectorFunction2D(Lambdas_ &&... lambdas)
Constructor.
static constexpr int domain_dim
this is a 2D function
Real initial_h_grad
initial H for gradient Richardson extrapolation
static constexpr bool can_grad
we can always compute gradients (either directly or by Richardson extrapolation)
LambdaSet lambda_set
the actual lambda set for this function
static constexpr bool have_hess
are all second order lambdas given?
Analytic::Image::Vector< domain_dim > ImageType
this is a vector field
static constexpr bool have_value
we can compute values if LambdaValue_ is not void
int max_steps_hess
maximum number of hessian Richardson extrapolation steps
int max_steps_grad
maximum number of gradient Richardson extrapolation steps
Intern::LambdaHelper< LambdaDxy1_ > dxy1
the lambdas for the XY-derivatives
Intern::LambdaHelper< LambdaDyy1_ > dyy1
the lambdas for the YY-derivatives
Intern::LambdaHelper< LambdaValue1_ > value1
the lambdas for the function values
Intern::LambdaHelper< LambdaDyz1_ > dyz1
the lambdas for the YZ-derivatives
Intern::LambdaHelper< LambdaDy1_ > dy1
the lambdas for the Y-derivatives
LambdaSet(LambdaValue1_ &&value1_, LambdaValue2_ &&value2_, LambdaValue3_ &&value3_, LDx1_ &&dx1_, LDx2_ &&dx2_, LDx3_ &&dx3_, LDy1_ &&dy1_, LDy2_ &&dy2_, LDy3_ &&dy3_, LDz1_ &&dz1_, LDz2_ &&dz2_, LDz3_ &&dz3_, LDxx1_ &&dxx1_, LDxx2_ &&dxx2_, LDxx3_ &&dxx3_, LDyy1_ &&dyy1_, LDyy2_ &&dyy2_, LDyy3_ &&dyy3_, LDzz1_ &&dzz1_, LDzz2_ &&dzz2_, LDzz3_ &&dzz3_, LDxy1_ &&dxy1_, LDxy2_ &&dxy2_, LDxy3_ &&dxy3_, LDyz1_ &&dyz1_, LDyz2_ &&dyz2_, LDyz3_ &&dyz3_, LDzx1_ &&dzx1_, LDzx2_ &&dzx2_, LDzx3_ &&dzx3_)
constructor for values, gradients and hessians
Tiny::Vector< DT_, 3 > eval_value(const Tiny::Vector< DT_, 3 > &v) const
function value evaluation function
LambdaSet(LambdaValue1_ &&value1_, LambdaValue2_ &&value2_, LambdaValue3_ &&value3_)
constructor for values only
Intern::LambdaHelper< LambdaDxx1_ > dxx1
the lambdas for the XX-derivatives
Intern::LambdaHelper< LambdaDzz1_ > dzz1
the lambdas for the ZZ-derivatives
Intern::LambdaHelper< LambdaDx1_ > dx1
the lambdas for the X-derivatives
Intern::LambdaHelper< LambdaDzx1_ > dzx1
the lambdas for the ZX-derivatives
Intern::LambdaHelper< LambdaDz1_ > dz1
the lambdas for the Z-derivatives
LambdaSet(LambdaValue1_ &&value1_, LambdaValue2_ &&value2_, LambdaValue3_ &&value3_, LDx1_ &&dx1_, LDx2_ &&dx2_, LDx3_ &&dx3_, LDy1_ &&dy1_, LDy2_ &&dy2_, LDy3_ &&dy3_, LDz1_ &&dz1_, LDz2_ &&dz2_, LDz3_ &&dz3_)
constructor for values and gradients
Analytic 3D vector-valued lambda expression function implementation.
static constexpr bool can_hess
we can always compute hessians (either directly or by Richardson extrapolation)
static constexpr bool can_grad
we can always compute gradients (either directly or by Richardson extrapolation)
Analytic::Image::Vector< domain_dim > ImageType
this is a vector field
int max_steps_grad
maximum number of gradient Richardson extrapolation steps
Real initial_h_hess
initial H for hessian Richardson extrapolation
static constexpr bool have_value
we can compute values if LambdaValue_ is not void
LambdaVectorFunction3D(Lambdas_ &&... lambdas)
Constructor.
static constexpr bool have_grad
are all first order lambdas given?
int max_steps_hess
maximum number of hessian Richardson extrapolation steps
static constexpr bool can_value
nothing makes sense if we cannot compute function values
static constexpr int domain_dim
this is a 3D function
Intern::LambdaFunctionEvaluator< LambdaSet, Traits_, have_grad, have_hess > Evaluator
evaluator class template is outsourced
static constexpr bool have_hess
are all second order lambdas given?
Real initial_h_grad
initial H for gradient Richardson extrapolation
LambdaSet lambda_set
the actual lambda set for this function
EvalTraits_::DataType DataType
coefficient data type
EvalTraits_::PointType PointType
evaluation point type
Simpler 2D vector version of the general LambdaFunction interface.
static constexpr bool can_hess
we can always compute hessians (either directly or by Richardson extrapolation)
static constexpr bool can_grad
we can always compute gradients (either directly or by Richardson extrapolation)
static constexpr bool can_value
we can always compute values
Analytic::Image::Vector< domain_dim > ImageType
this is a vector field
static constexpr int domain_dim
this is a 2D function
EvalTraits_::DataType DataType
coefficient data type
EvalTraits_::PointType PointType
evaluation point type
Simpler 3D vector version of the general LambdaFunction interface.
static constexpr bool can_grad
we can always compute gradients (either directly or by Richardson extrapolation)
static constexpr int domain_dim
this is a 2D function
static constexpr bool can_value
we can always compute values
static constexpr bool can_hess
we can always compute hessians (either directly or by Richardson extrapolation)
Analytic::Image::Vector< domain_dim > ImageType
this is a vector field
Tiny Vector class template.
CUDA_HOST_DEVICE void convert(const Vector< Tx_, n_, sx_ > &x)
conversion operator
LambdaScalarFunction1D< LambdaValue_ > create_lambda_function_scalar_1d(LambdaValue_ &&value)
Creates a scalar 1D lambda function from function values only.
LambdaVectorFunction3D< LambdaValue1_, LambdaValue2_, LambdaValue3_ > create_lambda_function_vector_3d(LambdaValue1_ &&value1, LambdaValue2_ &&value2, LambdaValue3_ &&value3)
Creates a vector-valued 3D lambda function from function values only.
LambdaScalarFunction2D< LambdaValue_ > create_lambda_function_scalar_2d(LambdaValue_ &&value)
Creates a scalar 2D lambda function from function values only.
LambdaVectorFunction2D< LambdaValue1_, LambdaValue2_ > create_lambda_function_vector_2d(LambdaValue1_ &&value1, LambdaValue2_ &&value2)
Creates a vector-valued 2D lambda function from function values only.
LambdaScalarFunction3D< LambdaValue_ > create_lambda_function_scalar_3d(LambdaValue_ &&value)
Creates a scalar 3D lambda function from function values only.
Type
bitmask for zfp header
Definition: pack.hpp:81
FEAT namespace.
Definition: adjactor.hpp:12
double Real
Real data type.
@ value
specifies whether the space should supply basis function values
@ hess
specifies whether the space should supply basis function hessians
@ grad
specifies whether the space should supply basis function gradients
Scalar Function Image tag class.
Definition: function.hpp:28
Vector Field Image tag class.
Definition: function.hpp:47