36#ifndef MJR_INCLUDE_MR_rect_tree
59#include <unordered_map>
65#include "MRMathCPP.hpp"
128 template <
int max_level,
class spc_real_t,
int dom_dim,
int rng_dim>
129 requires ((max_level>0) &&
132 (dom_dim*max_level<=CHAR_BIT*
sizeof(uint64_t)) &&
133 (std::is_floating_point<spc_real_t>::value))
141 constexpr static int domain_dimension = dom_dim;
143 constexpr static int range_dimension = rng_dim;
145 constexpr static int maximum_level = max_level;
167 typedef std::array<src_t, dom_dim>
drta_t;
186 typedef std::array<src_t, rng_dim>
rrta_t;
203 constexpr static int dic_bits = max_level+1;
207 constexpr static int diti_bits = dic_bits * dom_dim;
217 typedef typename std::conditional<std::cmp_greater_equal(CHAR_BIT*
sizeof(int8_t), dic_bits), uint8_t,
218 typename std::conditional<std::cmp_greater_equal(CHAR_BIT*
sizeof(int16_t), dic_bits), uint16_t,
219 typename std::conditional<std::cmp_greater_equal(CHAR_BIT*
sizeof(int32_t), dic_bits), uint32_t,
224 typedef typename std::conditional<std::cmp_greater_equal(CHAR_BIT*
sizeof(int8_t), diti_bits), uint8_t,
225 typename std::conditional<std::cmp_greater_equal(CHAR_BIT*
sizeof(int16_t), diti_bits), uint16_t,
226 typename std::conditional<std::cmp_greater_equal(CHAR_BIT*
sizeof(int32_t), diti_bits), uint32_t,
252 constexpr static dic_t dic_max = (
static_cast<dic_t>(1) << max_level);
254 constexpr static dic_t dic_ctr = (
static_cast<dic_t>(1) << (max_level-1));
282 constexpr static diti_t diti_ones = ~static_cast<diti_t>(0);
284 constexpr static diti_t diti_msk0 =
static_cast<diti_t>(~(diti_ones << dic_bits));
320 if constexpr (dom_dim == 1) {
321 bbox_delta = (bbox_max - bbox_min) / ((
dic_t(1) << max_level));
322 if (bbox_max <= bbox_min) {
323 std::cerr <<
"ERROR(update_bbox_delta): bbox_min must be less than bbox_max!" << std::endl;
327 for(
int i=0; i<dom_dim; i++) {
328 bbox_delta[i] = (bbox_max[i] - bbox_min[i]) / ((
dic_t(1) << max_level));
329 if (bbox_max[i] <= bbox_min[i]) {
330 std::cerr <<
"ERROR(update_bbox_delta): Corrisponding elements of bbox_min must be less than bbox_max!" << std::endl;
341 bbox_min = new_bbox_min;
342 bbox_max = new_bbox_max;
348 if constexpr (dom_dim == 1) {
349 bbox_min =
static_cast<src_t>(-1.0);
350 bbox_max =
static_cast<src_t>( 1.0);
352 bbox_min.fill(
static_cast<src_t>(-1.0));
353 bbox_max.fill(
static_cast<src_t>( 1.0));
388 if constexpr (rng_dim == 1)
389 ret[0] = get_sample(vertex);
391 ret = get_sample(vertex);
397 inline std::unordered_map<diti_t, rrpt_t>::const_iterator
cbegin_samples() {
return samples.cbegin(); }
401 inline std::unordered_map<diti_t, rrpt_t>::const_iterator
cend_samples() {
return samples.cend(); }
487 dic_t tmp = cuc_get_crd(cell, index);
488 dic_t delta = ccc_cell_full_width(cell);
489 if (direction == 1) {
490 if ((dic_max-tmp) >= delta)
491 return cuc_inc_crd(cell, index, delta);
494 return cuc_dec_crd(cell, index, delta);
505 if (ccc_cell_level(cell) < (max_level-1)) {
506 return cuc_two_cross(cell, ccc_cell_quarter_width(cell));
520 if (ccc_cell_level(cell) < (max_level-1)) {
521 return cuc_two_cross(cell, ccc_cell_quarter_width(cell), index, direction);
569 if constexpr (dom_dim == 1) {
570 return (diti - value);
574 for(
int i=0; i<dom_dim; i++) {
576 tmp =
static_cast<diti_t>(tmp << dic_bits);
587 if constexpr (dom_dim == 1) {
588 return (diti + value);
592 for(
int i=0; i<dom_dim; i++) {
594 tmp =
static_cast<diti_t>(tmp << dic_bits);
604 if constexpr (dom_dim == 1) {
609 for(
int i=0; i<dom_dim; i++)
610 rv |= (tmp << (i * dic_bits));
626 for(
int i=0; i<(1 << dom_dim); i++) {
628 for(
int j=0; j<dom_dim; j++) {
630 tmp = cuc_inc_crd(tmp, j, delta);
632 tmp = cuc_dec_crd(tmp, j, delta);
658 for(
int i=0; i<(1 << dom_dim); i++) {
659 if (((i >> index) & 1) == direction) {
661 for(
int j=0; j<dom_dim; j++) {
663 tmp = cuc_inc_crd(tmp, j, delta);
665 tmp = cuc_dec_crd(tmp, j, delta);
687 for(
int idx=0; idx<dom_dim; idx++) {
688 for(
int up=0; up<2; up++) {
689 dic_t tmp = cuc_get_crd(diti, idx);
691 if ((dic_max-tmp) >= delta)
692 rv.push_back(cuc_inc_crd(diti, idx, delta));
695 rv.push_back(cuc_dec_crd(diti, idx, delta));
709 if constexpr (rng_dim == 1) {
718 if constexpr (dom_dim == 1) {
734 if constexpr (dom_dim == 1) {
738 for(
int i=0; i<dom_dim; i++)
739 rv |= (dita[i] << (i * dic_bits));
749 if constexpr (dom_dim == 1) {
753 for(
int i=0; i<dom_dim; i++)
754 rv[i] = (diti >> ((dom_dim-1-i) * dic_bits)) & diti_msk0;
769 if constexpr (dom_dim == 1) {
770 return (bbox_min + bbox_delta * diti);
773 rv.fill(
static_cast<src_t>(0.0));
774 for(
int i=0; i<dom_dim; i++) {
775 rv[i] = (bbox_min[i] + bbox_delta[i] * cuc_get_crd(diti, i));
787 rv.fill(
static_cast<src_t>(0.0));
788 if constexpr (dom_dim == 1) {
789 rv[0] = (bbox_min + bbox_delta * diti);
791 for(
int i=0; i<dom_dim; i++) {
792 rv[i] = (bbox_min[i] + bbox_delta[i] * cuc_get_crd(diti, i));
808 if (sample_point_maybe(cell, func)) {
809 for(
auto const e: ccc_get_corners(cell)) {
810 sample_point_maybe(e, func);
817 sample_cell(ccc_get_top_cell(), func);
825 if ( !(vertex_exists(diti))) {
826 drpt_t xvec = diti_to_drpt(diti);
839 drpt_t xvec = diti_to_drpt(diti);
852 if constexpr (rng_dim == 1) {
853 return std::isnan(val);
855 return (std::any_of(val.cbegin(), val.cend(), [](
src_t v) { return (std::isnan(v)); }));
863 if constexpr (rng_dim == 1) {
864 return std::abs(val1-val2);
867 for(
int i=0; i<rng_dim; ++i)
868 ret = std::max(ret, std::abs(val1[i]-val2[i]));
882 if constexpr (dom_dim == 1) {
883 return std::abs(val1-val2);
886 for(
int i=0; i<dom_dim; ++i)
887 ret = std::max(ret, std::abs(val1[i]-val2[i]));
896 if constexpr (dom_dim == 1) {
897 return (val1+val2)/
static_cast<src_t>(2.0);
900 for(
int i=0; i<dom_dim; ++i)
901 ret[i] = (val1[i] + val2[i])/
static_cast<src_t>(2.0);
926 auto children = ccc_get_children(cell);
927 if (children.empty()) {
930 for(
auto const c : children)
931 sample_cell(c, func);
947 diti_t tmp = ccc_cell_get_corner_min(cell);
948 if constexpr (dom_dim == 1) {
949 dic_t del = ccc_cell_half_width(cell) >> level_delta;
950 for(
int i=0; i<(1 << (1+level_delta))+1; i++) {
951 sample_point(tmp, func);
954 }
else if constexpr (dom_dim == 2) {
955 dic_t del =
static_cast<dic_t>(ccc_cell_full_width(cell) >> level_delta);
957 for(
dic_t i=0; i<(1 << level_delta)+1; i++) {
958 diti_t tmp2 = cuc_inc_crd(tmp, 0, i*del);
959 for(
dic_t j=0; j<(1 << level_delta)+1; j++) {
960 diti_t tmp3 = cuc_inc_crd(tmp2, 1, j*del);
961 sample_point(tmp3, func);
965 tmp = cuc_inc_all_crd(tmp, del/2);
966 for(
dic_t i=0; i<(1 << level_delta); i++) {
967 diti_t tmp2 = cuc_inc_crd(tmp, 0, i*del);
968 for(
dic_t j=0; j<(1 << level_delta); j++) {
969 diti_t tmp3 = cuc_inc_crd(tmp2, 1, j*del);
970 sample_point(tmp3, func);
973 }
else if constexpr (dom_dim == 3) {
974 dic_t del =
static_cast<dic_t>(ccc_cell_full_width(cell) >> level_delta);
976 for(
dic_t i=0; i<(1 << level_delta)+1; i++) {
977 diti_t tmp2 = cuc_inc_crd(tmp, 0, i*del);
978 for(
dic_t j=0; j<(1 << level_delta)+1; j++) {
979 diti_t tmp3 = cuc_inc_crd(tmp2, 1, j*del);
980 for(
dic_t k=0; k<(1 << level_delta)+1; k++) {
981 diti_t tmp4 = cuc_inc_crd(tmp3, 2, k*del);
982 sample_point(tmp4, func);
987 tmp = cuc_inc_all_crd(tmp, del/2);
988 for(
dic_t i=0; i<(1 << level_delta); i++) {
989 diti_t tmp2 = cuc_inc_crd(tmp, 0, i*del);
990 for(
dic_t j=0; j<(1 << level_delta); j++) {
991 diti_t tmp3 = cuc_inc_crd(tmp2, 1, j*del);
992 for(
dic_t k=0; k<(1 << level_delta); k++) {
993 diti_t tmp4 = cuc_inc_crd(tmp3, 2, k*del);
994 sample_point(tmp4, func);
999 std::cout <<
"ERROR: refine_grid with dom_dim>3 not supported (use refine_recursive)!" << std::endl;
1005 refine_grid(ccc_get_top_cell(), level_delta, func);
1017 sample_cell(cell, func);
1018 if ((level < 0) || (ccc_cell_level(cell) < level)) {
1019 for(
auto const c : ccc_get_children(cell)) {
1020 sample_cell(c, func);
1021 refine_recursive(c, level, func);
1028 refine_recursive(ccc_get_top_cell(), level, func);
1044 if ((level < 0) || (ccc_cell_level(cell) < level)) {
1046 refine_once(cell, func);
1047 for(
auto const c : ccc_get_children(cell)) {
1048 refine_recursive_cell_pred(c, level, func, pred);
1061 for(
auto c: get_leaf_cells(cell))
1062 refine_recursive_cell_pred(c, level, func, pred);
1067 refine_leaves_recursive_cell_pred(ccc_get_top_cell(), level, func, pred);
1081 diti_list_t cells_to_check = get_leaf_cells(cell);
1083 for(
auto c: cells_to_check)
1085 if ((level < 0) || (ccc_cell_level(c) < level))
1086 cells_to_refine.push_back(c);
1087 int refined_count = 0;
1088 for(
auto c: cells_to_refine)
1089 refined_count += refine_once(c, func);
1090 return refined_count;
1095 return refine_leaves_once_if_cell_pred(ccc_get_top_cell(), level, func, pred);
1107 int refined_count = 0;
1108 while (0 < (refined_count = refine_leaves_once_if_cell_pred(cell, level, func, pred)))
1110 return refined_count;
1115 return refine_leaves_atomically_if_cell_pred(ccc_get_top_cell(), level, func, pred);
1137 return refine_leaves_once_if_cell_pred(ccc_get_top_cell(), -1, func, std::bind_front(&cell_is_unbalanced,
this, level_delta));
1147 refine_leaves_atomically_if_cell_pred(ccc_get_top_cell(), -1, func, std::bind_front(&this_t::cell_is_unbalanced,
this, level_delta));
1160 if constexpr (dom_dim == 1) {
1161 return ((0 < cell) && (dic_max > cell));
1163 diti_t working_tuple = cell;
1164 for(
int i=0; i<dom_dim; i++) {
1165 dic_t cur_dic = diti_msk0 & working_tuple;
1166 if ((cur_dic <= 0) || (cur_dic >= dic_max)) {
1169 working_tuple = working_tuple >> dic_bits;
1179 return (vertex_exists(cell));
1187 return (std::all_of(verts.cbegin(), verts.cend(), [
this](
diti_t i) { return (vertex_exists(i)); }));
1194 return (std::any_of(verts.cbegin(), verts.cend(), [
this](
diti_t i) { return (vertex_is_nan(i)); }));
1201 return (std::any_of(corners.cbegin(), corners.cend(), [
this](
diti_t i) { return (vertex_is_nan(i)); }));
1208 return (cell_can_have_children(cell) && cell_exists(cuc_dec_all_crd(cell, ccc_cell_quarter_width(cell))));
1215 return ( !(cell_has_child(cell)));
1221 return (ccc_cell_level(cell) < (max_level - 1));
1229 diti_t tmp = ccc_get_neighbor(cell, index, direction);
1231 return cell_is_sampled(cell);
1252 int center_sign = mjr::math::sfun::sgn(sdf(diti_to_drpt(cell)));
1253 if (center_sign == 0)
1255 for(
diti_t& v: ccc_get_corners(cell))
1256 if (center_sign != mjr::math::sfun::sgn(sdf(diti_to_drpt(v))))
1267 drpt_t min_drpt = diti_to_drpt(ccc_cell_get_corner_min(cell));
1268 for(
int i=0; i<dom_dim; i++)
1269 if (dom_at(min_drpt, i)-epsilon > dom_at(domain_point, i))
1271 drpt_t max_drpt = diti_to_drpt(ccc_cell_get_corner_max(cell));
1272 for(
int i=0; i<dom_dim; i++)
1273 if (dom_at(max_drpt, i)+epsilon < dom_at(domain_point, i))
1285 return ( (dom_at(diti_to_drpt(ccc_cell_get_corner_min(cell)), domain_index) < domain_level+epsilon) &&
1286 (dom_at(diti_to_drpt(ccc_cell_get_corner_max(cell)), domain_index) > domain_level-epsilon) );
1295 return (dom_at(diti_to_drpt(ccc_cell_get_corner_max(cell)), domain_index) < domain_level);
1304 return ((dom_at(diti_to_drpt(ccc_cell_get_corner_min(cell)), domain_index) > domain_level));
1314 int center_sign = mjr::math::sfun::sgn(rng_at(samples[cell], range_index)-range_level);
1315 if (center_sign == 0)
1317 for(
diti_t& v: ccc_get_corners(cell))
1318 if (center_sign != mjr::math::sfun::sgn(rng_at(samples[v], range_index)-range_level))
1330 return std::all_of(verts.cbegin(), verts.cend(), [
this, range_index, range_level](
int i) { return (rng_at(samples[i], range_index) < range_level); });
1340 return std::all_of(verts.cbegin(), verts.cend(), [
this, range_index, range_level](
int i) { return (rng_at(samples[i], range_index) > range_level); });
1349 int max_level_neighbor = get_smallest_neighbor_level(cell);
1350 int current_ccc_cell_level = ccc_cell_level(cell);
1351 if (max_level_neighbor > current_ccc_cell_level+level_delta)
1365 if constexpr (rng_dim == 1) {
1366 return std::isnan(samples[vertex]);
1368 return (std::any_of(samples[vertex].cbegin(), samples[vertex].cend(), [
this](
src_t v) {
return (std::isnan(v)); }));
1375 return (samples.contains(vertex));
1387 if (cell_has_child(cell)) {
1388 for(
auto const c : ccc_get_children(cell)) {
1389 auto mv = get_leaf_cells(c);
1390 std::move(mv.begin(), mv.end(), std::back_inserter(rv));
1400 return get_leaf_cells(ccc_get_top_cell());
1409 for(
auto c: get_leaf_cells(cell))
1411 cells_to_return.push_back(c);
1412 return cells_to_return;
1421 if (cell_has_child(cell)) {
1422 for(
auto const c : ccc_get_children(cell, index, direction)) {
1423 auto mv = get_leaf_cells(c, index, direction);
1424 std::move(mv.begin(), mv.end(), std::back_inserter(rv));
1436 if (cell_has_child(cell)) {
1437 for(
auto const c : ccc_get_children(cell)) {
1438 int mv = count_leaf_cells(c);
1454 diti_t tmp = ccc_get_neighbor(cell, index, direction);
1455 if ( (tmp!=0) && cell_exists(tmp)) {
1456 if (cell_has_child(tmp)) {
1457 return get_leaf_cells(tmp, index, -direction);
1469 int maximum_level = -1;
1470 int start_level = ccc_cell_level(cell);
1471 for(
int aix=0; aix<dom_dim; aix++) {
1472 for(
int dir=-1; dir<2; dir+=2) {
1473 diti_t nbr0 = ccc_get_neighbor(cell, aix, dir);
1474 if ( (nbr0!=0) && cell_exists(nbr0)) {
1475 if (cell_has_child(nbr0)) {
1476 diti_list_t nbr_leafs = get_leaf_cells(nbr0, aix, -dir);
1477 for(
auto nbr_leaf: nbr_leafs) {
1478 int nbr_leaf_lvl = ccc_cell_level(nbr_leaf);
1479 if (nbr_leaf_lvl > maximum_level)
1480 maximum_level = nbr_leaf_lvl;
1483 if (start_level > maximum_level)
1484 maximum_level = start_level;
1489 return maximum_level;
1502 std::ostringstream convert;
1503 int pwid = (do_hex ? (max_level+1)/4+1 : (max_level+1)/2+1);
1504 dita_t tmp1 = diti_to_dita(diti);
1505 for(
int i=0; i<dom_dim; i++)
1506 convert << std::setw(pwid) << std::setfill(
'0') << (do_hex ? std::hex : std::dec ) << (uint32_t)tmp1[dom_dim-1-i] << std::dec << std::setw(0) << std::setfill(
'\0') <<
" ";
1507 if (include_domain) {
1508 drta_t tmp3 = diti_to_drta(diti);
1510 for (
const auto tmp4 : tmp3)
1511 convert << std::setprecision(5) << static_cast<src_t>(tmp4) <<
" ";
1514 return(convert.str());
1523 std::ostringstream convert;
1524 if constexpr (dom_dim == 1) {
1525 convert <<
"[ " << x <<
" ]";
1529 convert << std::setprecision(5) << static_cast<src_t>(c) <<
" ";
1532 return(convert.str());
1537 std::ostringstream convert;
1538 if constexpr (rng_dim == 1) {
1539 convert <<
"[ " << x <<
" ]";
1543 convert << std::setprecision(5) << static_cast<src_t>(c) <<
" ";
1546 return(convert.str());
1552 std::cout <<
"Meta Data" << std::endl;
1553 std::cout <<
" get_bbox_min ... " << drpt_to_string(get_bbox_min()) << std::endl;
1554 std::cout <<
" get_bbox_max ... " << drpt_to_string(get_bbox_max()) << std::endl;
1555 std::cout <<
" dom_dim ........ " << dom_dim << std::endl;
1556 std::cout <<
" rng_dim ........ " << rng_dim << std::endl;
1557 std::cout <<
" max_level ...... " << max_level << std::endl;
1558 std::cout <<
" size icrd Cmp .. " <<
sizeof(
dic_t) << std::endl;
1559 std::cout <<
" size icrd Tup .. " <<
sizeof(
diti_t) << std::endl;
1560 std::cout <<
" Samples ........ " << samples.size() << std::endl;
1561 std::cout <<
" Leaf Cells ..... " << count_leaf_cells(ccc_get_top_cell()) << std::endl;
1562 std::cout <<
"Samples" << std::endl;
1563 int num_printed = 0;
1564 for (
const auto& kvp : samples) {
1565 std::cout <<
" c=" << diti_to_string(kvp.first,
true);
1566 std::cout <<
" v=" << rrpt_to_string(kvp.second) << std::endl;
1568 if ((max_num_print > 0) && (num_printed >= max_num_print)) {
1569 std::cout <<
"Maximum number of samples reached. Halting tree dump." << std::endl;
1577 std::ofstream out_stream;
1578 out_stream.open(file_name, std::ios::out | std::ios::binary | std::ios::trunc);
1579 if (out_stream.is_open()) {
1580 out_stream.imbue(std::locale::classic());
1582 std::cout <<
"ERROR(write_xml_vtk): Could not open file!" << std::endl;
1585 for (
const auto& kvp : samples) {
1586 for(
int i=0; i<dom_dim; i++)
1587 out_stream << std::setprecision(5) << dom_at(diti_to_drpt(kvp.first), i) <<
" ";
1588 for(
int i=0; i<rng_dim; i++)
1589 out_stream << std::setprecision(5) << rng_at(kvp.second, i) <<
" ";
1590 out_stream << std::endl;
1733#define MJR_INCLUDE_MR_rect_tree
Template Class used to house an MR_rect_tree.
dic_t ccc_cell_level(diti_t cell) const
Compute cell level.
diti_list_t ccc_get_vertexes(diti_t cell) const
Return a list of the vertexes (corners and center) of the given cell.
drpt_t get_bbox_delta() const
Return the bounding box minimum point.
dic_t ccc_cell_full_width(diti_t cell) const
Compute cell full width.
void refine_recursive_if_cell_vertex_is_nan(int level, drpt2rrpt_func_t func)
Refine a cells with NaNs until refined cells reach specified level.
src_t rrpt_distance_inf(rrpt_t val1, rrpt_t val2) const
Distance between two points in the range space using the infinity norm (max absolute value)
bool cell_above_range_level(diti_t cell, int range_index, src_t range_level)
Test if a cell is above given range component value.
bool cell_above_domain_level(diti_t cell, int domain_index, src_t domain_level)
Test if a cell above the given domain component value.
diti_t ccc_get_top_cell() const
Compute the top cell coordinates for the tree.
std::array< src_t, rng_dim > rrta_t
An std::array for points in the range space.
std::unordered_map< diti_t, rrpt_t > samples
Holds the sampled data.
diti_list_t get_existing_neighbor(diti_t cell, int index, int direction) const
Return a list of sampled neighbors to the given cell.
void set_bbox_min(drpt_t new_bbox_min)
Set the bounding box minimum.
std::string drpt_to_string(drpt_t x) const
Convert a drpt_t to a string representation.
bool cell_cross_range_level(diti_t cell, int range_index, src_t range_level)
Test if a cell crosses the given range component value.
rrta_t get_sample_rrta(diti_t vertex) const
Return the sample value for vertex as an rrta_t (an std::array)
dita_t diti_to_dita(diti_t diti) const
Convert a packed integer coordinate tuple to an std::array of integer coordinate tuple Note dita_t is...
MR_rect_tree(drpt_t new_bbox_min, drpt_t new_bbox_max)
Set real coordinate as specified.
bool cell_near_domain_level(diti_t cell, int domain_index, src_t domain_level, src_t epsilon)
Test if a cell crosses the given domain component value.
std::function< bool(diti_t)> diti2bool_func_t
Integer input predicate function.
void refine_leaves_recursive_cell_pred(int level, drpt2rrpt_func_t func, diti2bool_func_t pred)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool cell_has_neighbor(diti_t cell, int index, int direction)
Test if the specified neighbor cell exixts (is smapled).
std::function< rrpt_t(drpt_t)> drpt2rrpt_func_t
Real input sample function.
int refine_leaves_once_if_unbalanced(int level_delta, drpt2rrpt_func_t func)
Refine leaf cells if they are unbalanced at the given level.
bool cell_cross_sdf(diti_t cell, drpt2real_func_t sdf)
Test if a cell crosses, or is on, a signed distance function boundry.
bool vertex_exists(diti_t vertex) const
Point has been sampled.
void balance_tree(int level_delta, drpt2rrpt_func_t func)
Balance the cell to the given level.
diti_list_t ccc_get_children(diti_t cell, int index, int direction) const
Return a list of child cells of the specified cell An empty vector is returned if no children are pos...
void refine_recursive(diti_t cell, int level, drpt2rrpt_func_t func)
Refine a cell until refined cells reach specified level.
bool cell_corner_is_nan(diti_t cell)
Test if a cell has an corner with a NaN value for a sample.
diti_t cuc_set_all_crd(dic_t value) const
Set all components in a a tuple to a constant.
void refine_leaves_recursive_cell_pred(diti_t cell, int level, drpt2rrpt_func_t func, diti2bool_func_t pred)
Refine a cells matching predicate until refined cells reach specified level.
diti_t ccc_get_neighbor(diti_t cell, int index, int direction) const
Return the potential neighbor cell along the given axis in the specified direction.
std::string diti_to_string(diti_t diti, bool include_domain) const
bool vertex_is_nan(diti_t vertex)
Test if a vertex is NaN or, when it is an std::array, if it contains a NaN element.
std::conditional< std::cmp_greater_equal(CHAR_BIT *sizeof(int8_t), diti_bits), uint8_t, typenamestd::conditional< std::cmp_greater_equal(CHAR_BIT *sizeof(int16_t), diti_bits), uint16_t, typenamestd::conditional< std::cmp_greater_equal(CHAR_BIT *sizeof(int32_t), diti_bits), uint32_t, uint64_t >::type >::type >::type priv_diti_t
diti_t ccc_cell_get_corner_min(diti_t cell) const
Cell first corner.
bool cell_vertex_is_nan(diti_t cell)
Test if a cell has a vertex with a NaN value for a sample.
diti_t dita_to_diti(const dita_t &dita) const
Convert an std::array of integer coordinate tuple to an packed integer coordinate tuple.
bool cell_can_have_children(diti_t cell) const
Test if a cell can have children (it not of minimal size)
void set_bbox_default()
Set the bounding box to the default: -1 for all minimum components and +1 for all maximum components.
void refine_grid(int level_delta, drpt2rrpt_func_t func)
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::function< src_t(drpt_t)> drpt2real_func_t
Real input, single real variable output function.
drpt_t bbox_max
Holds the maximal point for the real domain range.
std::unordered_map< diti_t, rrpt_t >::const_iterator cbegin_samples()
Provide a constant forward iterator for the sample data.
diti_list_t cuc_axis_cross(diti_t diti, dic_t delta) const
Compute axis aligned cross points centered at diti and delta away Axis aligned cross points that fall...
bool cell_good_cords(diti_t cell) const
Check if cell coordinates are in range to be a cell center.
void refine_recursive(int level, drpt2rrpt_func_t func)
This is an overloaded member function, provided for convenience. It differs from the above function o...
MR_rect_tree< max_level, spc_real_t, dom_dim, rng_dim > this_t
Externally exposed typedef for spc_real_t.
priv_diti_t diti_t
Unsigned integer type large large enough to hold an integer coordiante tuple.
diti_t cuc_dec_crd(diti_t diti, int index, dic_t value) const
Decriment a component in a a tuple.
diti_t ccc_cell_get_corner_max(diti_t cell) const
Cell last corner.
diti_t cuc_inc_all_crd(diti_t diti, dic_t value) const
Incriment all components in a a tuple.
diti_list_t ccc_get_children(diti_t cell) const
Return a list of child cells of the specified cell.
bool cell_is_sampled(diti_t cell) const
Test if a cell has been sampled.
std::function< bool(drpt_t)> drpt2bool_func_t
Real input predicate function.
bool cell_near_domain_point(drpt_t domain_point, src_t epsilon, diti_t cell)
Test if a cell contains, or is close to, a point in the domain.
bool cell_has_no_child(diti_t cell) const
Test if a cell has no children.
bool cell_below_range_level(diti_t cell, int range_index, src_t range_level)
Test if a cell is below given range component value.
src_t dom_at(drpt_t value, int index) const
drpt_t real_domain_t
A nicely descriptive typedef for drpt_t.
bool cell_has_child(diti_t cell) const
Test if a cell has children.
std::conditional< std::cmp_equal(dom_dim, 1), src_t, drta_t >::type drpt_t
For values in the domain space.
bool sample_point_maybe(diti_t diti, drpt2rrpt_func_t func)
Sample a point if it has not already been sampled.
std::string rrpt_to_string(rrpt_t x) const
Convert rrpt value to a string representation.
void sample_point(diti_t diti, drpt2rrpt_func_t func)
Sample, or resample, a point.
priv_dic_t dic_t
Unsigned integer type large large enough to hold an integer coordiante component.
std::array< dic_t, 3 > dita_t
Domain point given as an std::array integer tuple.
bool cell_below_domain_level(diti_t cell, int domain_index, src_t domain_level)
Test if a cell is below the given domain component value.
int refine_leaves_atomically_if_cell_pred(int level, drpt2rrpt_func_t func, diti2bool_func_t pred)
This is an overloaded member function, provided for convenience. It differs from the above function o...
drpt_t drpt_midpoint(drpt_t val1, drpt_t val2) const
Return the midpoint between two points in the domain space.
src_t drpt_distance_inf(drpt_t val1, drpt_t val2) const
Distance between two points in the domain space using the infinity norm (max absolute value)
drta_t diti_to_drta(diti_t diti) const
Convert a packed integer coordinate tuple to the coorisponding std::array tuple of src_t Unlike diti_...
rrpt_t real_range_t
A nicely descriptive typedef for rrpt_t.
diti_t cuc_dec_all_crd(diti_t diti, dic_t value) const
Decriment all components in a a tuple.
diti_list_t get_leaf_cells() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::unordered_map< diti_t, rrpt_t >::const_iterator cend_samples()
Provide a constant end iterator for the sample data.
std::conditional< std::cmp_equal(rng_dim, 1), src_t, rrta_t >::type rrpt_t
For values in the range space.
diti_list_t cuc_two_cross(diti_t diti, dic_t delta, int index, int direction) const
Compute directional cross product points centered at diti and delta away.
dic_t ccc_cell_quarter_width(diti_t cell) const
Compute cell quarter width.
diti_t cuc_inc_crd(diti_t diti, int index, dic_t value) const
Incriment a component in a a tuple.
int count_leaf_cells(diti_t cell) const
Count the number of leaf cells starting from the given cell.
void refine_grid(diti_t cell, int level_delta, drpt2rrpt_func_t func)
Sample a function uniformly across given cell to the given level.
std::vector< diti_t > diti_list_t
A std::vector used to pass lists of diti_t types around.
diti_list_t ccc_get_corners(diti_t cell, int index, int direction) const
Return a list of the corners of the given cell.
int get_smallest_neighbor_level(diti_t cell) const
Return the level of the smallest, existing neighbor.
void set_bbox(drpt_t new_bbox_min, drpt_t new_bbox_max)
Set the bounding box.
std::string diti_to_string(diti_t diti) const
drpt_t get_bbox_max() const
Return the bounding box minimum point.
void update_bbox_delta()
Update the value of bbox_delta.
bool cell_is_unbalanced(int level_delta, diti_t cell)
Test if a cell is unbalanced at the given level.
std::string diti_to_string(diti_t diti, bool include_domain, bool do_hex) const
Convert a diti_t to a string representation.
dic_t ccc_cell_half_width(diti_t cell) const
Compute cell half width.
drpt_t bbox_min
Holds the minimal point for the real domain range.
rrpt_t get_sample(diti_t vertex) const
Return the sample value for vertex.
spc_real_t src_t
Externally exposed typedef for spc_real_t.
int refine_leaves_atomically_if_cell_pred(diti_t cell, int level, drpt2rrpt_func_t func, diti2bool_func_t pred)
Repeatedly refine leaves of the given cell for which pred is true.
std::vector< dic_t > ditv_t
Domain point given as an std::vector integer tuple.
diti_list_t get_leaf_cells(diti_t cell, int index, int direction) const
Extract a list of all leaf cells starting from the given cell.
void dump_tree(int max_num_print) const
Dump tree to STDOUT.
bool cell_exists(diti_t cell) const
Test if a cell has been sampled.
int refine_leaves_once_if_cell_pred(int level, drpt2rrpt_func_t func, diti2bool_func_t pred)
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::vector< src_t > drtv_t
std::vector for values in the domain space.
diti_list_t get_leaf_cells_pred(diti_t cell, diti2bool_func_t pred) const
Extract a list of all leaf cells starting from the given cell that match the given predicate.
int dump_tree_datafile(std::string file_name) const
Dump tree points to file – one tuple per line with domain coordinates followed by range values.
drpt_t bbox_delta
The wdith of the real domain range.
void set_bbox_max(drpt_t new_bbox_max)
Set the bounding box max_level.
drpt_t diti_to_drpt(diti_t diti) const
Convert a packed integer coordinate tuple to the coorisponding coordinate in drpt_t Note this functio...
drpt_t get_bbox_min() const
Return the bounding box minimum point.
int refine_leaves_once_if_cell_pred(diti_t cell, int level, drpt2rrpt_func_t func, diti2bool_func_t pred)
Refine each leaf cell if pred returns true and the cell level is less than the given level value.
bool refine_once(diti_t cell, drpt2rrpt_func_t func)
Refine a cell if possible.
diti_list_t get_leaf_cells(diti_t cell) const
Extract a list of all leaf cells starting from the given cell.
diti_list_t cuc_two_cross(diti_t diti, dic_t delta) const
Compute cross product points centered at diti and delta away Examples:
std::vector< src_t > rrtv_t
std::vector for values in the range space.
void refine_recursive_cell_pred(diti_t cell, int level, drpt2rrpt_func_t func, diti2bool_func_t pred)
Refine a cells matching predicate until refined cells reach specified level.
dic_t cuc_get_crd(diti_t diti, int index) const
Extract a component from a tuple.
std::conditional< std::cmp_greater_equal(CHAR_BIT *sizeof(int8_t), dic_bits), uint8_t, typenamestd::conditional< std::cmp_greater_equal(CHAR_BIT *sizeof(int16_t), dic_bits), uint16_t, typenamestd::conditional< std::cmp_greater_equal(CHAR_BIT *sizeof(int32_t), dic_bits), uint32_t, uint64_t >::type >::type >::type priv_dic_t
void sample_cell(drpt2rrpt_func_t func)
This is an overloaded member function, provided for convenience. It differs from the above function o...
src_t rng_at(rrpt_t value, int index) const
diti_list_t ccc_get_corners(diti_t cell) const
Return a list of the corners of the given cell.
diti_list_t ccc_get_neighbors(diti_t cell) const
Return a list of potential neighbor cells of the specified cell Note the cells are not in canonical o...
bool rrpt_is_nan(rrpt_t val) const
Test if a point in the range space contains a NaN coordinate value.
MR_rect_tree()
Set real coordinates to defaults.
void sample_cell(diti_t cell, drpt2rrpt_func_t func)
Sample a cell.
std::array< src_t, dom_dim > drta_t
An std::array for points in the domain space.
mjr::MR_rect_tree< 15, double, 4, 1 > tree15b4d1rT
mjr::MR_rect_tree< 15, double, 3, 3 > tree15b3d3rT
mjr::MR_rect_tree< 7, double, 4, 2 > tree7b4d2rT
mjr::MR_rect_tree< 31, double, 2, 4 > tree31b2d4rT
mjr::MR_rect_tree< 15, double, 3, 9 > tree15b3d9rT
mjr::MR_rect_tree< 31, double, 2, 3 > tree31b2d3rT
mjr::MR_rect_tree< 7, double, 3, 3 > tree7b3d3rT
mjr::MR_rect_tree< 15, double, 1, 1 > tree15b1d1rT
mjr::MR_rect_tree< 15, double, 3, 12 > tree15b3d12rT
mjr::MR_rect_tree< 15, double, 1, 14 > tree15b1d14rT
mjr::MR_rect_tree< 15, double, 2, 7 > tree15b2d7rT
mjr::MR_rect_tree< 7, double, 4, 1 > tree7b4d1rT
mjr::MR_rect_tree< 7, double, 2, 1 > tree7b2d1rT
mjr::MR_rect_tree< 15, double, 2, 9 > tree15b2d9rT
mjr::MR_rect_tree< 15, double, 3, 2 > tree15b3d2rT
mjr::MR_rect_tree< 15, double, 1, 9 > tree15b1d9rT
mjr::MR_rect_tree< 7, double, 2, 2 > tree7b2d2rT
mjr::MR_rect_tree< 15, double, 3, 13 > tree15b3d13rT
mjr::MR_rect_tree< 15, double, 2, 1 > tree15b2d1rT
mjr::MR_rect_tree< 15, double, 1, 6 > tree15b1d6rT
mjr::MR_rect_tree< 31, double, 2, 2 > tree31b2d2rT
mjr::MR_rect_tree< 15, double, 4, 5 > tree15b4d5rT
mjr::MR_rect_tree< 15, double, 1, 5 > tree15b1d5rT
mjr::MR_rect_tree< 15, double, 1, 15 > tree15b1d15rT
mjr::MR_rect_tree< 15, double, 3, 1 > tree15b3d1rT
mjr::MR_rect_tree< 15, double, 2, 4 > tree15b2d4rT
mjr::MR_rect_tree< 15, double, 1, 11 > tree15b1d11rT
mjr::MR_rect_tree< 7, double, 1, 1 > tree7b1d1rT
mjr::MR_rect_tree< 63, double, 1, 3 > tree63b1d3rT
mjr::MR_rect_tree< 15, double, 1, 13 > tree15b1d13rT
mjr::MR_rect_tree< 7, double, 3, 2 > tree7b3d2rT
mjr::MR_rect_tree< 15, double, 4, 12 > tree15b4d12rT
mjr::MR_rect_tree< 7, double, 1, 4 > tree7b1d4rT
mjr::MR_rect_tree< 15, double, 3, 4 > tree15b3d4rT
mjr::MR_rect_tree< 15, double, 4, 4 > tree15b4d4rT
mjr::MR_rect_tree< 7, double, 4, 3 > tree7b4d3rT
mjr::MR_rect_tree< 63, double, 1, 4 > tree63b1d4rT
mjr::MR_rect_tree< 15, double, 2, 5 > tree15b2d5rT
mjr::MR_rect_tree< 15, double, 2, 13 > tree15b2d13rT
mjr::MR_rect_tree< 63, double, 1, 2 > tree63b1d2rT
mjr::MR_rect_tree< 15, double, 3, 6 > tree15b3d6rT
mjr::MR_rect_tree< 31, double, 2, 1 > tree31b2d1rT
mjr::MR_rect_tree< 15, double, 3, 15 > tree15b3d15rT
mjr::MR_rect_tree< 15, double, 3, 5 > tree15b3d5rT
mjr::MR_rect_tree< 15, double, 2, 12 > tree15b2d12rT
mjr::MR_rect_tree< 31, double, 1, 2 > tree31b1d2rT
mjr::MR_rect_tree< 7, double, 5, 1 > tree7b5d1rT
mjr::MR_rect_tree< 15, double, 1, 8 > tree15b1d8rT
mjr::MR_rect_tree< 15, double, 4, 7 > tree15b4d7rT
mjr::MR_rect_tree< 7, double, 3, 4 > tree7b3d4rT
mjr::MR_rect_tree< 15, double, 2, 6 > tree15b2d6rT
mjr::MR_rect_tree< 15, double, 4, 10 > tree15b4d10rT
mjr::MR_rect_tree< 7, double, 3, 1 > tree7b3d1rT
mjr::MR_rect_tree< 7, double, 1, 3 > tree7b1d3rT
mjr::MR_rect_tree< 15, double, 2, 2 > tree15b2d2rT
mjr::MR_rect_tree< 7, double, 1, 2 > tree7b1d2rT
mjr::MR_rect_tree< 15, double, 3, 11 > tree15b3d11rT
mjr::MR_rect_tree< 15, double, 4, 13 > tree15b4d13rT
mjr::MR_rect_tree< 15, double, 4, 8 > tree15b4d8rT
mjr::MR_rect_tree< 15, double, 4, 11 > tree15b4d11rT
mjr::MR_rect_tree< 15, double, 4, 6 > tree15b4d6rT
mjr::MR_rect_tree< 15, double, 2, 3 > tree15b2d3rT
mjr::MR_rect_tree< 15, double, 2, 11 > tree15b2d11rT
mjr::MR_rect_tree< 31, double, 1, 4 > tree31b1d4rT
mjr::MR_rect_tree< 15, double, 2, 15 > tree15b2d15rT
mjr::MR_rect_tree< 15, double, 2, 10 > tree15b2d10rT
mjr::MR_rect_tree< 15, double, 3, 14 > tree15b3d14rT
mjr::MR_rect_tree< 15, double, 1, 7 > tree15b1d7rT
mjr::MR_rect_tree< 15, double, 4, 14 > tree15b4d14rT
mjr::MR_rect_tree< 31, double, 1, 1 > tree31b1d1rT
mjr::MR_rect_tree< 15, double, 3, 7 > tree15b3d7rT
mjr::MR_rect_tree< 15, double, 1, 12 > tree15b1d12rT
mjr::MR_rect_tree< 15, double, 2, 8 > tree15b2d8rT
mjr::MR_rect_tree< 31, double, 1, 3 > tree31b1d3rT
mjr::MR_rect_tree< 15, double, 1, 10 > tree15b1d10rT
mjr::MR_rect_tree< 15, double, 4, 9 > tree15b4d9rT
mjr::MR_rect_tree< 15, double, 3, 8 > tree15b3d8rT
mjr::MR_rect_tree< 7, double, 2, 3 > tree7b2d3rT
mjr::MR_rect_tree< 7, double, 2, 4 > tree7b2d4rT
mjr::MR_rect_tree< 15, double, 1, 3 > tree15b1d3rT
mjr::MR_rect_tree< 15, double, 4, 15 > tree15b4d15rT
mjr::MR_rect_tree< 15, double, 4, 2 > tree15b4d2rT
mjr::MR_rect_tree< 15, double, 4, 3 > tree15b4d3rT
mjr::MR_rect_tree< 15, double, 1, 4 > tree15b1d4rT
mjr::MR_rect_tree< 15, double, 1, 2 > tree15b1d2rT
mjr::MR_rect_tree< 15, double, 3, 10 > tree15b3d10rT
mjr::MR_rect_tree< 63, double, 1, 1 > tree63b1d1rT
mjr::MR_rect_tree< 7, double, 4, 4 > tree7b4d4rT
mjr::MR_rect_tree< 15, double, 2, 14 > tree15b2d14rT