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;
375 template<erule effective_rule>
376 double evalSupport(
int max_order,
int point,
double x,
bool &isSupported) {
377 switch(effective_rule) {
379 double distance = std::abs(x - getNode<effective_rule>(point));
380 double support = getSupport<effective_rule>(point);
381 isSupported = (distance <= 2.0 * support);
382 return (distance <= support) ? 1.0 : 0.0;
389 double xn = scaleX<effective_rule>(point, x);
390 if (std::abs(xn) <= 1.0) {
392 case 1:
return 1.0 - std::abs(xn);
393 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
394 case 3:
return evalPWCubic<effective_rule>(point, xn);
396 return evalPWPower<effective_rule>(max_order, point, xn);
403 case erule::semilocalp:
407 case 1:
return 0.5 * x * (x - 1.0);
408 case 2:
return 0.5 * x * (x + 1.0);
410 double xn = scaleX<effective_rule>(point, x);
411 if (std::abs(xn) <= 1.0) {
413 case 1:
return 1.0 - std::abs(xn);
414 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
415 case 3:
return evalPWCubic<effective_rule>(point, xn);
417 return evalPWPower<effective_rule>(max_order, point, xn);
427 double xn = scaleX<effective_rule>(point, x);
428 if (std::abs(xn) <= 1.0) {
431 case 1:
return 1.0 - std::abs(xn);
432 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
433 case 3:
return evalPWCubic<effective_rule>(point, xn);
435 return evalPWPower<effective_rule>(max_order, point, xn);
445 template<erule effective_rule>
446 double evalRaw(
int max_order,
int point,
double x) {
447 switch(effective_rule) {
449 return (std::abs(x - getNode<effective_rule>(point)) <= getSupport<effective_rule>(point)) ? 1.0 : 0.0;
454 double xn = scaleX<effective_rule>(point, x);
455 if (std::abs(xn) <= 1.0) {
457 case 1:
return 1.0 - std::abs(xn);
458 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
459 case 3:
return evalPWCubic<effective_rule>(point, xn);
461 return evalPWPower<effective_rule>(max_order, point, xn);
467 case erule::semilocalp:
470 case 1:
return 0.5 * x * (x - 1.0);
471 case 2:
return 0.5 * x * (x + 1.0);
473 double xn = scaleX<effective_rule>(point, x);
474 if (std::abs(xn) <= 1.0) {
476 case 1:
return 1.0 - std::abs(xn);
477 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
478 case 3:
return evalPWCubic<effective_rule>(point, xn);
480 return evalPWPower<effective_rule>(max_order, point, xn);
489 double xn = scaleX<effective_rule>(point, x);
490 if (std::abs(xn) <= 1.0) {
492 case 1:
return 1.0 - std::abs(xn);
493 case 2:
return evalPWQuadratic<effective_rule>(point, xn);
494 case 3:
return evalPWCubic<effective_rule>(point, xn);
496 return evalPWPower<effective_rule>(max_order, point, xn);
505 template<erule effective_rule>
506 double diffPWQuadratic(
int point,
double x) {
507 if (effective_rule == erule::localp) {
514 }
else if (effective_rule == erule::localpb) {
524 template<erule effective_rule>
525 double diffPWCubic(
int point,
double x) {
526 if (effective_rule == erule::localp) {
532 case 4:
return -2.0 * x;
534 return (point % 2 == 0) ? 1.0 / 3.0 - x * (x + 2.0) : -1.0 / 3.0 + x * (x - 2.0);
536 }
else if (effective_rule == erule::localpb) {
540 case 2:
return -2.0 * x;
542 return (point % 2 == 0) ? 1.0 / 3.0 - x * (x + 2.0) : -1.0 / 3.0 + x * (x - 2.0);
544 }
else if (effective_rule == erule::localp0) {
545 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));
547 return (point % 2 == 0) ? 1.0 / 3.0 - x * (x + 2.0) : -1.0 / 3.0 + x * (x - 2.0);
550 template<erule effrule>
551 double diffPWPower(
int max_order,
int point,
double x) {
553 if (effrule == erule::localp and point <= 8)
return diffPWCubic<effrule>(point, x);
554 if (effrule == erule::semilocalp and point <= 4)
return diffPWCubic<effrule>(point, x);
555 if (effrule == erule::localpb and point <= 4)
return diffPWCubic<effrule>(point, x);
556 if (effrule == erule::localp0 and point <= 2)
return diffPWCubic<effrule>(point, x);
557 int level = getLevel<effrule>(point);
558 int max_ancestors = [&]()->
int {
560 case erule::pwc:
return 0;
561 case erule::localp:
return level - 2;
562 case erule::semilocalp:
563 case erule::localpb:
return level - 1;
564 default:
return level;
568 if (max_order > 0) max_ancestors = std::min(max_ancestors, max_order - 2);
573 double phantom_distance = 1.0;
574 auto update_and_get_next_node = [&]() {
576 phantom_distance = 2.0 * phantom_distance + 1.0;
577 int turns = (effrule == erule::localp0) ? ((point+1) % most_turns) : ((point-1) % most_turns);
578 return (turns < most_turns / 2) ?
579 (phantom_distance - 2.0 * ((double) turns)) :
580 (-phantom_distance + 2.0 * ((double) (most_turns - 1 - turns)));
584 auto rollback_and_get_prev_node = [&]() {
586 phantom_distance = 0.5 * (phantom_distance - 1.0);
587 int turns = (effrule == erule::localp0) ? ((point+1) % most_turns) : ((point-1) % most_turns);
588 return (turns < most_turns / 2) ?
589 (phantom_distance - 2.0 * ((double) turns)) :
590 (-phantom_distance + 2.0 * ((double) (most_turns - 1 - turns)));
594 std::vector<double> left_prods(max_ancestors);
596 double node = update_and_get_next_node();
597 double coeff = 1.0 / (-node);
598 for(
int j=1; j<max_ancestors; j++) {
599 left_prods[j] = left_prods[j-1] * (x - node);
600 node = update_and_get_next_node();
601 coeff *= 1.0 / (-node);
603 double right_prod = 1.0;
604 double derivative = left_prods[max_ancestors-1];
605 for (
int j=max_ancestors-2; j>=0; j--) {
606 right_prod *= x - node;
607 derivative += right_prod * left_prods[j];
608 node = rollback_and_get_prev_node();
612 derivative = derivative * (1.0 - x) * (1.0 + x) + right_prod * (x - node) * (-2.0) * x;
618 template<erule effrule>
619 double diffRaw(
int max_order,
int point,
double x) {
621 case erule::pwc:
return 0.0;
622 case erule::localp: {
623 if (point == 0)
return 0.0;
624 double xn = scaleX<effrule>(point, x);
625 double an = scaleDiffX<effrule>(point);
627 case 1:
return ((xn >= 0 ? -1.0 : 1.0) * an);
628 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
629 case 3:
return an * diffPWCubic<effrule>(point, xn);
631 return an * diffPWPower<effrule>(point, xn);
634 case erule::semilocalp:
637 case 1:
return x - 0.5;
638 case 2:
return x + 0.5;
640 double xn = scaleX<effrule>(point, x);
641 double an = scaleDiffX<effrule>(point);
643 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
644 case 3:
return an * diffPWCubic<effrule>(point, xn);
646 return an * diffPWPower<effrule>(point, xn);
650 case erule::localp0: {
651 double xn = scaleX<effrule>(point, x);
652 double an = scaleDiffX<effrule>(point);
654 case 1:
return (x == 1.0 and point == 0) ? -1.0 : ((xn >= 0 ? -1.0 : 1.0) * an);
655 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
656 case 3:
return an * diffPWCubic<effrule>(point, xn);
658 return an * diffPWPower<effrule>(point, xn);
662 double xn = scaleX<effrule>(point, x);
663 double an = scaleDiffX<effrule>(point);
665 case 1:
return ((xn >= 0 ? -1.0 : 1.0) * an);
666 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
667 case 3:
return an * diffPWCubic<effrule>(point, xn);
669 return an * diffPWPower<effrule>(point, xn);
675 template<erule effrule>
676 double diffSupport(
int max_order,
int point,
double x,
bool &isSupported) {
681 case erule::localp: {
682 if (point == 0) { isSupported =
true;
return 0.0; }
683 double xn = scaleX<effrule>(point, x);
684 isSupported = (-1.0 <= xn and xn < 1.0) or (x == 1.0 and xn == 1.0);
686 double an = scaleDiffX<effrule>(point);
688 case 1:
return (x == 1.0 and point == 2) ? an : (((xn >= 0 ? -1.0 : 1.0) * an));
689 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
690 case 3:
return an * diffPWCubic<effrule>(point, xn);
692 return an * diffPWPower<effrule>(max_order, point, xn);
698 case erule::semilocalp:
700 case 0: { isSupported =
true;
return 0.0; }
701 case 1: { isSupported =
true;
return x - 0.5; }
702 case 2: { isSupported =
true;
return x + 0.5; }
704 double xn = scaleX<effrule>(point, x);
705 isSupported = (-1.0 <= xn and xn < 1.0) or (x == 1.0 and xn == 1.0);
707 double an = scaleDiffX<effrule>(point);
709 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
710 case 3:
return an * diffPWCubic<effrule>(point, xn);
712 return an * diffPWPower<effrule>(max_order, point, xn);
719 case erule::localp0: {
720 double xn = scaleX<effrule>(point, x);
721 isSupported = (-1.0 <= xn and xn < 1.0) or (x == 1.0 and xn == 1.0);
723 double an = scaleDiffX<effrule>(point);
725 case 1:
return (x == 1.0 and point == 0) ? -1.0 : ((xn >= 0 ? -1.0 : 1.0) * an);
726 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
727 case 3:
return an * diffPWCubic<effrule>(point, xn);
729 return an * diffPWPower<effrule>(max_order, point, xn);
736 double xn = scaleX<effrule>(point, x);
737 isSupported = (-1.0 <= xn and xn < 1.0) or (x == 1.0 and xn == 1.0);
739 double an = scaleDiffX<effrule>(point);
741 case 1:
return ((xn >= 0 ? -1.0 : 1.0) * an);
742 case 2:
return an * diffPWQuadratic<effrule>(point, xn);
743 case 3:
return an * diffPWCubic<effrule>(point, xn);
745 return an * diffPWPower<effrule>(max_order, point, xn);
754 template<erule effrule>
755 double getArea(
int max_order,
int point, std::vector<double>
const &w, std::vector<double>
const &x) {
758 return 2.0 * getSupport<effrule>(point);
766 case 1:
return getSupport<effrule>(point);
768 case 3:
return (4.0/3.0) * getSupport<effrule>(point);
770 if (point <= 8)
return (4.0/3.0) * getSupport<effrule>(point);
776 case erule::semilocalp:
780 case 2:
return 1.0/3.0;
784 case 3:
return (4.0/3.0) * getSupport<effrule>(point);
786 if (point <= 4)
return (4.0/3.0) * getSupport<effrule>(point);
794 case 1:
return getSupport<effrule>(point);
796 case 3:
return (4.0/3.0) * getSupport<effrule>(point);
798 if (point <= 2)
return (4.0/3.0) * getSupport<effrule>(point);
807 case 1:
return getSupport<effrule>(point);
809 case 3:
return (4.0/3.0) * getSupport<effrule>(point);
811 if (point <= 4)
return (4.0/3.0) * getSupport<effrule>(point);
818 for(
size_t i=0; i<w.size(); i++) sum += w[i] * evalPWPower<effrule>(max_order, point, x[i]);
819 return sum * getSupport<effrule>(point);
822 template<erule effrule>
823 void van_matrix(
int max_order,
int num_rows, std::vector<int> &pntr, std::vector<int> &indx, std::vector<double> &vals) {
824 int max_level = getLevel<effrule>(num_rows);
826 if (effrule == erule::pwc) {
835 vals = {1.0, 1.0, 1.0};
839 indx = {0, 0, 1, 0, 2};
840 vals = {1.0, 1.0, 1.0, 1.0, 1.0};
845 indx.reserve(num_rows * max_level);
847 vals.reserve(num_rows * max_level);
848 pntr = std::vector<int>(num_rows + 1, 0);
849 for(
auto i : std::array<int, 5>{0, 0, 1, 0, 2})
851 for(
size_t i=0; i<5; i++)
856 std::vector<int> ancestors;
857 ancestors.reserve(max_level);
858 for(
int r=3; r<num_rows; r++) {
859 pntr[r] =
static_cast<int>(indx.size());
866 ancestors.push_back(dad);
868 if (kid != 3 * dad + 2)
869 ancestors.push_back(dad);
875 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
877 for(
size_t i=0; i<ancestors.size() + 2; i++)
880 pntr.back() =
static_cast<int>(indx.size());
884 }
else if (effrule == erule::localp) {
893 indx.reserve(num_rows * max_level);
895 vals.reserve(num_rows * max_level);
896 pntr = std::vector<int>(num_rows + 1, 0);
900 std::vector<int> ancestors;
901 std::vector<double> ancestors_vals;
902 ancestors.reserve(max_level);
903 ancestors_vals.reserve(max_level);
904 for(
int r=1; r<num_rows; r++) {
905 double x = getNode<effrule>(r);
906 pntr[r] =
static_cast<int>(indx.size());
908 ancestors_vals.clear();
910 int dad = (kid + 1) / 2;
913 ancestors.push_back(dad);
914 ancestors_vals.push_back( evalRaw<effrule>(max_order, dad, x) );
920 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
923 vals.insert(vals.end(), ancestors_vals.rbegin(), ancestors_vals.rend());
926 pntr.back() =
static_cast<int>(indx.size());
930 }
else if (effrule == erule::semilocalp) {
939 vals = {1.0, 1.0, 1.0};
943 indx = {0, 0, 1, 0, 2};
944 vals = {1.0, 1.0, 1.0, 1.0, 1.0};
949 indx.reserve(num_rows * max_level);
951 vals.reserve(num_rows * max_level);
952 pntr = std::vector<int>(num_rows + 1, 0);
953 for(
auto i : std::array<int, 5>{0, 0, 1, 0, 2})
955 for(
int i=0; i<5; i++)
960 std::vector<int> ancestors;
961 std::vector<double> ancestors_vals;
962 ancestors.reserve(max_level);
963 ancestors_vals.reserve(max_level);
964 for(
int r=3; r<num_rows; r++) {
965 pntr[r] =
static_cast<int>(indx.size());
966 double x = getNode<effrule>(r);
968 ancestors_vals.clear();
970 int dad = (kid + 1) / 2;
972 ancestors.push_back(dad);
973 ancestors_vals.push_back( evalRaw<effrule>(max_order, dad, x) );
980 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
983 vals.push_back( evalRaw<effrule>(max_order, 1, x) );
984 vals.push_back( evalRaw<effrule>(max_order, 2, x) );
985 vals.insert(vals.end(), ancestors_vals.rbegin(), ancestors_vals.rend());
988 pntr.back() =
static_cast<int>(indx.size());
992 }
else if (effrule == erule::localp0) {
1001 indx.reserve(num_rows * max_level);
1003 vals.reserve(num_rows * max_level);
1004 pntr = std::vector<int>(num_rows + 1, 0);
1006 vals.push_back(1.0);
1008 std::vector<int> ancestors;
1009 std::vector<double> ancestors_vals;
1010 ancestors.reserve(max_level);
1011 ancestors_vals.reserve(max_level);
1012 for(
int r=1; r<num_rows; r++) {
1013 double x = getNode<effrule>(r);
1014 pntr[r] =
static_cast<int>(indx.size());
1016 ancestors_vals.clear();
1018 int dad = (kid - 1) / 2;
1020 ancestors.push_back(dad);
1021 ancestors_vals.push_back( evalRaw<effrule>(max_order, dad, x) );
1023 dad = (kid - 1) / 2;
1026 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
1028 vals.push_back( evalRaw<effrule>(max_order, 0, x) );
1029 vals.insert(vals.end(), ancestors_vals.rbegin(), ancestors_vals.rend());
1030 vals.push_back(1.0);
1032 pntr.back() =
static_cast<int>(indx.size());
1050 indx.reserve(num_rows * max_level);
1052 vals.reserve(num_rows * max_level);
1053 pntr = std::vector<int>(num_rows + 1, 0);
1056 vals.push_back(1.0);
1057 vals.push_back(1.0);
1060 std::vector<int> ancestors;
1061 std::vector<double> ancestors_vals;
1062 ancestors.reserve(max_level);
1063 ancestors_vals.reserve(max_level);
1064 for(
int r=2; r<num_rows; r++) {
1065 pntr[r] =
static_cast<int>(indx.size());
1066 double x = getNode<effrule>(r);
1068 ancestors_vals.clear();
1070 int dad = (kid + 1) / 2;
1072 ancestors.push_back(dad);
1073 ancestors_vals.push_back( evalRaw<effrule>(max_order, dad, x) );
1075 dad = (kid + 1) / 2;
1079 indx.insert(indx.end(), ancestors.rbegin(), ancestors.rend());
1081 vals.push_back( evalRaw<effrule>(max_order, 0, x) );
1082 vals.push_back( evalRaw<effrule>(max_order, 1, x) );
1083 vals.insert(vals.end(), ancestors_vals.rbegin(), ancestors_vals.rend());
1084 vals.push_back(1.0);
1086 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:285
@ rule_localp
Nested rule with a hierarchy of uniformly distributed nodes and functions with compact support.
Definition tsgEnumerates.hpp:362
@ rule_localpb
Variation of rule_localp focusing nodes on the boundary instead of the interior.
Definition tsgEnumerates.hpp:368
@ rule_localp0
Variation of rule_localp assuming the model is zero at the domain boundary.
Definition tsgEnumerates.hpp:364
@ rule_semilocalp
Variation of rule_localp using increased support in exchange for higher order basis (better for smoot...
Definition tsgEnumerates.hpp:366
Encapsulates the Tasmanian Sparse Grid module.
Definition TasmanianSparseGrid.hpp:68