31#ifndef __TSG_RULE_LOCAL_POLYNOMIAL_HPP
32#define __TSG_RULE_LOCAL_POLYNOMIAL_HPP
34#include "tsgCoreOneDimensional.hpp"
38#ifndef __TASMANIAN_DOXYGEN_SKIP
43 pwc, localp, semilocalp, localp0, localpb
46 inline erule getEffectiveRule(
int order, TypeOneDRule rule) {
47 if (order == 0)
return erule::pwc;
57 switch(effective_rule) {
67 template<erule effective_rule>
68 int getNumPoints(
int level) {
69 switch(effective_rule) {
72 while (level-- > 0) n *= 3;
76 case erule::semilocalp:
77 return (level == 0) ? 1 : ((1 << level) + 1);
79 return (1 << (level+1)) -1;
81 return ((1 << level) + 1);
85 template<erule effective_rule>
86 int getMaxNumKids() {
return (effective_rule == erule::pwc) ? 4 : 2; }
87 template<erule effrule>
88 int getMaxNumParents() {
89 return ((effrule == erule::pwc or effrule == erule::semilocalp or effrule == erule::localpb) ? 2 : 1);
92 template<erule effective_rule>
93 int getParent(
int point) {
94 switch(effective_rule) {
96 return (point == 0) ? -1 : point / 3;
98 case erule::semilocalp: {
99 int dad = (point + 1) / 2;
100 if (point < 4) dad--;
104 return (point == 0) ? -1 : (point - 1) / 2;
106 return (point < 2) ? -1 : ((point + 1) / 2);
110 template<erule effective_rule>
111 int getStepParent(
int point) {
112 if (effective_rule == erule::pwc){
113 int i3l3 = Maths::int3log3(point);
114 if (point == i3l3/3)
return -1;
115 if (point == i3l3-1)
return -1;
116 int mod3 = point % 3;
117 int mod2 = point % 2;
118 if (mod3 == 2 and mod2 == 0)
return point / 3 + 1;
119 if (mod3 == 0 and mod2 == 1)
return point / 3 - 1;
122 if (effective_rule == erule::semilocalp){
129 }
else if (effective_rule == erule::localpb){
130 return (point == 2) ? 0 : -1;
136 template<erule effective_rule>
137 int getKid(
int point,
int kid_number) {
138 switch(effective_rule) {
140 if (point == 0)
return (kid_number == 0) ? 1 : (kid_number==1) ? 2 : -1;
141 if (kid_number == 3){
142 int i3l3 = Maths::int3log3(point);
143 if (point == i3l3/3)
return -1;
144 if (point == i3l3-1)
return -1;
145 return (point % 2 == 0) ? 3*point + 3 : 3*point - 1;
147 return 3*point + kid_number;
149 case erule::semilocalp:
150 if (kid_number == 0){
156 return 2 * point - 1;
168 return 2 * point + ((kid_number == 0) ? 1 : 2);
173 return (kid_number == 0) ? 2 : -1;
175 return 2*point - ((kid_number == 0) ? 1 : 0);
180 template<erule effective_rule>
181 double getNode(
int point) {
182 switch(effective_rule) {
184 return -2.0 + (1.0 / ((double) Maths::int3log3(point))) * (3*point + 2 - point % 2);
186 case erule::semilocalp:
192 return ((
double)(2*point - 1)) / ((double) Maths::int2log2(point - 1)) - 3.0;
195 return ((
double)(2*point + 3) ) / ((double) Maths::int2log2(point + 1) ) - 3.0;
202 return ((
double)(2*point - 1)) / ((double) Maths::int2log2(point - 1)) - 3.0;
207 template<erule effective_rule>
208 int getLevel(
int point) {
209 switch(effective_rule) {
212 while(point >= 1){ point /= 3; level += 1; }
216 case erule::semilocalp:
217 return (point == 0) ? 0 : (point == 1) ? 1 : (Maths::intlog2(point - 1) + 1);
219 return Maths::intlog2(point + 1);
221 return (point <= 1) ? 0 : (Maths::intlog2(point - 1) + 1);
225 template<erule effective_rule>
226 double getSupport(
int point) {
227 switch(effective_rule) {
229 return 1.0 / (double) Maths::int3log3(point);
231 case erule::semilocalp:
232 return (point == 0) ? 1.0 : 1.0 / ((double) Maths::int2log2(point - 1));
234 return 1.0 / ((double) Maths::int2log2(point + 1));
236 return (point <= 1) ? 2.0 : 1.0 / ((double) Maths::int2log2(point - 1));
240 template<erule effective_rule>
241 double scaleDiffX(
int point) {
242 switch(effective_rule) {
246 return (point <= 2) ? 1.0 :
static_cast<double>(Maths::int2log2(point - 1));
247 case erule::semilocalp:
248 return static_cast<double>(Maths::int2log2(point - 1));
250 return (point == 0) ? 1.0 :
static_cast<double>(Maths::int2log2(point + 1));
257 return static_cast<double>(Maths::int2log2(point - 1));
262 template<erule effective_rule>
263 double scaleX(
int point,
double x) {
264 switch(effective_rule) {
270 case 1:
return (x + 1.0);
271 case 2:
return (x - 1.0);
273 return ((
double) Maths::int2log2(point - 1) * (x + 3.0) + 1.0 - (
double) (2*point));
275 case erule::semilocalp:
276 return ((
double) Maths::int2log2(point - 1) * (x + 3.0) + 1.0 - (
double) (2*point));
278 return ((
double) Maths::int2log2(point + 1) * (x + 3.0) - 3.0 - (
double) (2*point));
281 case 0:
return (x + 1.0) / 2.0;
282 case 1:
return (x - 1.0) / 2.0;
285 return ((
double) Maths::int2log2(point - 1) * (x + 3.0) + 1.0 - (
double) (2*point));
290 template<erule effective_rule>
291 double evalPWQuadratic(
int point,
double x) {
292 if (effective_rule == erule::localp){
294 case 1:
return 1.0 - x;
295 case 2:
return 1.0 + x;
297 return (1.0 - x) * (1.0 + x);
299 }
else if (effective_rule == erule::localpb){
301 case 0:
return 1.0 - x;
302 case 1:
return 1.0 + x;
304 return (1.0 - x) * (1.0 + x);
307 return (1.0 - x) * (1.0 + x);
309 template<erule effective_rule>
310 double evalPWCubic(
int point,
double x) {
311 if (effective_rule == erule::localp){
314 case 1:
return 1.0 - x;
315 case 2:
return 1.0 + x;
317 case 4:
return (1.0 - x) * (1.0 + x);
319 return (point % 2 == 0) ? (1.0 - x) * (1.0 + x) * (3.0 + x) / 3.0 : (1.0 - x) * (1.0 + x) * (3.0 - x) / 3.0;
321 }
else if (effective_rule == erule::localp0){
322 if (point == 0)
return (1.0 - x) * (1.0 + x);
323 }
else if (effective_rule == erule::localpb){
325 case 0:
return 1.0 - x;
326 case 1:
return 1.0 + x;
327 case 2:
return (1.0 - x) * (1.0 + x);
329 return (point % 2 == 0) ? (1.0 - x) * (1.0 + x) * (3.0 + x) / 3.0 : (1.0 - x) * (1.0 + x) * (3.0 - x) / 3.0;
332 return (point % 2 == 0) ? (1.0 - x) * (1.0 + x) * (3.0 + x) / 3.0 : (1.0 - x) * (1.0 + x) * (3.0 - x) / 3.0;
335 template<erule effective_rule>
336 double evalPWPower(
int max_order,
int point,
double x) {
338 if (effective_rule == erule::localp)
if (point <= 8)
return evalPWCubic<effective_rule>(point, x);
339 if (effective_rule == erule::semilocalp)
if (point <= 4)
return evalPWCubic<effective_rule>(point, x);
340 if (effective_rule == erule::localpb)
if (point <= 4)
return evalPWCubic<effective_rule>(point, x);
341 if (effective_rule == erule::localp0)
if (point <= 2)
return evalPWCubic<effective_rule>(point, x);
342 int level = getLevel<effective_rule>(point);
344 double value = (1.0 - x)*(1.0 + x);
345 double phantom_distance = 1.0;
346 int max_ancestors = [&]()->
int{
347 switch(effective_rule) {
348 case erule::pwc:
return 0;
349 case erule::localp:
return max_ancestors = level-2;
350 case erule::semilocalp:
return max_ancestors = level-1;
351 case erule::localpb:
return max_ancestors = level-1;
352 default:
return max_ancestors = level;
355 if (max_order > 0) max_ancestors = std::min(max_ancestors, max_order - 2);
357 for(
int j=0; j < max_ancestors; j++){
367 phantom_distance = 2.0 * phantom_distance + 1.0;
368 int turns = (effective_rule == erule::localp0) ? ((point+1) % most_turns) : ((point-1) % most_turns);
369 double node = (turns < most_turns / 2) ? (phantom_distance - 2.0 * ((
double) turns)) : (-phantom_distance + 2.0 * ((double) (most_turns - 1 - turns)));
370 value *= - ( x - node ) / node;
380 template<erule effective_rule,
bool use_edge_test = false>
381 double evalSupport(
int max_order,
int point,
double x,
bool &isSupported) {
382 auto test_support = [&](
double xn,
int p) ->
bool {
383 if constexpr (use_edge_test) {
389 if constexpr (effective_rule == erule::localp0) {
390 int const pp = p + 2;
391 return (-1.0 <= xn and (xn < 1.0 or (pp < 3 or ((pp & (pp - 1)) == 0))));
392 }
else if constexpr (effective_rule == erule::localpb) {
393 return (-1.0 <= xn and (xn < 1.0 or (p < 3 or ((p & (p - 1)) == 0))));
395 return (-1.0 <= xn and (xn < 1.0 or (p > 1 and ((p & (p - 1)) == 0))));
398 return (std::abs(xn) <= 1.0);
402 switch(effective_rule) {
404 double distance = std::abs(x - getNode<effective_rule>(point));
405 double support = getSupport<effective_rule>(point);
406 isSupported = (distance <= 2.0 * support);
407 return (distance <= support) ? 1.0 : 0.0;
414 const double xn = scaleX<effective_rule>(point, x);
415 if (test_support(xn, point)) {
417 case 1:
return 1.0 - std::abs(xn);
418 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
419 case 3:
return evalPWCubic<effective_rule>(point, xn);
421 return evalPWPower<effective_rule>(max_order, point, xn);
428 case erule::semilocalp:
432 case 1:
return 0.5 * x * (x - 1.0);
433 case 2:
return 0.5 * x * (x + 1.0);
435 const double xn = scaleX<effective_rule>(point, x);
436 if (test_support(xn, point)) {
438 case 1:
return 1.0 - std::abs(xn);
439 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
440 case 3:
return evalPWCubic<effective_rule>(point, xn);
442 return evalPWPower<effective_rule>(max_order, point, xn);
452 const double xn = scaleX<effective_rule>(point, x);
453 if (test_support(xn, point)) {
456 case 1:
return 1.0 - std::abs(xn);
457 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
458 case 3:
return evalPWCubic<effective_rule>(point, xn);
460 return evalPWPower<effective_rule>(max_order, point, xn);
470 template<erule effective_rule>
471 double evalRaw(
int max_order,
int point,
double x) {
472 switch(effective_rule) {
474 return (std::abs(x - getNode<effective_rule>(point)) <= getSupport<effective_rule>(point)) ? 1.0 : 0.0;
479 double xn = scaleX<effective_rule>(point, x);
480 if (std::abs(xn) <= 1.0) {
482 case 1:
return 1.0 - std::abs(xn);
483 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
484 case 3:
return evalPWCubic<effective_rule>(point, xn);
486 return evalPWPower<effective_rule>(max_order, point, xn);
492 case erule::semilocalp:
495 case 1:
return 0.5 * x * (x - 1.0);
496 case 2:
return 0.5 * x * (x + 1.0);
498 double xn = scaleX<effective_rule>(point, x);
499 if (std::abs(xn) <= 1.0) {
501 case 1:
return 1.0 - std::abs(xn);
502 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
503 case 3:
return evalPWCubic<effective_rule>(point, xn);
505 return evalPWPower<effective_rule>(max_order, point, xn);
514 double xn = scaleX<effective_rule>(point, x);
515 if (std::abs(xn) <= 1.0) {
517 case 1:
return 1.0 - std::abs(xn);
518 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
519 case 3:
return evalPWCubic<effective_rule>(point, xn);
521 return evalPWPower<effective_rule>(max_order, point, xn);
530 template<erule effective_rule>
531 double diffPWQuadratic(
int point,
double x) {
532 if (effective_rule == erule::localp) {
539 }
else if (effective_rule == erule::localpb) {
549 template<erule effective_rule>
550 double diffPWCubic(
int point,
double x) {
551 if (effective_rule == erule::localp) {
557 case 4:
return -2.0 * x;
559 return (point % 2 == 0) ? 1.0 / 3.0 - x * (x + 2.0) : -1.0 / 3.0 + x * (x - 2.0);
561 }
else if (effective_rule == erule::localpb) {
565 case 2:
return -2.0 * x;
567 return (point % 2 == 0) ? 1.0 / 3.0 - x * (x + 2.0) : -1.0 / 3.0 + x * (x - 2.0);
569 }
else if (effective_rule == erule::localp0) {
570 return (point == 0) ? -2.0 * x : ((point % 2 == 0) ? 1.0 / 3.0 - x * (x + 2.0) : -1.0 / 3.0 + x * (x - 2.0));
572 return (point % 2 == 0) ? 1.0 / 3.0 - x * (x + 2.0) : -1.0 / 3.0 + x * (x - 2.0);
575 template<erule effrule>
576 double diffPWPower(
int max_order,
int point,
double x) {
578 if (effrule == erule::localp and point <= 8)
return diffPWCubic<effrule>(point, x);
579 if (effrule == erule::semilocalp and point <= 4)
return diffPWCubic<effrule>(point, x);
580 if (effrule == erule::localpb and point <= 4)
return diffPWCubic<effrule>(point, x);
581 if (effrule == erule::localp0 and point <= 2)
return diffPWCubic<effrule>(point, x);
582 int level = getLevel<effrule>(point);
583 int max_ancestors = [&]()->
int {
585 case erule::pwc:
return 0;
586 case erule::localp:
return level - 2;
587 case erule::semilocalp:
588 case erule::localpb:
return level - 1;
589 default:
return level;
593 if (max_order > 0) max_ancestors = std::min(max_ancestors, max_order - 2);
598 double phantom_distance = 1.0;
599 auto update_and_get_next_node = [&]() {
601 phantom_distance = 2.0 * phantom_distance + 1.0;
602 int turns = (effrule == erule::localp0) ? ((point+1) % most_turns) : ((point-1) % most_turns);
603 return (turns < most_turns / 2) ?
604 (phantom_distance - 2.0 * ((double) turns)) :
605 (-phantom_distance + 2.0 * ((double) (most_turns - 1 - turns)));
609 auto rollback_and_get_prev_node = [&]() {
611 phantom_distance = 0.5 * (phantom_distance - 1.0);
612 int turns = (effrule == erule::localp0) ? ((point+1) % most_turns) : ((point-1) % most_turns);
613 return (turns < most_turns / 2) ?
614 (phantom_distance - 2.0 * ((double) turns)) :
615 (-phantom_distance + 2.0 * ((double) (most_turns - 1 - turns)));
619 std::vector<double> left_prods(max_ancestors);
621 double node = update_and_get_next_node();
622 double coeff = 1.0 / (-node);
623 for(
int j=1; j<max_ancestors; j++) {
624 left_prods[j] = left_prods[j-1] * (x - node);
625 node = update_and_get_next_node();
626 coeff *= 1.0 / (-node);
628 double right_prod = 1.0;
629 double derivative = left_prods[max_ancestors-1];
630 for (
int j=max_ancestors-2; j>=0; j--) {
631 right_prod *= x - node;
632 derivative += right_prod * left_prods[j];
633 node = rollback_and_get_prev_node();
637 derivative = derivative * (1.0 - x) * (1.0 + x) + right_prod * (x - node) * (-2.0) * x;
643 template<erule effrule>
644 double scaleXclamp(
int i,
double x) {
645 return std::clamp(scaleX<effrule>(i, x), -1.0, 1.0);
648 template<erule effrule>
649 double diffRaw(
int max_order,
int point,
double x) {
651 case erule::pwc:
return 0.0;
652 case erule::localp: {
654 return std::array<double, 3>{0, -1, 1}[point];
655 double xn = scaleXclamp<effrule>(point, x);
656 double an = scaleDiffX<effrule>(point);
658 case 1:
return (xn >= 0 ? -1.0 : 1.0) * an;
659 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
660 case 3:
return an * diffPWCubic<effrule>(point, xn);
662 return an * diffPWPower<effrule>(point, xn);
665 case erule::semilocalp:
668 case 1:
return x - 0.5;
669 case 2:
return x + 0.5;
671 double xn = scaleXclamp<effrule>(point, x);
672 double an = scaleDiffX<effrule>(point);
674 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
675 case 3:
return an * diffPWCubic<effrule>(point, xn);
677 return an * diffPWPower<effrule>(point, xn);
681 case erule::localp0: {
682 double xn = scaleXclamp<effrule>(point, x);
683 double an = scaleDiffX<effrule>(point);
685 case 1:
return (xn >= 0 ? -1.0 : 1.0) * an;
686 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
687 case 3:
return an * diffPWCubic<effrule>(point, xn);
689 return an * diffPWPower<effrule>(point, xn);
694 return std::array<double, 2>{-0.5, 0.5}[point];
695 double xn = scaleXclamp<effrule>(point, x);
696 double an = scaleDiffX<effrule>(point);
698 case 1:
return (xn >= 0 ? -1.0 : 1.0) * an;
699 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
700 case 3:
return an * diffPWCubic<effrule>(point, xn);
702 return an * diffPWPower<effrule>(point, xn);
708 template<erule effrule>
709 double diffSupport(
int max_order,
int point,
double x) {
713 case erule::localp: {
715 return std::array<double, 3>{0, -1, 1}[point];
716 double xn = scaleXclamp<effrule>(point, x);
717 double an = scaleDiffX<effrule>(point);
719 case 1:
return (xn >= 0 ? -1.0 : 1.0) * an;
720 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
721 case 3:
return an * diffPWCubic<effrule>(point, xn);
723 return an * diffPWPower<effrule>(max_order, point, xn);
726 case erule::semilocalp:
729 case 1:
return x - 0.5;
730 case 2:
return x + 0.5;
732 double xn = scaleXclamp<effrule>(point, x);
733 double an = scaleDiffX<effrule>(point);
735 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
736 case 3:
return an * diffPWCubic<effrule>(point, xn);
738 return an * diffPWPower<effrule>(max_order, point, xn);
742 case erule::localp0: {
743 double xn = scaleXclamp<effrule>(point, x);
744 double an = scaleDiffX<effrule>(point);
746 case 1:
return ((xn >= 0 ? -1.0 : 1.0) * an);
747 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
748 case 3:
return an * diffPWCubic<effrule>(point, xn);
750 return an * diffPWPower<effrule>(max_order, point, xn);
755 return std::array<double, 2>{-0.5, 0.5}[point];
756 double xn = scaleXclamp<effrule>(point, x);
757 double an = scaleDiffX<effrule>(point);
759 case 1:
return ((xn >= 0 ? -1.0 : 1.0) * an);
760 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
761 case 3:
return an * diffPWCubic<effrule>(point, xn);
763 return an * diffPWPower<effrule>(max_order, point, xn);
769 template<erule effrule>
770 double getArea(
int max_order,
int point, std::vector<double>
const &w, std::vector<double>
const &x) {
773 return 2.0 * getSupport<effrule>(point);
781 case 1:
return getSupport<effrule>(point);
783 case 3:
return (4.0/3.0) * getSupport<effrule>(point);
785 if (point <= 8)
return (4.0/3.0) * getSupport<effrule>(point);
791 case erule::semilocalp:
795 case 2:
return 1.0/3.0;
799 case 3:
return (4.0/3.0) * getSupport<effrule>(point);
801 if (point <= 4)
return (4.0/3.0) * getSupport<effrule>(point);
809 case 1:
return getSupport<effrule>(point);
811 case 3:
return (4.0/3.0) * getSupport<effrule>(point);
813 if (point <= 2)
return (4.0/3.0) * getSupport<effrule>(point);
822 case 1:
return getSupport<effrule>(point);
824 case 3:
return (4.0/3.0) * getSupport<effrule>(point);
826 if (point <= 4)
return (4.0/3.0) * getSupport<effrule>(point);
833 for(
size_t i=0; i<w.size(); i++) sum += w[i] * evalPWPower<effrule>(max_order, point, x[i]);
834 return sum * getSupport<effrule>(point);
837 template<erule effrule>
838 void van_matrix(
int max_order,
int num_rows, std::vector<int> &pntr, std::vector<int> &indx, std::vector<double> &vals) {
839 int max_level = getLevel<effrule>(num_rows);
841 if (effrule == erule::pwc) {
850 vals = {1.0, 1.0, 1.0};
854 indx = {0, 0, 1, 0, 2};
855 vals = {1.0, 1.0, 1.0, 1.0, 1.0};
860 indx.reserve(num_rows * max_level);
862 vals.reserve(num_rows * max_level);
863 pntr = std::vector<int>(num_rows + 1, 0);
864 for(
auto i : std::array<int, 5>{0, 0, 1, 0, 2})
866 for(
size_t i=0; i<5; i++)
871 std::vector<int> ancestors;
872 ancestors.reserve(max_level);
873 for(
int r=3; r<num_rows; r++) {
874 pntr[r] =
static_cast<int>(indx.size());
881 ancestors.push_back(dad);
883 if (kid != 3 * dad + 2)
884 ancestors.push_back(dad);
890 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
892 for(
size_t i=0; i<ancestors.size() + 2; i++)
895 pntr.back() =
static_cast<int>(indx.size());
899 }
else if (effrule == erule::localp) {
908 indx.reserve(num_rows * max_level);
910 vals.reserve(num_rows * max_level);
911 pntr = std::vector<int>(num_rows + 1, 0);
915 std::vector<int> ancestors;
916 std::vector<double> ancestors_vals;
917 ancestors.reserve(max_level);
918 ancestors_vals.reserve(max_level);
919 for(
int r=1; r<num_rows; r++) {
920 double x = getNode<effrule>(r);
921 pntr[r] =
static_cast<int>(indx.size());
923 ancestors_vals.clear();
925 int dad = (kid + 1) / 2;
928 ancestors.push_back(dad);
929 ancestors_vals.push_back( evalRaw<effrule>(max_order, dad, x) );
935 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
938 vals.insert(vals.end(), ancestors_vals.rbegin(), ancestors_vals.rend());
941 pntr.back() =
static_cast<int>(indx.size());
945 }
else if (effrule == erule::semilocalp) {
954 vals = {1.0, 1.0, 1.0};
958 indx = {0, 0, 1, 0, 2};
959 vals = {1.0, 1.0, 1.0, 1.0, 1.0};
964 indx.reserve(num_rows * max_level);
966 vals.reserve(num_rows * max_level);
967 pntr = std::vector<int>(num_rows + 1, 0);
968 for(
auto i : std::array<int, 5>{0, 0, 1, 0, 2})
970 for(
int i=0; i<5; i++)
975 std::vector<int> ancestors;
976 std::vector<double> ancestors_vals;
977 ancestors.reserve(max_level);
978 ancestors_vals.reserve(max_level);
979 for(
int r=3; r<num_rows; r++) {
980 pntr[r] =
static_cast<int>(indx.size());
981 double x = getNode<effrule>(r);
983 ancestors_vals.clear();
985 int dad = (kid + 1) / 2;
987 ancestors.push_back(dad);
988 ancestors_vals.push_back( evalRaw<effrule>(max_order, dad, x) );
995 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
998 vals.push_back( evalRaw<effrule>(max_order, 1, x) );
999 vals.push_back( evalRaw<effrule>(max_order, 2, x) );
1000 vals.insert(vals.end(), ancestors_vals.rbegin(), ancestors_vals.rend());
1001 vals.push_back(1.0);
1003 pntr.back() =
static_cast<int>(indx.size());
1007 }
else if (effrule == erule::localp0) {
1016 indx.reserve(num_rows * max_level);
1018 vals.reserve(num_rows * max_level);
1019 pntr = std::vector<int>(num_rows + 1, 0);
1021 vals.push_back(1.0);
1023 std::vector<int> ancestors;
1024 std::vector<double> ancestors_vals;
1025 ancestors.reserve(max_level);
1026 ancestors_vals.reserve(max_level);
1027 for(
int r=1; r<num_rows; r++) {
1028 double x = getNode<effrule>(r);
1029 pntr[r] =
static_cast<int>(indx.size());
1031 ancestors_vals.clear();
1033 int dad = (kid - 1) / 2;
1035 ancestors.push_back(dad);
1036 ancestors_vals.push_back( evalRaw<effrule>(max_order, dad, x) );
1038 dad = (kid - 1) / 2;
1041 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
1043 vals.push_back( evalRaw<effrule>(max_order, 0, x) );
1044 vals.insert(vals.end(), ancestors_vals.rbegin(), ancestors_vals.rend());
1045 vals.push_back(1.0);
1047 pntr.back() =
static_cast<int>(indx.size());
1065 indx.reserve(num_rows * max_level);
1067 vals.reserve(num_rows * max_level);
1068 pntr = std::vector<int>(num_rows + 1, 0);
1071 vals.push_back(1.0);
1072 vals.push_back(1.0);
1075 std::vector<int> ancestors;
1076 std::vector<double> ancestors_vals;
1077 ancestors.reserve(max_level);
1078 ancestors_vals.reserve(max_level);
1079 for(
int r=2; r<num_rows; r++) {
1080 pntr[r] =
static_cast<int>(indx.size());
1081 double x = getNode<effrule>(r);
1083 ancestors_vals.clear();
1085 int dad = (kid + 1) / 2;
1087 ancestors.push_back(dad);
1088 ancestors_vals.push_back( evalRaw<effrule>(max_order, dad, x) );
1090 dad = (kid + 1) / 2;
1094 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
1096 vals.push_back( evalRaw<effrule>(max_order, 0, x) );
1097 vals.push_back( evalRaw<effrule>(max_order, 1, x) );
1098 vals.insert(vals.end(), ancestors_vals.rbegin(), ancestors_vals.rend());
1099 vals.push_back(1.0);
1101 pntr.back() =
static_cast<int>(indx.size());
TypeOneDRule
Used to specify the one dimensional family of rules that induces the sparse grid.
Definition tsgEnumerates.hpp:288
@ rule_localp
Nested rule with a hierarchy of uniformly distributed nodes and functions with compact support.
Definition tsgEnumerates.hpp:365
@ rule_localpb
Variation of rule_localp focusing nodes on the boundary instead of the interior.
Definition tsgEnumerates.hpp:371
@ rule_localp0
Variation of rule_localp assuming the model is zero at the domain boundary.
Definition tsgEnumerates.hpp:367
@ rule_semilocalp
Variation of rule_localp using increased support in exchange for higher order basis (better for smoot...
Definition tsgEnumerates.hpp:369
Encapsulates the Tasmanian Sparse Grid module.
Definition TasmanianSparseGrid.hpp:68