-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
change kdTree code to choose the number of leaves #962
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,14 +64,18 @@ namespace ttk { | |
const int &ptNumber, | ||
const int &dimension, | ||
const std::vector<std::vector<dataType>> &weights = {}, | ||
const int weight_number = 1); | ||
const int weight_number = 1, | ||
int nodeNumber = -1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
void buildRecursive(dataType *data, | ||
std::vector<int> &idx_side, | ||
const int &ptNumber, | ||
const int &dimension, | ||
KDTree<dataType, Container> *parent, | ||
KDTreeMap &correspondence_map, | ||
const int nodeNumber, | ||
const int maximumLevel, | ||
int &createdNumberNode, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
const std::vector<std::vector<dataType>> &weights = {}, | ||
const int weight_number = 1); | ||
|
||
|
@@ -146,15 +150,67 @@ typename ttk::KDTree<dataType, Container>::KDTreeMap | |
const int &ptNumber, | ||
const int &dimension, | ||
const std::vector<std::vector<dataType>> &weights, | ||
const int weight_number) { | ||
const int weight_number, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same remark as above |
||
int nodeNumber) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same remark as above |
||
|
||
int createdNumberNode = 1; | ||
int idGenerator = createdNumberNode - 1; | ||
int maximumLevel = 0; | ||
|
||
int correspondence_map_size = 0; | ||
|
||
if(nodeNumber == -1) { | ||
correspondence_map_size = ptNumber; | ||
} else { | ||
correspondence_map_size = nodeNumber; | ||
maximumLevel = ceil(log2(nodeNumber + 1)) - 1; | ||
} | ||
|
||
KDTreeMap correspondence_map(correspondence_map_size); | ||
|
||
KDTreeMap correspondence_map(ptNumber); | ||
// First, perform a argsort on the data | ||
// initialize original index locations | ||
for(int axis = 0; axis < dimension; axis++) { | ||
coords_min_[axis] = std::numeric_limits<dataType>::lowest(); | ||
coords_max_[axis] = std::numeric_limits<dataType>::max(); | ||
dataType x_max = std::numeric_limits<dataType>::lowest(); | ||
dataType x_min = std::numeric_limits<dataType>::max(); | ||
dataType y_max = std::numeric_limits<dataType>::lowest(); | ||
dataType y_min = std::numeric_limits<dataType>::max(); | ||
dataType z_max = std::numeric_limits<dataType>::lowest(); | ||
dataType z_min = std::numeric_limits<dataType>::max(); | ||
|
||
for(int i = 0; i < ptNumber * dimension; i += dimension) { | ||
if(x_max < data[i]) { | ||
x_max = data[i]; | ||
} | ||
if(x_min > data[i]) { | ||
x_min = data[i]; | ||
} | ||
|
||
if(y_max < data[i + 1]) { | ||
y_max = data[i + 1]; | ||
} | ||
if(y_min > data[i + 1]) { | ||
y_min = data[i + 1]; | ||
} | ||
|
||
if(dimension > 2) { | ||
if(z_max < data[i + 2]) { | ||
z_max = data[i + 2]; | ||
} | ||
if(z_min > data[i + 2]) { | ||
z_min = data[i + 2]; | ||
} | ||
} | ||
} | ||
|
||
coords_min_[0] = x_min; | ||
coords_max_[0] = x_max; | ||
coords_min_[1] = y_min; | ||
coords_max_[1] = y_max; | ||
if(dimension > 2) { | ||
coords_min_[2] = z_min; | ||
coords_max_[2] = z_max; | ||
} | ||
|
||
std::vector<int> idx(ptNumber); | ||
for(int i = 0; i < ptNumber; i++) { | ||
idx[i] = i; | ||
|
@@ -164,15 +220,21 @@ typename ttk::KDTree<dataType, Container>::KDTreeMap | |
return data[dimension * i1 + coords_number_] | ||
< data[dimension * i2 + coords_number_]; | ||
}); | ||
int const median_loc = (int)(ptNumber - 1) / 2; | ||
int const median_idx = idx[median_loc]; | ||
correspondence_map[median_idx] = this; | ||
int median_loc = (int)(ptNumber - 1) / 2; | ||
int median_idx = idx[median_loc]; | ||
|
||
for(int axis = 0; axis < dimension; axis++) { | ||
coordinates_[axis] = data[dimension * median_idx + axis]; | ||
} | ||
|
||
id_ = median_idx; | ||
if(nodeNumber == -1) { | ||
correspondence_map[median_idx] = this; | ||
id_ = median_idx; | ||
} else { | ||
correspondence_map[idGenerator] = this; | ||
id_ = idGenerator; | ||
} | ||
|
||
parent_ = nullptr; | ||
level_ = 0; | ||
|
||
|
@@ -189,7 +251,8 @@ typename ttk::KDTree<dataType, Container>::KDTreeMap | |
} | ||
} | ||
|
||
if(idx.size() > 2) { | ||
if(((nodeNumber == -1) && (idx.size() > 2)) | ||
|| ((nodeNumber != -1) && (createdNumberNode < nodeNumber))) { | ||
// Build left leaf | ||
std::vector<int> idx_left(median_loc); | ||
for(int i = 0; i < median_loc; i++) { | ||
|
@@ -199,10 +262,12 @@ typename ttk::KDTree<dataType, Container>::KDTreeMap | |
this->left_ | ||
= std::make_unique<KDTree>(this, (coords_number_ + 1) % dimension, true); | ||
this->left_->buildRecursive(data, idx_left, ptNumber, dimension, this, | ||
correspondence_map, weights, weight_number); | ||
correspondence_map, nodeNumber, maximumLevel, | ||
createdNumberNode, weights, weight_number); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
if(idx.size() > 1) { | ||
if(((nodeNumber == -1) && (idx.size() > 1)) | ||
|| ((nodeNumber != -1) && (createdNumberNode < nodeNumber))) { | ||
// Build right leaf | ||
std::vector<int> idx_right(ptNumber - median_loc - 1); | ||
for(int i = 0; i < ptNumber - median_loc - 1; i++) { | ||
|
@@ -211,7 +276,8 @@ typename ttk::KDTree<dataType, Container>::KDTreeMap | |
this->right_ | ||
= std::make_unique<KDTree>(this, (coords_number_ + 1) % dimension, false); | ||
this->right_->buildRecursive(data, idx_right, ptNumber, dimension, this, | ||
correspondence_map, weights, weight_number); | ||
correspondence_map, nodeNumber, maximumLevel, | ||
createdNumberNode, weights, weight_number); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
return correspondence_map; | ||
|
@@ -225,23 +291,35 @@ void ttk::KDTree<dataType, Container>::buildRecursive( | |
const int &dimension, | ||
KDTree<dataType, Container> *parent, | ||
KDTreeMap &correspondence_map, | ||
const int nodeNumber, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const int maximumLevel, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
int &createdNumberNode, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const std::vector<std::vector<dataType>> &weights, | ||
const int weight_number) { | ||
|
||
createdNumberNode++; | ||
int idGenerator = createdNumberNode - 1; | ||
|
||
// First, perform a argsort on the data | ||
sort(idx_side.begin(), idx_side.end(), [&](int i1, int i2) { | ||
return data[dimension * i1 + coords_number_] | ||
< data[dimension * i2 + coords_number_]; | ||
}); | ||
int const median_loc = (int)(idx_side.size() - 1) / 2; | ||
int const median_idx = idx_side[median_loc]; | ||
correspondence_map[median_idx] = this; | ||
int median_loc = (int)(idx_side.size() - 1) / 2; | ||
int median_idx = idx_side[median_loc]; | ||
|
||
for(int axis = 0; axis < dimension; axis++) { | ||
coordinates_[axis] = data[dimension * median_idx + axis]; | ||
} | ||
|
||
id_ = median_idx; | ||
if(nodeNumber == -1) { | ||
correspondence_map[median_idx] = this; | ||
id_ = median_idx; | ||
} else { | ||
correspondence_map[idGenerator] = this; | ||
id_ = idGenerator; | ||
} | ||
|
||
parent_ = parent; | ||
level_ = parent->level_ + 1; | ||
|
||
|
@@ -278,7 +356,9 @@ void ttk::KDTree<dataType, Container>::buildRecursive( | |
= parent_->coordinates_[parent_->coords_number_]; | ||
} | ||
|
||
if(idx_side.size() > 2) { | ||
if(((nodeNumber == -1) && (idx_side.size() > 2)) | ||
|| ((nodeNumber != -1) && (level_ < maximumLevel) | ||
&& (createdNumberNode < nodeNumber))) { | ||
// Build left leaf | ||
std::vector<int> idx_left(median_loc); | ||
for(int i = 0; i < median_loc; i++) { | ||
|
@@ -288,10 +368,13 @@ void ttk::KDTree<dataType, Container>::buildRecursive( | |
this->left_ | ||
= std::make_unique<KDTree>(this, (coords_number_ + 1) % dimension, true); | ||
this->left_->buildRecursive(data, idx_left, ptNumber, dimension, this, | ||
correspondence_map, weights, weight_number); | ||
correspondence_map, nodeNumber, maximumLevel, | ||
createdNumberNode, weights, weight_number); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
if(idx_side.size() > 1) { | ||
if(((nodeNumber == -1) && (idx_side.size() > 1)) | ||
|| ((nodeNumber != -1) && (level_ < maximumLevel) | ||
&& (createdNumberNode < nodeNumber))) { | ||
// Build right leaf | ||
std::vector<int> idx_right(idx_side.size() - median_loc - 1); | ||
for(unsigned int i = 0; i < idx_side.size() - median_loc - 1; i++) { | ||
|
@@ -300,7 +383,8 @@ void ttk::KDTree<dataType, Container>::buildRecursive( | |
this->right_ | ||
= std::make_unique<KDTree>(this, (coords_number_ + 1) % dimension, false); | ||
this->right_->buildRecursive(data, idx_right, ptNumber, dimension, this, | ||
correspondence_map, weights, weight_number); | ||
correspondence_map, nodeNumber, maximumLevel, | ||
createdNumberNode, weights, weight_number); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
} | ||
|
||
|
@@ -414,4 +498,4 @@ void ttk::KDTree<dataType, Container>::recursiveGetKClosest( | |
k, coordinates, neighbours, costs, weight_index, power); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend to take the habit to use references for function parameters (unless pointers are necessary), even for integers.
const int weight_number = 1
->const int &weightNumber = 1
(also, we usually don't use underscores for names in TTK, but a camel wording)