static int KDTree_report_subtree(struct KDTree* tree, struct Node *node) { int ok; if (Node_is_leaf(node)) { /* report point(s) */ long int i; for (i=node->_start; i<node->_end; i++) { struct DataPoint data_point; data_point=tree->_data_point_list[i]; ok = KDTree_report_point(tree, data_point._index, data_point._coord); if (!ok) return 0; } } else { /* find points in subtrees via recursion */ ok = KDTree_report_subtree(tree, node->_left); if (!ok) return 0; ok = KDTree_report_subtree(tree, node->_right); if (!ok) return 0; } return 1; }
int KDTree_neighbor_search(struct KDTree* tree, float neighbor_radius, struct Neighbor** neighbors) { long int i; int ok; Region_dim=tree->dim; if(tree->_neighbor_list) { free(tree->_neighbor_list); tree->_neighbor_list = NULL; } tree->_neighbor_count=0; /* note the use of r^2 to avoid use of sqrt */ tree->_neighbor_radius=neighbor_radius; tree->_neighbor_radius_sq=neighbor_radius*neighbor_radius; if (Node_is_leaf(tree->_root)) { /* this is a boundary condition */ /* bucket_size>nr of points */ ok = KDTree_search_neighbors_in_bucket(tree, tree->_root); } else { /* "normal" situation */ struct Region *region; /* start with [-INF, INF] */ region= Region_create(NULL, NULL); if (!region) return 0; ok = KDTree__neighbor_search(tree, tree->_root, region, 0); Region_destroy(region); } if (!ok) return 0; *neighbors = NULL; for (i = 0; i < tree->_neighbor_count; i++) { struct Neighbor* neighbor = malloc(sizeof(struct Neighbor)); if (!neighbor) { while(1) { neighbor = *neighbors; if (!neighbor) return 0; *neighbors = neighbor->next; free(neighbor); } } *neighbor = tree->_neighbor_list[i]; neighbor->next = *neighbors; *neighbors = neighbor; } return 1; }
SuffixTreeIndex_T leaf_array_node_func(SuffixTree_T tree, Node_T node, void* vleaf_array, SuffixTreeIndex_T prev_suf_length) { if(node == SuffixTree_get_root(tree)) return 0; size_t edge_length = Node_get_incoming_edge_length(node, tree); size_t current_suf_length = prev_suf_length + edge_length; Node_T* leaf_array = vleaf_array; if(Node_is_leaf(node, tree)) { size_t suffix_start = SuffixTree_get_string_length(tree) - current_suf_length; if(suffix_start + 1 != SuffixTree_get_string_length(tree)) { leaf_array[suffix_start] = node; } } return current_suf_length; }
static int KDTree__neighbor_search(struct KDTree* tree, struct Node *node, struct Region *region, int depth) { struct Node *left, *right; struct Region *left_region = NULL; struct Region *right_region = NULL; int localdim; int intersect; float cut_value; int ok = 1; localdim=depth%tree->dim; left=node->_left; right=node->_right; cut_value = node->_cut_value; /* planes of left and right nodes */ intersect=Region_test_intersect_left(region, cut_value, localdim); if(intersect==1) { left_region = Region_create(region->_left, region->_right); if (!left_region) ok = 0; } else if(intersect==0) { left_region = Region_create_intersect_left(region, cut_value, localdim); if (!left_region) ok = 0; } else if(intersect==-1) /* intersect is -1 if no overlap */ { left_region = NULL; } intersect=Region_test_intersect_right(region, cut_value, localdim); if(intersect==-1) { right_region = Region_create(region->_left, region->_right); if (!right_region) ok = 0; } else if(intersect==0) { right_region = Region_create_intersect_right(region, cut_value, localdim); if (!right_region) ok = 0; } else if(intersect==+1) /* intersect is +1 if no overlap */ { right_region = NULL; } if (ok) { if (!Node_is_leaf(left)) { /* search for pairs in this half plane */ ok = KDTree__neighbor_search(tree, left, left_region, depth+1); } else { ok = KDTree_search_neighbors_in_bucket(tree, left); } } if (ok) { if (!Node_is_leaf(right)) { /* search for pairs in this half plane */ ok = KDTree__neighbor_search(tree, right, right_region, depth+1); } else { ok = KDTree_search_neighbors_in_bucket(tree, right); } } /* search for pairs between the half planes */ if (ok) { ok = KDTree_neighbor_search_pairs(tree, left, left_region, right, right_region, depth+1); } /* cleanup */ Region_destroy(left_region); Region_destroy(right_region); return ok; }
static int KDTree_neighbor_search_pairs(struct KDTree* tree, struct Node *down, struct Region *down_region, struct Node *up, struct Region *up_region, int depth) { int down_is_leaf, up_is_leaf; int localdim; int ok = 1; /* if regions do not overlap - STOP */ if (!down || !up || !down_region || !up_region) { /* STOP */ return ok; } if (Region_test_intersection(down_region, up_region, tree->_neighbor_radius)==0) { /* regions cannot contain neighbors */ return ok; } /* dim */ localdim=depth%tree->dim; /* are they leaves? */ up_is_leaf=Node_is_leaf(up); down_is_leaf=Node_is_leaf(down); if (up_is_leaf && down_is_leaf) { /* two leaf nodes */ ok = KDTree_search_neighbors_between_buckets(tree, down, up); } else { /* one or no leaf nodes */ struct Node *up_right, *up_left, *down_left, *down_right; struct Region *up_left_region = NULL; struct Region *up_right_region = NULL; struct Region *down_left_region = NULL; struct Region *down_right_region = NULL; if (down_is_leaf) { down_left=down; /* make a copy of down_region */ down_left_region= Region_create(down_region->_left, down_region->_right); if (down_left_region==NULL) ok = 0; down_right=NULL; down_right_region=NULL; } else { float cut_value; int intersect; cut_value=down->_cut_value; down_left=down->_left; down_right=down->_right; intersect=Region_test_intersect_left(down_region, cut_value, localdim); if(intersect==1) { down_left_region = Region_create(down_region->_left, down_region->_right); if (down_left_region==NULL) ok = 0; } else if(intersect==0) { down_left_region = Region_create_intersect_left(down_region, cut_value, localdim); if (down_left_region==NULL) ok = 0; } else if(intersect==-1) /* intersect is -1 if no overlap */ { down_left_region = NULL; } intersect=Region_test_intersect_right(down_region, cut_value, localdim); if(intersect==-1) { down_right_region = Region_create(down_region->_left, down_region->_right); if (down_right_region==NULL) ok = 0; } else if(intersect==0) { down_right_region = Region_create_intersect_right(down_region, cut_value, localdim); if (down_right_region==NULL) ok = 0; } else if(intersect==+1) { down_right_region = NULL; } } if (up_is_leaf) { up_left=up; /* make a copy of up_region */ up_left_region= Region_create(up_region->_left, up_region->_right); if (up_left_region==NULL) ok = 0; up_right=NULL; up_right_region=NULL; } else { float cut_value; int intersect; cut_value=up->_cut_value; up_left=up->_left; up_right=up->_right; intersect=Region_test_intersect_left(up_region, cut_value, localdim); if(intersect==1) { up_left_region = Region_create(up_region->_left, up_region->_right); if (up_left_region==NULL) ok = 0; } else if(intersect==0) { up_left_region = Region_create_intersect_left(up_region, cut_value, localdim); if (up_left_region==NULL) ok = 0; } else if(intersect==-1) /* intersect is -1 if no overlap */ { up_left_region = NULL; } intersect=Region_test_intersect_right(up_region, cut_value, localdim); if(intersect==-1) { up_right_region = Region_create(up_region->_left, up_region->_right); if (up_right_region==NULL) ok = 0; } else if(intersect==0) { up_right_region = Region_create_intersect_right(up_region, cut_value, localdim); if (up_right_region==NULL) ok = 0; } else if(intersect==+1) /* intersect is +1 if no overlap */ { up_right_region = NULL; } } if (ok) ok = KDTree_neighbor_search_pairs(tree, up_left, up_left_region, down_left, down_left_region, depth+1); if (ok) ok = KDTree_neighbor_search_pairs(tree, up_left, up_left_region, down_right, down_right_region, depth+1); if (ok) ok = KDTree_neighbor_search_pairs(tree, up_right, up_right_region, down_left, down_left_region, depth+1); if (ok) ok = KDTree_neighbor_search_pairs(tree, up_right, up_right_region, down_right, down_right_region, depth+1); Region_destroy(down_left_region); Region_destroy(down_right_region); Region_destroy(up_left_region); Region_destroy(up_right_region); } return ok; }
static int KDTree_search(struct KDTree* tree, struct Region *region, struct Node *node, int depth) { int current_dim; int ok = 1; if(depth==0) { /* start with [-INF, INF] region */ region = Region_create(NULL, NULL); if (region==NULL) return 0; /* start with root node */ node=tree->_root; } current_dim=depth%tree->dim; if(Node_is_leaf(node)) { long int i; for (i=node->_start; i<node->_end; i++) { struct DataPoint data_point; data_point=tree->_data_point_list[i]; if (Region_encloses(tree->_query_region, data_point._coord)) { /* point is enclosed in query region - report & stop */ ok = KDTree_report_point(tree, data_point._index, data_point._coord); } } } else { struct Node *left_node, *right_node; struct Region *left_region, *right_region; int intersect_left, intersect_right; left_node=node->_left; /* LEFT HALF PLANE */ /* new region */ intersect_left=Region_test_intersect_left(region, node->_cut_value, current_dim); if(intersect_left==1) { left_region = Region_create(region->_left, region->_right); if (left_region) ok = KDTree_test_region(tree, left_node, left_region, depth); else ok = 0; } else if (intersect_left==0) { left_region = Region_create_intersect_left(region, node->_cut_value, current_dim); if (left_region) ok = KDTree_test_region(tree, left_node, left_region, depth); else ok = 0; } /* intersect_left is -1 if no overlap */ /* RIGHT HALF PLANE */ right_node=node->_right; /* new region */ intersect_right=Region_test_intersect_right(region, node->_cut_value, current_dim); if (intersect_right==-1) { right_region = Region_create(region->_left, region->_right); /* test for overlap/inside/outside & do recursion/report/stop */ if (right_region) ok = KDTree_test_region(tree, right_node, right_region, depth); else ok = 0; } else if (intersect_right==0) { right_region = Region_create_intersect_right(region, node->_cut_value, current_dim); /* test for overlap/inside/outside & do recursion/report/stop */ if (right_region) ok = KDTree_test_region(tree, right_node, right_region, depth); else ok = 0; } /* intersect_right is +1 if no overlap */ } Region_destroy(region); return ok; }