137 void * coords_data,
size_t coords_size,
size_t coords_count,
141 double balance_point[3] = {0.0,0.0,0.0};
144 for (
size_t i = 0; i < coords_count; ++i) {
147 (
double*)(((
unsigned char*)coords_data) + i * coords_size);
148 balance_point[0] += coords[0];
149 balance_point[1] += coords[1];
150 balance_point[2] += coords[2];
153 if ((fabs(balance_point[0]) > 1e-9) ||
154 (fabs(balance_point[1]) > 1e-9) ||
155 (fabs(balance_point[2]) > 1e-9)) {
158 balance_point[0] = prev_gc_norm_vector[2];
159 balance_point[1] = prev_gc_norm_vector[0];
160 balance_point[2] = prev_gc_norm_vector[1];
186 for (
size_t j = begin; j < end; ++j)
200 size_t I_begin = I_FULL_size;
201 size_t U_begin = I_FULL_size + I_size;
202 size_t T_begin = I_FULL_size + I_size + U_size;
204 size_t I_end = I_begin + I_size;
205 size_t U_end = U_begin + U_size;
206 size_t T_end = T_begin + T_size;
208 while (I_end > I_begin && part_data[I_end-1].
node_type ==
I_NODE) I_end--;
209 while (U_end > U_begin && part_data[U_end-1].
node_type ==
U_NODE) U_end--;
210 while (T_end > T_begin && part_data[T_end-1].
node_type ==
T_NODE) T_end--;
212 for (
size_t i = 0; i < I_FULL_size; ++i)
220 I_begin = I_FULL_size;
221 for (
size_t i = I_begin; i < I_end; ++i)
233 U_begin = I_FULL_size + I_size;
234 T_begin = I_FULL_size + I_size + U_size;
235 for (
size_t i = U_begin; i < U_end; ++i)
246 size_t num_cell_ids,
size_t threshold,
struct sphere_part_node * parent_node,
247 double prev_gc_norm_vector[]) {
249 if (num_cell_ids == 0) {
255 part_data,
sizeof(*part_data), num_cell_ids,
261 size_t I_FULL_size = 0;
268 for (
size_t i = 0; i < num_cell_ids; ++i) {
305 max_inc_angle = inc_angle;
309 }
else if (angle.
cos < 0.0) {
325 I_size += I_FULL_size;
326 parent_node->
I_size = I_size;
327 parent_node->
U_size = U_size;
328 parent_node->
T_size = T_size;
334 parent_node->
I_angle = max_inc_angle;
348 for (
size_t i = 0; i < I_FULL_size; ++i) {
355 for (
size_t i = I_FULL_size; i < I_size; ++i) {
357 double GCp[3], bVp[3];
366 (fabs(bVp[0]) > 1e-9) || (fabs(bVp[1]) > 1e-9) ||
367 (fabs(bVp[2]) > 1e-9),
368 "ERROR(partition_data): "
369 "projected vector is nearly identical to gc_norm_vector")
380 double bnd_circle_lat_cos =
383 M_PI_2 - acos(curr_bnd_circle.
inc_angle.
sin/bnd_circle_lat_cos);
400 for (
size_t i = 0; i < I_size; ++i)
401 local_cell_ids[i] = part_data[i].local_id;
402 parent_node->
I.
list = (
void*)local_cell_ids;
405 parent_node->
I.
list = NULL;
408 local_cell_ids += I_size;
411 if (U_size <= threshold) {
413 for (
size_t i = 0; i < U_size; ++i)
414 local_cell_ids[i] = part_data[i].local_id;
415 parent_node->
U = (
void*)local_cell_ids;
424 local_cell_ids += U_size;
427 if (T_size <= threshold) {
429 for (
size_t i = 0; i < T_size; ++i)
430 local_cell_ids[i] = part_data[i].local_id;
431 parent_node->
T = (
void*)local_cell_ids;
433 local_cell_ids += T_size;
450 double prev_gc_norm_vector[],
size_t curr_tree_depth,
451 size_t * max_tree_depth) {
453 if (curr_tree_depth > *max_tree_depth) *max_tree_depth = curr_tree_depth;
473 while (left <= right) {
475 double dot = curr_coordinates_xyz[0] * gc_norm_vector[0] +
476 curr_coordinates_xyz[1] * gc_norm_vector[1] +
477 curr_coordinates_xyz[2] * gc_norm_vector[2];
480 if (dot > 0.0)
break;
485 while (left < right) {
486 double * curr_coordinates_xyz = &(right->coordinates_xyz[0]);
487 double dot = curr_coordinates_xyz[0] * gc_norm_vector[0] +
488 curr_coordinates_xyz[1] * gc_norm_vector[1] +
489 curr_coordinates_xyz[2] * gc_norm_vector[2];
492 if (dot <= 0.0)
break;
507 size_t U_size = left -
points;
515 if ((U_size <= threshold) || (U_size ==
num_points)) {
524 curr_tree_depth + 1, max_tree_depth);
527 if ((T_size <= threshold) || (T_size ==
num_points)) {
537 curr_tree_depth + 1, max_tree_depth);
548 double gc_norm_vector[3] = {0.0,0.0,1.0};
556 xmalloc(num_circles *
sizeof(*part_data));
557 for (
size_t i = 0; i < num_circles; ++i) {
571 const void * a,
const void * b) {
578 for (
int i = 0; i < 3; ++i)
588 yac_int const * ids,
int const * mask) {
593 double const scale = (double)(2 << 21);
595 size_t num_unmasked_points;
599 for (
size_t i = 0; i < num_unmasked_points; ++i) {
601 points_int32[i].
idx = i;
602 for (
size_t j = 0; j < 3; ++j)
604 (int32_t)round(coordinates_xyz[i][j] * scale);
607 num_unmasked_points = 0;
610 if (!mask[i])
continue;
611 points_int32[num_unmasked_points].
idx = i;
612 for (
size_t j = 0; j < 3; ++j)
614 (int32_t)round(coordinates_xyz[i][j] * scale);
615 num_unmasked_points++;
620 qsort(points_int32, num_unmasked_points,
624 dummy.
idx = SIZE_MAX;
630 size_t new_num_points = 0;
631 for (
size_t i = 0; i < num_unmasked_points; ++i, ++curr) {
633 size_t curr_idx = curr->
idx;
635 prev = points_int32 + new_num_points++;
636 if (prev != curr) *prev = *curr;
637 prev_id = ids[curr_idx];
639 yac_int curr_id = ids[curr_idx];
640 if (curr_id > prev_id) {
642 prev->
idx = curr_idx;
648 for (
size_t i = 0; i < new_num_points; ++i) {
649 size_t curr_idx = points_int32[i].
idx;
670 size_t max_tree_depth = 0;
687 yac_int const * ids,
int const * mask) {
703 (
double[3]){0.0,0.0,1.0}, 1, &max_tree_depth);
714 size_t ** restrict overlap_cells,
size_t * overlap_cells_array_size,
715 size_t * restrict num_overlap_cells,
716 struct overlaps * search_interval_tree_buffer,
double prev_gc_norm_vector[]) {
723 angle.
cos = fabs(angle.
cos);
730 (*overlap_cells)[(*num_overlap_cells)+i] =
736 double GCp[3], bVp[3];
743 (fabs(bVp[0]) > 1e-9) || (fabs(bVp[1]) > 1e-9) || (fabs(bVp[2]) > 1e-9),
744 "ERROR(search_bnd_circle_I_node): "
745 "projected vector is nearly identical to gc_norm_vector")
751 double bnd_circle_lat_cos =
754 M_PI_2 - acos(bnd_circle.
inc_angle.
sin/bnd_circle_lat_cos);
764 .left = base_angle - inc_angle,
765 .right = base_angle + inc_angle},
766 search_interval_tree_buffer);
772 for (
size_t i = 0; i < search_interval_tree_buffer->
num_overlaps; ++i)
773 (*overlap_cells)[(*num_overlap_cells)+i] =
777 *num_overlap_cells += search_interval_tree_buffer->
num_overlaps;
782 *num_overlap_cells + node->
I_size);
783 memcpy(*overlap_cells + *num_overlap_cells, node->
I.
list,
784 node->
I_size *
sizeof(**overlap_cells));
785 *num_overlap_cells += node->
I_size;
792 size_t ** restrict overlap_cells,
size_t * overlap_cells_array_size,
793 size_t * restrict num_overlap_cells,
794 struct overlaps * search_interval_tree_buffer,
double prev_gc_norm_vector[]) {
799 *num_overlap_cells + node->
T_size);
800 memcpy(*overlap_cells + *num_overlap_cells, node->
T,
801 node->
T_size *
sizeof(**overlap_cells));
802 *num_overlap_cells += node->
T_size;
806 node->
T, bnd_circle, overlap_cells, overlap_cells_array_size,
807 num_overlap_cells, search_interval_tree_buffer, node->
gc_norm_vector);
813 *num_overlap_cells + node->
U_size);
814 memcpy(*overlap_cells + *num_overlap_cells, node->
U,
815 node->
U_size *
sizeof(**overlap_cells));
816 *num_overlap_cells += node->
U_size;
820 node->
U, bnd_circle, overlap_cells, overlap_cells_array_size,
821 num_overlap_cells, search_interval_tree_buffer, node->
gc_norm_vector);
825 node, bnd_circle, overlap_cells, overlap_cells_array_size,
826 num_overlap_cells, search_interval_tree_buffer, prev_gc_norm_vector);
831 size_t ** restrict overlap_cells,
size_t * overlap_cells_array_size,
832 size_t * restrict num_overlap_cells,
833 struct overlaps * search_interval_tree_buffer,
double prev_gc_norm_vector[]) {
845 *num_overlap_cells + node->
T_size);
846 memcpy(*overlap_cells + *num_overlap_cells, node->
T,
847 node->
T_size *
sizeof(**overlap_cells));
848 *num_overlap_cells += node->
T_size;
852 node->
T, bnd_circle, overlap_cells, overlap_cells_array_size,
853 num_overlap_cells, search_interval_tree_buffer,
864 *num_overlap_cells + node->
U_size);
865 memcpy(*overlap_cells + *num_overlap_cells, node->
U,
866 node->
U_size *
sizeof(**overlap_cells));
867 *num_overlap_cells += node->
U_size;
871 node->
U, bnd_circle, overlap_cells, overlap_cells_array_size,
872 num_overlap_cells, search_interval_tree_buffer,
897 if (((angle_sum.
sin < 0.0) || (angle_sum.
cos <= 0.0)) ||
898 (fabs(dot) <= angle_sum.
sin)) {
900 node, bnd_circle, overlap_cells, overlap_cells_array_size,
901 num_overlap_cells, search_interval_tree_buffer, prev_gc_norm_vector);
907 size_t ** restrict overlap_cells,
908 size_t * overlap_cells_array_size,
909 size_t * restrict num_overlap_cells,
910 struct overlaps * search_interval_tree_buffer,
911 double prev_gc_norm_vector[]) {
916 node, bnd_circle, overlap_cells, overlap_cells_array_size,
917 num_overlap_cells, search_interval_tree_buffer, prev_gc_norm_vector);
920 node, bnd_circle, overlap_cells, overlap_cells_array_size,
921 num_overlap_cells, search_interval_tree_buffer, prev_gc_norm_vector);
926 double * point_coordinates_xyz,
struct sin_cos_angle * best_angle,
927 double (**result_coordinates_xyz)[3],
928 size_t * result_coordinates_xyz_array_size,
size_t ** local_point_ids,
929 size_t * local_point_ids_array_size,
size_t total_num_local_point_ids,
930 size_t * num_local_point_ids) {
932 size_t * local_point_ids_ = *local_point_ids;
933 size_t local_point_ids_array_size_ = *local_point_ids_array_size;
934 double (*result_coordinates_xyz_)[3];
935 size_t result_coordinates_xyz_array_size_;
936 size_t num_local_point_ids_ = *num_local_point_ids;
938 if (result_coordinates_xyz != NULL) {
939 result_coordinates_xyz_ = *result_coordinates_xyz;
940 result_coordinates_xyz_array_size_ = *result_coordinates_xyz_array_size;
942 result_coordinates_xyz_, result_coordinates_xyz_array_size_,
943 total_num_local_point_ids + num_local_point_ids_ +
num_points);
944 *result_coordinates_xyz = result_coordinates_xyz_;
945 *result_coordinates_xyz_array_size = result_coordinates_xyz_array_size_;
946 result_coordinates_xyz_ += total_num_local_point_ids;
949 local_point_ids_, local_point_ids_array_size_,
950 total_num_local_point_ids + num_local_point_ids_ +
num_points);
951 *local_point_ids = local_point_ids_;
952 *local_point_ids_array_size = local_point_ids_array_size_;
953 local_point_ids_ += total_num_local_point_ids;
961 points[i].coordinates_xyz, point_coordinates_xyz);
965 if (compare > 0)
continue;
970 *best_angle = curr_angle;
971 num_local_point_ids_ = 1;
972 if (result_coordinates_xyz != NULL) {
973 result_coordinates_xyz_[0][0] =
points[i].coordinates_xyz[0];
974 result_coordinates_xyz_[0][1] =
points[i].coordinates_xyz[1];
975 result_coordinates_xyz_[0][2] =
points[i].coordinates_xyz[2];
977 local_point_ids_[0] =
points[i].idx;
981 if (result_coordinates_xyz != NULL) {
982 result_coordinates_xyz_[num_local_point_ids_][0] =
983 points[i].coordinates_xyz[0];
984 result_coordinates_xyz_[num_local_point_ids_][1] =
985 points[i].coordinates_xyz[1];
986 result_coordinates_xyz_[num_local_point_ids_][2] =
987 points[i].coordinates_xyz[2];
989 local_point_ids_[num_local_point_ids_] =
points[i].idx;
990 num_local_point_ids_++;
994 *num_local_point_ids = num_local_point_ids_;
998 struct bounding_circle * bnd_circle,
double (**result_coordinates_xyz)[3],
999 size_t * result_coordinates_xyz_array_size,
size_t ** local_point_ids,
1000 size_t * local_point_ids_array_size,
size_t total_num_local_point_ids,
1001 size_t * num_local_point_ids,
double * dot_stack,
1003 int * flags,
size_t curr_tree_depth) {
1005 double * point_coordinates_xyz = bnd_circle->
base_vector;
1008 double dot = dot_stack[curr_tree_depth];
1020 if ((dot < best_angle.
sin) | (best_angle.
cos <= 0.0)) {
1026 point_coordinates_xyz, &best_angle, result_coordinates_xyz,
1027 result_coordinates_xyz_array_size, local_point_ids,
1028 local_point_ids_array_size, total_num_local_point_ids,
1029 num_local_point_ids);
1039 dot_stack[curr_tree_depth] = dot;
1040 node_stack[curr_tree_depth] = node;
1041 flags[curr_tree_depth] = 0;
1054 if ((dot > - best_angle.
sin) || (best_angle.
cos <= 0.0)) {
1060 point_coordinates_xyz, &best_angle, result_coordinates_xyz,
1061 result_coordinates_xyz_array_size, local_point_ids,
1062 local_point_ids_array_size, total_num_local_point_ids,
1063 num_local_point_ids);
1073 dot_stack[curr_tree_depth] = dot;
1074 node_stack[curr_tree_depth] = node;
1075 flags[curr_tree_depth] = 0;
1083 if (curr_tree_depth == 0)
break;
1088 dot = dot_stack[curr_tree_depth];
1089 node = node_stack[curr_tree_depth];
1113 size_t U_size = node->
U_size;
1114 for (
size_t i = 0; i < U_size; ++i) {
1133 size_t T_size = node->
T_size;
1134 for (
size_t i = 0; i < T_size; ++i) {
1152 size_t ** local_point_ids,
size_t * local_point_ids_array_size,
1153 double (**result_coordinates_xyz)[3],
1154 size_t * result_coordinates_xyz_array_size,
1155 size_t total_num_local_point_ids,
size_t * num_local_point_ids) {
1163 total_num_local_point_ids + 1);
1164 (*local_point_ids)[total_num_local_point_ids] =
points[i].idx;
1165 if (result_coordinates_xyz != NULL) {
1167 *result_coordinates_xyz_array_size,
1168 total_num_local_point_ids + 1);
1169 memcpy((*result_coordinates_xyz) + total_num_local_point_ids,
1172 *num_local_point_ids = 1;
1183 double * cos_angles,
1184 double (**result_coordinates_xyz)[3],
1185 size_t * result_coordinates_xyz_array_size,
1186 size_t ** local_point_ids,
1187 size_t * local_point_ids_array_size,
1188 size_t * num_local_point_ids) {
1190 memset(num_local_point_ids, 0,
num_points *
sizeof(*num_local_point_ids));
1192 if (search == NULL)
return;
1196 size_t total_num_local_point_ids = 0;
1207 double * curr_coordinates_xyz = coordinates_xyz[i];
1209 size_t curr_tree_depth = 0;
1211 size_t curr_num_points = 0;
1216 double dot = curr_node->
gc_norm_vector[0]*curr_coordinates_xyz[0] +
1220 dot_stack[curr_tree_depth] = dot;
1221 node_stack[curr_tree_depth] = curr_node;
1222 flags[curr_tree_depth] = 0;
1227 flags[curr_tree_depth] =
U_FLAG;
1230 if (curr_node->
U_size > 0) {
1232 curr_num_points = curr_node->
U_size;
1235 flags[curr_tree_depth] =
T_FLAG;
1238 "ERROR(yac_point_sphere_part_search_NN): "
1239 "if one branch is empty, the other has to be a leaf");
1241 curr_num_points = curr_node->
T_size;
1244 }
else curr_node = curr_node->
U;
1249 flags[curr_tree_depth] =
T_FLAG;
1252 if (curr_node->
T_size > 0) {
1254 curr_num_points = curr_node->
T_size;
1257 flags[curr_tree_depth] =
U_FLAG;
1260 "ERROR(yac_point_sphere_part_search_NN): "
1261 "if one branch is empty, the other has to be a leaf");
1263 curr_num_points = curr_node->
U_size;
1266 }
else curr_node = curr_node->
T;
1274 points, curr_num_points, curr_coordinates_xyz, local_point_ids,
1275 local_point_ids_array_size, result_coordinates_xyz,
1276 result_coordinates_xyz_array_size, total_num_local_point_ids,
1277 num_local_point_ids + i)) {
1279 if (cos_angles != NULL) cos_angles[i] = 1.0;
1284 bnd_circle.
base_vector[0] = curr_coordinates_xyz[0];
1285 bnd_circle.
base_vector[1] = curr_coordinates_xyz[1];
1286 bnd_circle.
base_vector[2] = curr_coordinates_xyz[2];
1288 bnd_circle.
sq_crd = DBL_MAX;
1292 result_coordinates_xyz, result_coordinates_xyz_array_size,
1293 local_point_ids, local_point_ids_array_size, total_num_local_point_ids,
1294 num_local_point_ids + i);
1298 &bnd_circle, result_coordinates_xyz, result_coordinates_xyz_array_size,
1299 local_point_ids, local_point_ids_array_size, total_num_local_point_ids,
1300 num_local_point_ids + i, dot_stack, node_stack, flags, curr_tree_depth);
1302 if (cos_angles != NULL) cos_angles[i] = bnd_circle.
inc_angle.
cos;
1305 total_num_local_point_ids += num_local_point_ids[i];
1321 if (ret != 0)
return ret;
1329 size_t * results_array_size) {
1344#pragma _NEC novector
1350 points[i].coordinates_xyz[0] * point_coordinates_xyz[0] +
1351 points[i].coordinates_xyz[1] * point_coordinates_xyz[1] +
1352 points[i].coordinates_xyz[2] * point_coordinates_xyz[2]);
1360 double min_cos_angle = results_[n - 1].
cos_angle;
1362 for (num_results = n;
1364 !(fabs(min_cos_angle - results_[num_results].
cos_angle) > 0.0);
1371 size_t n, double * point_coordinates_xyz,
1376 size_t num_results_ = *num_results;
1382 double min_cos_angle = results_[num_results_-1].
cos_angle;
1387 double curr_cos_angle =
1388 points[i].coordinates_xyz[0] * point_coordinates_xyz[0] +
1389 points[i].coordinates_xyz[1] * point_coordinates_xyz[1] +
1390 points[i].coordinates_xyz[2] * point_coordinates_xyz[2];
1393 if (curr_cos_angle < min_cos_angle)
continue;
1396 {.
point =
points[i], .cos_angle = curr_cos_angle};
1400 for (j = 0; j < num_results_; ++j) {
1403 &point, results_ + num_results_ - j - 1) < 0) {
1404 results_[num_results_ - j] = results_[num_results_ - j - 1];
1409 results_[num_results_ - j] = point;
1417 if (num_results_ > n) {
1419 size_t new_num_results;
1420 min_cos_angle = results_[n - 1].
cos_angle;
1422 for (new_num_results = n;
1423 (new_num_results < num_results_) &&
1424 !(fabs(min_cos_angle - results_[new_num_results].cos_angle) > 0.0);
1426 num_results_ = new_num_results;
1428 *num_results = num_results_;
1432 results_[num_results_-1].point.coordinates_xyz, point_coordinates_xyz);
1433 }
else return curr_angle;
1437 size_t n,
double * point_coordinates_xyz,
1439 size_t * num_results,
double * dot_stack,
1441 size_t curr_tree_depth) {
1445 (*results)[(*num_results)-1].point.coordinates_xyz,
1446 point_coordinates_xyz);
1451 double dot = dot_stack[curr_tree_depth];
1463 if ((dot < angle.
sin) | (angle.
cos <= 0.0)) {
1469 node->
U_size, results, results_array_size, num_results, angle);
1479 dot_stack[curr_tree_depth] = dot;
1480 node_stack[curr_tree_depth] = node;
1481 flags[curr_tree_depth] = 0;
1494 if ((dot > - angle.
sin) || (angle.
cos <= 0.0)) {
1500 node->
T_size, results, results_array_size, num_results, angle);
1510 dot_stack[curr_tree_depth] = dot;
1511 node_stack[curr_tree_depth] = node;
1512 flags[curr_tree_depth] = 0;
1520 if (curr_tree_depth == 0)
break;
1525 dot = dot_stack[curr_tree_depth];
1526 node = node_stack[curr_tree_depth];
1535 double (*coordinates_xyz)[3],
size_t n,
1536 double ** cos_angles,
1537 size_t * cos_angles_array_size,
1538 double (**result_coordinates_xyz)[3],
1539 size_t * result_coordinates_xyz_array_size,
1540 size_t ** local_point_ids,
1541 size_t * local_point_ids_array_size,
1542 size_t * num_local_point_ids) {
1546 if (cos_angles != NULL)
1551 search,
num_points, coordinates_xyz, (cos_angles!=NULL)?*cos_angles:NULL,
1552 result_coordinates_xyz, result_coordinates_xyz_array_size,
1553 local_point_ids, local_point_ids_array_size, num_local_point_ids);
1555 size_t total_num_local_points = 0;
1557 total_num_local_points += num_local_point_ids[i];
1559 if ((cos_angles != NULL) && (total_num_local_points >
num_points)) {
1562 total_num_local_points);
1564 for (
size_t i =
num_points - 1, offset = total_num_local_points - 1;
1565 i != (size_t)-1; i--) {
1567 for (
size_t j = 0; j < num_local_point_ids[i]; ++j, --offset)
1568 (*cos_angles)[offset] = (*cos_angles)[i];
1575 if (search == NULL) {
1576 memset(num_local_point_ids, 0,
num_points *
sizeof(*num_local_point_ids));
1582 size_t total_num_local_point_ids = 0;
1590 size_t results_array_size = 0;
1596 double * curr_coordinates_xyz = coordinates_xyz[i];
1598 size_t curr_tree_depth = 0;
1600 size_t curr_num_points = 0;
1605 double dot = curr_node->
gc_norm_vector[0]*curr_coordinates_xyz[0] +
1609 dot_stack[curr_tree_depth] = dot;
1610 node_stack[curr_tree_depth] = curr_node;
1611 flags[curr_tree_depth] = 0;
1616 if (curr_node->
U_size < n) {
1619 curr_num_points = curr_node->
U_size + curr_node->
T_size;
1623 flags[curr_tree_depth] =
U_FLAG;
1624 curr_num_points = curr_node->
U_size;
1628 flags[curr_tree_depth] =
U_FLAG;
1629 curr_node = curr_node->
U;
1634 if (curr_node->
T_size < n) {
1637 curr_num_points = curr_node->
U_size + curr_node->
T_size;
1642 flags[curr_tree_depth] =
T_FLAG;
1643 curr_num_points = curr_node->
T_size;
1648 flags[curr_tree_depth] =
T_FLAG;
1649 curr_node = curr_node->
T;
1656 assert(curr_num_points > 0);
1658 size_t num_results =
1660 n,
points, curr_num_points, curr_coordinates_xyz,
1661 &results, &results_array_size);
1665 n, curr_coordinates_xyz, &results, &results_array_size, &num_results,
1666 dot_stack, node_stack, flags, curr_tree_depth);
1670 total_num_local_point_ids + num_results);
1671 size_t * local_point_ids_ =
1672 (*local_point_ids) + total_num_local_point_ids;
1673 double * cos_angles_;
1674 if (cos_angles != NULL) {
1676 total_num_local_point_ids + num_results);
1677 cos_angles_ = (*cos_angles) + total_num_local_point_ids;
1681 double (*result_coordinates_xyz_)[3];
1682 if (result_coordinates_xyz != NULL) {
1684 *result_coordinates_xyz_array_size,
1685 total_num_local_point_ids + num_results);
1686 result_coordinates_xyz_ =
1687 (*result_coordinates_xyz) + total_num_local_point_ids;
1689 result_coordinates_xyz_ = NULL;
1692 for (
size_t j = 0; j < num_results; ++j) {
1694 local_point_ids_[j] = results[j].
point.
idx;
1695 if (cos_angles_ != NULL) cos_angles_[j] = results[j].
cos_angle;
1696 if (result_coordinates_xyz_ != NULL) {
1703 num_local_point_ids[i] = num_results;
1704 total_num_local_point_ids += num_results;
1716 if (search == NULL)
return 0;
1723 size_t ** overlap_cells,
1724 size_t * overlap_cells_array_size,
1725 size_t * num_overlap_cells,
1726 struct overlaps * search_interval_tree_buffer,
1727 double prev_gc_norm_vector[]) {
1739 *num_overlap_cells + node->
T_size);
1740 memcpy(*overlap_cells + *num_overlap_cells, node->
T,
1741 node->
T_size *
sizeof(**overlap_cells));
1742 *num_overlap_cells += node->
T_size;
1746 overlap_cells_array_size, num_overlap_cells,
1757 *num_overlap_cells + node->
U_size);
1758 memcpy(*overlap_cells + *num_overlap_cells, node->
U,
1759 node->
U_size *
sizeof(**overlap_cells));
1760 *num_overlap_cells += node->
U_size;
1764 overlap_cells_array_size, num_overlap_cells,
1776 double GCp[3], bVp[3];
1783 if ((fabs(bVp[0]) > 1e-9) || (fabs(bVp[1]) > 1e-9) ||
1784 (fabs(bVp[2]) > 1e-9)) {
1787 search_interval.
left=base_angle;
1788 search_interval.
right=base_angle;
1790 search_interval.
left = -M_PI;
1791 search_interval.
right = M_PI;
1797 search_interval, search_interval_tree_buffer);
1800 *num_overlap_cells +
1803 for (
size_t i = 0; i < search_interval_tree_buffer->
num_overlaps;
1805 (*overlap_cells)[(*num_overlap_cells)+i] =
1810 *num_overlap_cells += search_interval_tree_buffer->
num_overlaps;
1815 *num_overlap_cells + node->
I_size);
1816 memcpy(*overlap_cells + *num_overlap_cells, node->
I.
list,
1817 node->
I_size *
sizeof(**overlap_cells));
1818 *num_overlap_cells += node->
I_size;
1825 size_t count,
size_t ** cells,
size_t * num_cells_per_coordinate) {
1829 size_t * temp_search_results = NULL;
1830 size_t temp_search_results_array_size = 0;
1831 size_t num_temp_search_results = 0;
1833 struct overlaps search_interval_tree_buffer = {0, 0, NULL};
1836 num_cells_per_coordinate, 0, count *
sizeof(*num_cells_per_coordinate));
1837 size_t * cells_ = NULL;
1838 size_t cells_array_size = 0;
1839 size_t num_cells = 0;
1842 for (
size_t i = 0; i < count; ++i) {
1844 double * curr_coordinates_xyz = &(coordinates_xyz[i][0]);
1846 num_temp_search_results = 0;
1848 double gc_norm_vector[3] = {0.0,0.0,1.0};
1850 search_point(base_node, curr_coordinates_xyz, &temp_search_results,
1851 &temp_search_results_array_size, &num_temp_search_results,
1852 &search_interval_tree_buffer, gc_norm_vector);
1855 cells_, cells_array_size, num_cells + num_temp_search_results);
1857 memcpy(cells_ + num_cells, temp_search_results,
1858 num_temp_search_results *
sizeof(*temp_search_results));
1859 num_cells_per_coordinate[i] = num_temp_search_results;
1860 num_cells += num_temp_search_results;
1863 free(temp_search_results);
1864 free(search_interval_tree_buffer.
overlap_iv);
1866 *cells =
xrealloc(cells_, num_cells *
sizeof(*cells_));
1871 size_t count,
size_t ** cells,
size_t * num_cells_per_bnd_circle) {
1875 size_t * temp_search_results = NULL;
1876 size_t temp_search_results_array_size = 0;
1877 size_t num_temp_search_results = 0;
1879 struct overlaps search_interval_tree_buffer = {0, 0, NULL};
1882 num_cells_per_bnd_circle, 0, count *
sizeof(*num_cells_per_bnd_circle));
1883 size_t * cells_ = NULL;
1884 size_t cells_array_size = 0;
1885 size_t num_cells = 0;
1888 for (
size_t i = 0; i < count; ++i) {
1890 num_temp_search_results = 0;
1892 double gc_norm_vector[3] = {0.0,0.0,1.0};
1895 &temp_search_results_array_size, &num_temp_search_results,
1896 &search_interval_tree_buffer, gc_norm_vector);
1899 cells_, cells_array_size, num_cells + num_temp_search_results);
1901 memcpy(cells_ + num_cells, temp_search_results,
1902 num_temp_search_results *
sizeof(*temp_search_results));
1903 num_cells_per_bnd_circle[i] = num_temp_search_results;
1904 num_cells += num_temp_search_results;
1907 free(temp_search_results);
1908 free(search_interval_tree_buffer.
overlap_iv);
1910 *cells =
xrealloc(cells_, num_cells *
sizeof(*cells_));
1946 if (search == NULL)
return;
1955 if (search == NULL)
return;
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
static struct sin_cos_angle get_vector_angle_2(double const a[3], double const b[3])
static double clamp_abs_one(double val)
static const struct sin_cos_angle SIN_COS_ZERO
static int points_are_identically(double const *a, double const *b)
static const struct sin_cos_angle SIN_COS_M_PI
static struct sin_cos_angle sum_angles_no_check(struct sin_cos_angle a, struct sin_cos_angle b)
static void crossproduct_kahan(double const a[], double const b[], double cross[])
static const struct sin_cos_angle SIN_COS_M_PI_2
static int compare_angles(struct sin_cos_angle a, struct sin_cos_angle b)
static void normalise_vector(double v[])
static double get_vector_angle(double const a[3], double const b[3])
static struct sin_cos_angle sin_cos_angle_new(double sin, double cos)
void yac_search_interval_tree(struct interval_node tree[], size_t num_nodes, struct interval query, struct overlaps *overlaps)
void yac_generate_interval_tree(struct interval_node intervals[], size_t num_nodes)
#define xrealloc(ptr, size)
static int leaf_contains_matching_point(struct point_id_xyz *points, size_t num_points, double coordinate_xyz[3], size_t **local_point_ids, size_t *local_point_ids_array_size, double(**result_coordinates_xyz)[3], size_t *result_coordinates_xyz_array_size, size_t total_num_local_point_ids, size_t *num_local_point_ids)
static size_t initial_point_bnd_search_NNN(size_t n, struct point_id_xyz *points, size_t num_points, double *point_coordinates_xyz, struct point_id_xyz_angle **results, size_t *results_array_size)
static void search_point(struct sphere_part_node *node, double point[], size_t **overlap_cells, size_t *overlap_cells_array_size, size_t *num_overlap_cells, struct overlaps *search_interval_tree_buffer, double prev_gc_norm_vector[])
static int compare_point_idx_xyz(void const *a, void const *b)
static size_t swap_node_type(struct temp_partition_data *part_data, size_t i, int node_type, size_t begin, size_t end)
static void check_leaf_NN(struct point_id_xyz *points, size_t num_points, double *point_coordinates_xyz, struct sin_cos_angle *best_angle, double(**result_coordinates_xyz)[3], size_t *result_coordinates_xyz_array_size, size_t **local_point_ids, size_t *local_point_ids_array_size, size_t total_num_local_point_ids, size_t *num_local_point_ids)
static struct point_id_xyz * get_unique_points(size_t *num_points, yac_const_coordinate_pointer coordinates_xyz, yac_int const *ids, int const *mask)
void yac_bnd_sphere_part_search_do_bnd_circle_search(struct bnd_sphere_part_search *search, struct bounding_circle *bnd_circles, size_t count, size_t **cells, size_t *num_cells_per_bnd_circle)
static void compute_gc_norm_vector(void *coords_data, size_t coords_size, size_t coords_count, double prev_gc_norm_vector[], double gc_norm_vector[])
static void point_search_NN(struct bounding_circle *bnd_circle, double(**result_coordinates_xyz)[3], size_t *result_coordinates_xyz_array_size, size_t **local_point_ids, size_t *local_point_ids_array_size, size_t total_num_local_point_ids, size_t *num_local_point_ids, double *dot_stack, struct point_sphere_part_node **node_stack, int *flags, size_t curr_tree_depth)
struct bnd_sphere_part_search * yac_bnd_sphere_part_search_new(struct bounding_circle *circles, size_t num_circles)
static void search_bnd_circle_I_node(struct sphere_part_node *node, struct bounding_circle bnd_circle, size_t **restrict overlap_cells, size_t *overlap_cells_array_size, size_t *restrict num_overlap_cells, struct overlaps *search_interval_tree_buffer, double prev_gc_norm_vector[])
static void search_big_bnd_circle(struct sphere_part_node *node, struct bounding_circle bnd_circle, size_t **restrict overlap_cells, size_t *overlap_cells_array_size, size_t *restrict num_overlap_cells, struct overlaps *search_interval_tree_buffer, double prev_gc_norm_vector[])
TODO change to iterative implementation and allocate overlap_cells first.
static void sort_partition_data(struct temp_partition_data *part_data, size_t I_FULL_size, size_t I_size, size_t U_size, size_t T_size)
static void partition_data(size_t *local_cell_ids, struct temp_partition_data *part_data, size_t num_cell_ids, size_t threshold, struct sphere_part_node *parent_node, double prev_gc_norm_vector[])
void yac_delete_point_sphere_part_search(struct point_sphere_part_search *search)
struct point_sphere_part_search * yac_point_sphere_part_search_mask_new(size_t num_points, yac_const_coordinate_pointer coordinates_xyz, yac_int const *ids, int const *mask)
void yac_bnd_sphere_part_search_delete(struct bnd_sphere_part_search *search)
static struct point_sphere_part_node * partition_point_data(struct point_id_xyz *points, size_t num_points, size_t threshold, double prev_gc_norm_vector[], size_t curr_tree_depth, size_t *max_tree_depth)
struct point_sphere_part_search * yac_point_sphere_part_search_new(size_t num_points, yac_const_coordinate_pointer coordinates_xyz, yac_int const *ids)
static struct sin_cos_angle check_leaf_NNN(size_t n, double *point_coordinates_xyz, struct point_id_xyz *points, size_t num_points, struct point_id_xyz_angle **results, size_t *results_array_size, size_t *num_results, struct sin_cos_angle curr_angle)
static struct sphere_part_node * get_sphere_part_node()
static void free_sphere_part_tree(struct sphere_part_node tree)
static int compare_point_id_xyz_angle(const void *a, const void *b)
void yac_bnd_sphere_part_search_do_point_search(struct bnd_sphere_part_search *search, yac_coordinate_pointer coordinates_xyz, size_t count, size_t **cells, size_t *num_cells_per_coordinate)
int yac_point_sphere_part_search_bnd_circle_contains_points(struct point_sphere_part_search *search, struct bounding_circle circle)
static int point_check_bnd_circle(struct point_sphere_part_node *node, struct bounding_circle bnd_circle)
static void search_small_bnd_circle(struct sphere_part_node *node, struct bounding_circle bnd_circle, size_t **restrict overlap_cells, size_t *overlap_cells_array_size, size_t *restrict num_overlap_cells, struct overlaps *search_interval_tree_buffer, double prev_gc_norm_vector[])
static void swap_partition_data(struct temp_partition_data *a, struct temp_partition_data *b)
static void init_sphere_part_node(struct sphere_part_node *node)
static void search_bnd_circle(struct sphere_part_node *node, struct bounding_circle bnd_circle, size_t **restrict overlap_cells, size_t *overlap_cells_array_size, size_t *restrict num_overlap_cells, struct overlaps *search_interval_tree_buffer, double prev_gc_norm_vector[])
void yac_point_sphere_part_search_NN(struct point_sphere_part_search *search, size_t num_points, double(*coordinates_xyz)[3], double *cos_angles, double(**result_coordinates_xyz)[3], size_t *result_coordinates_xyz_array_size, size_t **local_point_ids, size_t *local_point_ids_array_size, size_t *num_local_point_ids)
void yac_point_sphere_part_search_NNN(struct point_sphere_part_search *search, size_t num_points, double(*coordinates_xyz)[3], size_t n, double **cos_angles, size_t *cos_angles_array_size, double(**result_coordinates_xyz)[3], size_t *result_coordinates_xyz_array_size, size_t **local_point_ids, size_t *local_point_ids_array_size, size_t *num_local_point_ids)
static void free_point_sphere_part_tree(struct point_sphere_part_node *tree)
static int compare_points_int32_coord(const void *a, const void *b)
static void point_search_NNN(size_t n, double *point_coordinates_xyz, struct point_id_xyz_angle **results, size_t *results_array_size, size_t *num_results, double *dot_stack, struct point_sphere_part_node **node_stack, int *flags, size_t curr_tree_depth)
algorithm for searching cells and points on a grid
struct sphere_part_node base_node
struct sin_cos_angle inc_angle
angle between the middle point and the boundary of the spherical cap
struct point_id_xyz point
int32_t coordinate_xyz[3]
double coordinates_xyz[3]
struct point_sphere_part_node base_node
struct point_id_xyz * points
struct sin_cos_angle I_angle
struct bounding_circle bnd_circle
struct interval_node * head_node
static struct user_input_data_points ** points
#define YAC_ASSERT(exp, msg)
double const (*const yac_const_coordinate_pointer)[3]
double(* yac_coordinate_pointer)[3]