Skip to content
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

Merged
merged 3 commits into from
Sep 5, 2023
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 107 additions & 23 deletions core/base/kdTree/KDTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Collaborator

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)

int nodeNumber = -1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int &nodeNumber = -1 --> const int &nodeNumber = -1 (unless it is not read only)


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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above const (if indeed read only)

const std::vector<std::vector<dataType>> &weights = {},
const int weight_number = 1);

Expand Down Expand Up @@ -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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same remark as above const int &weightNumber.

int nodeNumber) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same remark as above const int &nodeNumber


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;
Expand All @@ -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;

Expand All @@ -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++) {
Expand All @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weightNumber

}

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++) {
Expand All @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weightNumber

}

return correspondence_map;
Expand All @@ -225,23 +291,35 @@ void ttk::KDTree<dataType, Container>::buildRecursive(
const int &dimension,
KDTree<dataType, Container> *parent,
KDTreeMap &correspondence_map,
const int nodeNumber,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const int &nodeNumber

const int maximumLevel,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const int &maximumLevel

int &createdNumberNode,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const int &createdNumberNode (unless not read-only)

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;

Expand Down Expand Up @@ -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++) {
Expand All @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weightNumber

}

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++) {
Expand All @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weightNumber

}
}

Expand Down Expand Up @@ -414,4 +498,4 @@ void ttk::KDTree<dataType, Container>::recursiveGetKClosest(
k, coordinates, neighbours, costs, weight_index, power);
}
}
}
}
Loading