Removed backup files

This commit is contained in:
Garry Boyer
2007-05-07 18:49:08 +00:00
parent 29c5d4b63a
commit 5c19e859c5
17 changed files with 0 additions and 3446 deletions
-214
View File
@@ -1,214 +0,0 @@
/*
* =====================================================================================
*
* Filename: ball_pivoter.h
*
* Description:
*
* Version: 1.0
* Created: 04/28/2007 04:15:36 PM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#ifdef BALL_PIVOTER_H_
#define BALL_PIVOTER_H_
#include "loki/Typelist.h"
#include "fastlib/fastlib.h"
#include "dataset/binary_dataset.h"
#include "hyper_ball.h"
template<typename TYPELIST, bool diagnostic>
class BallPivoter {
public:
typedef Loki::TL::TypeAt<TYPELIST, 0>::Result Precision_t;
typedef Loki::TL::TypeAt<TYPELIST, 1>::Result Allocator_t;
typedef Loki::TL::TypeAt<TYPELIST, 2>::Result Metric_t;
typedef HyperBall<TYPELIST, diagnostic> HyperBall_t;
FORBID_COPY(HyperBallPivoter)
struct PivotInfo {
public:
void Init(index_t start, index_t num_of_points, HyperBall_t &box) {
box_.Copy(box_);
start_=start;
num_of_points_=num_of_points;
}
HyperBall_t box_;
Loki::NullType statistics_;
index_t start_;
index_t num_of_points_;
};
Init(BinaryDataset<Precision_t> *data) {
data_=data;
}
pair<PivotInfo*, PivotInfo*> operator()(PivotInfo *pivot) {
index_t left_start = pivot->start_;
index_t right_start = pivot->start_ + pivot->num_of_points_-1;
int32 dimension = data_->get_dimension();
Array_t pivot_left = pivot->box_.get_pivot_left();
Array_t pivot_right = pivot->box_.get_pivot_right();
Precision_t *point_left = data->At(left_start);
Precision_t *point_right = data->At(right_start);
index_t left_points=0;
index_t right_points=0;
HyperBall_t ball_left, ball_right;
ball_left.Init(dimension);
ball_right.Init(dimension);
while (true) {
while (left_points < pivot->num_of_points_ &&
IsInLeftPivot(point_left, ball_left, ball_right, dimension)) {
UpdateHyperBall(point_left, ball_left);
left_points++;
point_left = data->At(left_start+left_points);
}
if (point_left > point_right || left_points == pivot->num_of_points_) {
break;
}
while (right_points < pivot->num_of_points_ &&
!IsInLeftPivot(point_right, ball_left, ball_right, dimension)) {
UpdateHyperBall(point_right, ball_right);
right_points++;
point_right = data->At(right_start - right_points);
}
if (point_left > point_right || right_points == pivot->num_of_points_) {
break;
}
data->Swap(left_start+left_points, right_start - right_points);
}
DEBUG_ASSERT(left_points>0);
DEBUG_ASSERT(right_points>0);
DEBUG_ASSERT(left_points+right_points == right_start - left_start+1);
NormalizeHyperBall(ball_left, left_points);
NormalizeHyperBall(ball_right, right_points);
FindPivotPoints(data, ball_left, left_start, left_points);
FindPivotPoints(data, ball_right, left_start+left_points, right_points);
PivotInfo* node_pv_left = new PivotInfo();
node_pv_left->Init(left_start, left_points, ball_left);
PivotInfo* node_pv_right = new PivotInfo();
node_pv_right->Init(left_start+left_points, right_points, ball_right);
return make_pair(node_pv_left, node_pv_right);
}
PivotInfo *operator()(index_t num_of_points) {
// make the parent
HyperBall_t ball;
ball.Init(data_->get_dimension());
for(index_t i=0; i<num_of_points; i++) {
UpdateHyperBall(data->At(i), ball);
}
NormalizeHyperBall(ball, num_of_points);
FindPivotPoints(ball, 0, num_of_points);
PivotInfo *pv = new PivoInfo();
pv->Init(0, num_of_points, ball);
return pv;
}
private:
BinaryDataset<Precision_t> *data_;
void FindPivotPoints(HyperBall_t &ball,
index_t start,
index_t num_of_points) {
DEBUG_ASSERT(num_of_points>0);
Precision_t radious=0;
Precision_t max_distance=0;
index_t furthest_point_index = 0;
int32 dimension = data->get_dimension();
index_t random_index = index_t(num_of_points*1.0
*rand()/RAND_MAX)+start;
for(index_t i=start; i< start+num_of_points; i++) {
Precision_t distance1 = Metric_t::Distance(pivot.center_,
data->At(i), dimension);
Precision_t distance = Metric_t::Distance(data->At(random_index),
data->At(i), dimension);
if (distance1 > radious) {
radious = distance1;
}
if (distance>max_distance) {
furthest_point_index=i;
max_distance=distance;
}
}
ball.set_radious(radious);
ball.get_pivot_left().Copy(data->At(furthest_point_index), dimension);
max_distance = 0;
for(index_t i=start; i< start+num_of_points; i++) {
Precision_t distance = Metric_t::Distance(pivot.left_,
data->At(i),
dimension);
if (distance > max_distance) {
furthest_point_index = i;
max_distance=distance;
}
}
ball.get_pivot_right().Copy(data->At(furthest_point_index), dimension);
DEBUG_ASSERT(Metric_t::Distance(pivot.left_, pivot.right_, dimension)>0);
}
template<typename POINTTYPE>
void UpdateHyperBall(POINTTYPE point,
HyperBall_T &ball) {
Metric_t::Addition(ball.get_center(), ball.get_center(),
point, data.get_dimension());
}
__TEMPLATE__
void __PivotPolicy__::NormalizeHyperBall(HyperBall_t &ball,
index_t num_of_points) {
Metric_t::Scale(ball.get_center(), ball.get_center(),
1.0/num_of_points, data->get_dimension());
}
template<typename POINTTYPE>
pair<Array_t, Precision_t> FindFurthestPoint(POINTTYPE point,
index_t start,
index_t num_of_points) {
Precision_t radious=0;
index_t furthest_point_index;
Array_t furthest_point(dimension);
for(index_t i=start; i<start+num_of_points; i++) {
Precision_t distance = Metric_t::Distance(point, data->At(i), dimension);
if (distance > radious) {
radious = distance;
furthest_point_index = i;
}
}
furthest_point.DeepCopy(data->At(furthest_point_index), dimension);
return make_pair(furthest_point, radious);
}
__TEMPLATE__
template<typename POINTTYPE>
bool __PivotPolicy__::IsInLeftPivot(Precision_t *point, POINTTYPE left,
POINTTYPE right,
int32 dimension) {
Precision_t left_distance = Metric_t::Distance(point, left, dimension);
Precision_t right_distance = Metric_t::Distance(point, right, dimension);
if (left_distance < right_distance) {
return true;
}
return false;
}
};
#endif // BALL_PIVOTER
-191
View File
@@ -1,191 +0,0 @@
/*
* =====================================================================================
*
* Filename: tree.h
*
* Description: A generic multidimensional binary tree. Currently tested under
* kd-nodes and ball-nodes
*
* Version: 2.0
* Created: 02/09/2007 08:25:15 PM EST
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: This material is property of Georgia Tech Fastlab-ESP Lab,
* and it is not for distribution
*
* =====================================================================================
*/
#ifndef BINARY_TREE_H_
#define BINARY_TREE_H_
#include <stdio.h>
#include <string>
#include <errno.h>
#include <string.h>
#include <limits>
#include <vector>
#include <list>
#include "fastlib/fastlib.h"
#include "node.h"
#include "show_progress.h"
using namespace std;
template<typename TYPELIST, bool diagnostic>
class BinaryTree {
public:
typedef typename TYPELIST::Precision_t Precision_t;
typedef typename TYPELIST::Allocator_t Allocator_t;
typedef typename TYPELIST::Metric_t Metric_t;
typedef typename TYPELIST::BoundingBox_t BoundingBox_t;
typedef typename TYPELIST::NodeCachedStatistics_t NodeCachedStatistics_t;
typedef typename TYPELIST::PointIdDiscriminator_t PointIdDiscriminator_t;
typedef typename TYPELIST::Pivot_t Pivot_t;
typedef typename Allocator_t::template ArrayPtr<Precision_t> Array_t;
typedef Node<TYPELIST, diagnostic> Node_t;
typedef typename Allocator_t::template Ptr<Node_t> NodePtr_t;
typedef typename Allocator_t::template Ptr<NodePtr_t> NodePtrPtr_t;
typedef Point<Precision_t, Allocator_t> Point_t;
typedef typename Node_t::NNResult Result_t;
typedef BinaryTree<TYPELIST, diagnostic> BinaryTree_t;
typedef typename Pivot_t::PivotInfo PivotInfo_t;
// For testing purposes only
template<typename, bool >friend class BinaryTreeTest;
class OutPutAllocator {
public:
OutPutAllocator() {
num_=0;
}
void set_ptr(Result_t *ptr) {
ptr_=ptr;
}
Result_t *get_ptr() {
return ptr_;
}
Result_t *Allocate(int32 num_of_points, int32 knns) {
Result_t *result=ptr_+num_;
num_+=knns*num_of_points;
return result;
}
private:
Result_t *ptr_;
index_t num_;
};
BinaryTree();
~BinaryTree();
void Init(BinaryDataset<Precision_t> *data);
void Destruct() {}
// Call this function to build Depth first a tree
void BuildDepthFirst();
void BuildDepthFirst(NodePtr_t &ptr, PivotInfo_t *pivot);
void BuildBreadthFirst();
void BuildBreadthFirst(
list<pair<NodePtrPtr_t, PivotInfo_t *> > &fifo);
// Builds tree k depth first. It builds all the subtrees depth first up to k level
void BuildKDepthFirst();
template<typename POINTTYPE, typename NEIGHBORTYPE>
void NearestNeighbor(POINTTYPE test_point,
vector<pair<Precision_t, Point_t> > *nearest_point,
NEIGHBORTYPE range);
// This is the core function doing the recursion, Use that only if you want
// to start the search from a particular node and not the parent
template<typename POINTTYPE, typename NEIGHBORTYPE>
void NearestNeighbor(NodePtr_t ptr,
POINTTYPE &test_point,
vector<pair<Precision_t, Point_t> > *nearest_point,
NEIGHBORTYPE range,
bool &found);
// This is the duall tree nearest neighbors method, again it works
// for all cases k nearest/ range nearest
template<typename NEIGHBORTYPE>
void AllNearestNeighbors(NodePtr_t query,
NEIGHBORTYPE range);
template<typename NEIGHBORTYPE>
void AllNearestNeighbors(NodePtr_t query,
NodePtr_t reference,
NEIGHBORTYPE range,
Precision_t distance);
void InitAllKNearestNeighborOutput(string file, int32 knns);
void CloseAllKNearestNeighborOutput(int32 knns);
void InitAllKNearestNeighborOutput(NodePtr_t ptr,
int32 knns);
void InitAllRangeNearestNeighborOutput(string file);
void InitAllRangeNearestNeighborOutput(NodePtr_t ptr,
FILE *fp);
void CloseAllRangeNearestNeighborOutput();
// Print the tree depth first
void Print();
void RecursivePrint(NodePtr_t ptr);
// Resets the counters of the tree that keep the statistics of search
void ResetCounters() {
computations_.Reset();
}
string Statistics();
string Computations();
void set_log_file(const string &log_file);
int32 get_current_level() {
return current_level_;
};
uint64 get_num_of_points(){
return num_of_points_;
}
NodePtr_t get_parent() {
return parent_;
}
void set_discriminator(PointIdDiscriminator_t *disc) {
discriminator_.reset(disc);
}
void set_max_points_on_leaf(index_t max_points_on_leaf) {
max_points_on_leaf_=max_points_on_leaf;
}
index_t get_max_points_on_leaf() {
return max_points_on_leaf_;
}
private:
// Maximum number of points on a leaf
index_t max_points_on_leaf_;
// Parent/Root
NodePtr_t parent_;
// Source of data
BinaryDataset<Precision_t> *data_;
// Total number of points on the tree
index_t num_of_points_;
// Number of Leafs on the tree
index_t num_of_leafs_;
// Number of nodes (incuding leafs)
index_t node_id_;
// Current level of tree while we build it
index_t current_level_;
// Maximum depth of the tree
index_t max_depth_;
// Minimum depth of the tree
index_t min_depth_;
// Dimensionality of points
int32 dimension_;
// Total number of points visited during search
index_t total_nodes_visited_;
// Structure for keeping statistics on the comparisons and distances computed
// during search
ComputationsCounter<diagnostic> computations_;
// total number of nodes visited
index_t total_points_visited_;
// used for visualization of progress during tree build
ShowProgress progress_;
bool log_progress_;
// Output file for All nearest neighbors
OutPutAllocator all_nn_out_;
FILE *log_file_ptr_;
string log_file_;
// This is usefull for our timit experiments
PointIdDiscriminator_t discriminator_;
// Does all the partitioning for the tree
Pivot_t pivoter_;
};
#include "binary_tree_impl.h"
#endif /*BINARY_TREE_H_*/
-525
View File
@@ -1,525 +0,0 @@
#ifndef BINARY_TREE_IMPL_H_
#define BINARY_TREE_IMPL_H_
#define TEMPLATE__ \
template<typename TYPELIST, bool diagnostic>
#define TREE__ BinaryTree<TYPELIST, diagnostic>
// Straight forward implemantation of the algorithms as described in Andrew Moore's
// paper. For more information regarding traits of nearest neighbors look at
// traits_nearest_neighbor.h file
TEMPLATE__
void TREE__::Init(BinaryDataset<Precision_t> *data) {
data_ = data;
dimension_ = data->get_dimension();
num_of_points_ = data->get_num_of_points();
node_id_=0;
num_of_leafs_=0;
current_level_=0;
max_depth_ = 0;
min_depth_ = numeric_limits<index_t>::max();
max_points_on_leaf_ = 30;
log_progress_=true;
pivoter_.Init(data_);
}
TEMPLATE__
TREE__::~BinaryTree(){
}
TEMPLATE__
void TREE__::BuildBreadthFirst() {
progress_.Reset();
total_points_visited_ = 0;
list<pair<NodePtrPtr_t, PivotInfo_t *> > fifo;
PivotInfo_t *pivot = pivoter_(num_of_points_);
parent_.Reset(new Node_t());
parent_->Init(pivot->box_,
pivot->statistics_,
node_id_,
pivot->num_of_points_);
node_id_++;
pair<PivotInfo_t*, PivotInfo_t*> pivot_pair;
pivot_pair = pivoter_(pivot);
delete pivot;
fifo.push_front(make_pair(parent_->get_left().Reference(), pivot_pair.first));
fifo.push_front(make_pair(parent_->get_right().Reference(), pivot_pair.second));
current_level_ =1;
BuildBreadthFirst(fifo);
if (log_progress_==true) {
printf("\n");
}
}
TEMPLATE__
void TREE__::BuildBreadthFirst(
list<pair<typename TREE__::NodePtrPtr_t,
typename TREE__::PivotInfo_t *> > &fifo) {
pair<PivotInfo_t*, PivotInfo_t*> pivot_pair;
while (!fifo.empty()) {
pair<NodePtrPtr_t, PivotInfo_t*> fifo_pair;
fifo_pair = fifo.back();
fifo.pop_back();
if (fifo_pair.second->num_of_points_ > max_points_on_leaf_) {
(*fifo_pair.first).Reset(new Node_t());
(*fifo_pair.first)->Init(fifo_pair.second->box_,
fifo_pair.second->statistics_,
node_id_,
fifo_pair.second->num_of_points_);
node_id_++;
pivot_pair = pivoter_(fifo_pair.second);
delete fifo_pair.second;
fifo.push_front(make_pair((*fifo_pair.first)->get_left().Reference(),
pivot_pair.first));
fifo.push_front(make_pair((*fifo_pair.first)->get_right().Reference(),
pivot_pair.second));
} else {
if (log_progress_==true) {
total_points_visited_ += fifo_pair.second->num_of_points_;
progress_.Show(total_points_visited_, get_num_of_points());
}
(*fifo_pair.first).Reset(new Node_t());
(*fifo_pair.first)->Init(fifo_pair.second->box_,
fifo_pair.second->statistics_,
node_id_,
fifo_pair.second->start_,
fifo_pair.second->num_of_points_,
dimension_,
data_);
num_of_leafs_++;
node_id_++;
}
}
}
TEMPLATE__
void TREE__::BuildDepthFirst() {
total_points_visited_ = 0;
min_depth_=numeric_limits<index_t>::max();
max_depth_=0;
current_level_=0;
progress_.Reset();
BuildDepthFirst(parent_, pivoter_(num_of_points_));
if (log_progress_==true) {
printf("\n");
}
}
TEMPLATE__
void TREE__::BuildDepthFirst(typename TREE__::NodePtr_t &ptr,
typename TREE__::PivotInfo_t *pivot_info) {
pair<PivotInfo_t *, PivotInfo_t *> pivot_pair;
if (pivot_info->num_of_points_ > max_points_on_leaf_) {
ptr.Reset(new Node_t());
ptr->Init(pivot_info->box_,
pivot_info->statistics_,
node_id_,
pivot_info->num_of_points_);
node_id_++;
pivot_pair = pivoter_(pivot_info);
// There is a case where on all the points are the same
// so pivoting returns 0 points on the left side
// In that case we create a gigantic leaf
if (pivot_pair.first->num_of_points_==0) {
if (log_progress_==true) {
total_points_visited_ +=pivot_pair.second->num_of_points_;
progress_.Show(total_points_visited_, get_num_of_points());
}
if (current_level_ > max_depth_) {
max_depth_=current_level_;
}
if (current_level_ < min_depth_) {
min_depth_=current_level_;
}
ptr.Reset(new Node_t());
ptr->Init(pivot_pair.second->box_,
pivot_pair.second->statistics_,
node_id_,
pivot_pair.second->start_,
pivot_pair.second->num_of_points_,
dimension_,
data_);
node_id_++;
num_of_leafs_++;
delete pivot_info;
delete pivot_pair.first;
delete pivot_pair.second;
return;
}
delete pivot_info;
current_level_++;
BuildDepthFirst(ptr->get_left(), pivot_pair.first);
BuildDepthFirst(ptr->get_right(), pivot_pair.second);
current_level_--;
} else {
if (log_progress_==true) {
total_points_visited_ += pivot_info->num_of_points_;
progress_.Show(total_points_visited_, get_num_of_points());
}
if (current_level_ > max_depth_) {
max_depth_=current_level_;
}
if (current_level_ < min_depth_) {
min_depth_=current_level_;
}
ptr.Reset(new Node_t());
ptr->Init(pivot_info->box_,
pivot_info->statistics_,
node_id_,
pivot_info->start_,
pivot_info->num_of_points_,
dimension_,
data_);
node_id_++;
num_of_leafs_++;
delete pivot_info;
}
}
// This function will return any of the nearest neighbors
// k nearest, range nearest or just nearest
TEMPLATE__
template<typename POINTTYPE, typename NEIGHBORTYPE>
void TREE__::NearestNeighbor(POINTTYPE test_point,
vector<pair<typename TREE__::Precision_t,
typename TREE__::Point_t> > *nearest_point,
NEIGHBORTYPE range) {
bool found = false;
NearestNeighbor(parent_,
test_point,
nearest_point,
range,
found);
}
TEMPLATE__
template<typename POINTTYPE, typename NEIGHBORTYPE>
void TREE__::NearestNeighbor(NodePtr_t ptr,
POINTTYPE &test_point,
vector<pair<typename TREE__::Precision_t,
typename TREE__::Point_t> > *nearest_point,
NEIGHBORTYPE range,
bool &found) {
computations_.UpdateComparisons();
Precision_t max_distance;
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==true) {
max_distance=range;
}
if (!ptr->IsLeaf()){
computations_.UpdateComparisons();
pair<NodePtr_t, NodePtr_t> child_pair =
ptr->ClosestChild(test_point, dimension_, computations_);
NearestNeighbor(child_pair.first, test_point, nearest_point,
range, found);
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==false) {
max_distance=nearest_point->back().first;
}
if (child_pair.second->get_box().CrossesBoundaries(test_point,
dimension_,
max_distance,
computations_)) {
NearestNeighbor(child_pair.second,
test_point,
nearest_point,
range, found);
}
if (found == true) {
return;
} else {
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==false) {
max_distance=nearest_point->back().first;
}
found = ptr->get_box().IsWithin(test_point,
dimension_,
max_distance,
computations_)==0;
if (found == true) {
return;
}
}
} else {
ptr->FindNearest(test_point, *nearest_point,
range, dimension_,
discriminator_,
computations_);
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==false) {
max_distance=nearest_point->back().first;
}
found = ptr->get_box().IsWithin(test_point, dimension_,
max_distance,
computations_);
}
}
TEMPLATE__
template<typename NEIGHBORTYPE>
void TREE__::AllNearestNeighbors(typename TREE__::NodePtr_t query,
NEIGHBORTYPE range) {
ResetCounters();
Precision_t distance = numeric_limits<Precision_t>::max();
progress_.Reset();
AllNearestNeighbors(query, parent_, range, distance);
total_points_visited_=0;
}
TEMPLATE__
template<typename NEIGHBORTYPE >
void TREE__::AllNearestNeighbors(typename TREE__::NodePtr_t query,
typename TREE__::NodePtr_t reference,
NEIGHBORTYPE range,
typename TREE__::Precision_t distance) {
if (distance > query->get_min_dist_so_far()) {
return ;
} else {
if (query->IsLeaf() && reference->IsLeaf()) {
Precision_t max_distance=numeric_limits<Precision_t>::max();
reference->FindAllNearest(query,
max_distance,
range,
dimension_,
discriminator_,
computations_);
query->set_min_dist_so_far(max_distance);
} else {
if (query->IsLeaf() && !reference->IsLeaf()) {
pair<pair<NodePtr_t, Precision_t>,
pair<NodePtr_t, Precision_t> > closest_child;
closest_child = query->ClosestNode(reference->get_left(),
reference->get_right(),
dimension_,
computations_);
AllNearestNeighbors(query,
closest_child.first.first, // child
range, // range
closest_child.first.second // distance of query
// from the reference child
);
AllNearestNeighbors(query, closest_child.second.first,
range, closest_child.second.second);
} else {
if (!query->IsLeaf() && reference->IsLeaf()) {
pair<pair<NodePtr_t, Precision_t>,
pair<NodePtr_t, Precision_t> > closest_child;
closest_child = reference->ClosestNode(query->get_left(),
query->get_right(),
dimension_,
computations_);
AllNearestNeighbors(closest_child.first.first,
reference,
range,
closest_child.first.second);
AllNearestNeighbors(closest_child.second.first,
reference,
range,
closest_child.second.second);
query->set_min_dist_so_far(
std::min<Precision_t>(query->get_min_dist_so_far(),
std::max<Precision_t>(query->get_left()->get_min_dist_so_far(),
query->get_right()->get_min_dist_so_far())));
} else {
if (!query->IsLeaf() && !reference->IsLeaf()) {
pair<pair<NodePtr_t, Precision_t>,
pair<NodePtr_t, Precision_t> > closest_child;
closest_child = query->get_left()->ClosestNode(
reference->get_left(),
reference->get_right(),
dimension_,
computations_);
AllNearestNeighbors(query->get_left(),
closest_child.first.first,
range,
closest_child.first.second);
AllNearestNeighbors(query->get_left(),
closest_child.second.first,
range,
closest_child.second.second);
closest_child = query->get_right()->ClosestNode(
reference->get_left(),
reference->get_right(),
dimension_,
computations_);
AllNearestNeighbors(query->get_right(),
closest_child.first.first,
range,
closest_child.first.second);
AllNearestNeighbors(query->get_right(),
closest_child.second.first,
range,
closest_child.second.second);
query->set_min_dist_so_far(
std::min<Precision_t>(query->get_min_dist_so_far(),
std::max<Precision_t>(query->get_left()->get_min_dist_so_far(),
query->get_right()->get_min_dist_so_far())));
}
}
}
}
}
}
TEMPLATE__
void TREE__::InitAllKNearestNeighborOutput(string file,
int32 knns) {
FILE *fp=fopen(file.c_str(), "w");
const int32 kChunk=8192;
typename Node_t::NNResult *buffer;
buffer=new typename Node_t::NNResult[kChunk*knns];
for(index_t i=0; i<num_of_points_/kChunk; i++) {
fwrite(buffer, sizeof(typename Node_t::NNResult),kChunk*knns, fp );
}
fwrite(buffer, sizeof(typename Node_t::NNResult),
(num_of_points_%kChunk)*knns, fp );
fclose(fp);
delete []buffer;
int fd=open(file.c_str(), O_RDWR);
typename Node_t::NNResult *ptr =(typename Node_t::NNResult *)mmap(NULL,
sizeof(typename Node_t::NNResult)*knns*num_of_points_,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr==MAP_FAILED) {
fprintf(stderr, "Unable to map file: %s", strerror(errno));
assert(false);
}
close(fd);
all_nn_out_.set_ptr(ptr);
InitAllKNearestNeighborOutput(parent_, knns);
}
TEMPLATE__
void TREE__::InitAllKNearestNeighborOutput(typename TREE__::NodePtr_t ptr,
int32 knns) {
if (ptr->IsLeaf()) {
ptr->set_kneighbors(all_nn_out_.Allocate(ptr->get_num_of_points(), knns),
knns);
ptr->InitKNeighbors(knns);
} else {
InitAllKNearestNeighborOutput(ptr->get_left(), knns);
InitAllKNearestNeighborOutput(ptr->get_right(), knns);
}
}
TEMPLATE__
void TREE__::InitAllRangeNearestNeighborOutput(string file) {
FILE *fp=fopen(file.c_str(), "w");
if (fp==NULL) {
FATAL("Cannot open %s, error: %s\n",
file.c_str(),
strerror(errno));
}
parent_->set_range_neighbors(fp);
InitAllRangeNearestNeighborOutput(parent_, fp);
}
TEMPLATE__
void TREE__::InitAllRangeNearestNeighborOutput(
typename TREE__::NodePtr_t ptr,
FILE *fp) {
if (ptr->IsLeaf()) {
ptr->set_range_neighbors(fp);
} else {
InitAllRangeNearestNeighborOutput(ptr->get_left(), fp);
InitAllRangeNearestNeighborOutput(ptr->get_right(), fp);
}
}
TEMPLATE__
void TREE__::CloseAllKNearestNeighborOutput(int32 knns) {
if (munmap(all_nn_out_.get_ptr(),
sizeof(typename Node_t::NNResult)*knns*num_of_points_)<0) {
fprintf(stderr, "Failed to umap file: %s", strerror(errno));
assert(false);
}
}
TEMPLATE__
void TREE__::CloseAllRangeNearestNeighborOutput() {
fclose(parent_->get_range_nn_fp());
}
TEMPLATE__
void TREE__::Print() {
RecursivePrint(parent_);
}
TEMPLATE__
void TREE__::RecursivePrint(typename TREE__::NodePtr_t ptr) {
string str;
if (ptr->IsLeaf()) {
str = ptr->Print(dimension_);
printf("%s\n", str.c_str());
} else {
str = ptr->Print(dimension_);
printf("%s\n", str.c_str());
RecursivePrint(ptr->get_left());
RecursivePrint(ptr->get_right());
}
}
TEMPLATE__
string TREE__::Statistics() {
char buff[4096];
sprintf(buff, "Number of points : %llu,\n"
"Number of dimensions : %i\n"
"Number of nodes : %llu,\n"
"Number of leafs : %llu,\n"
"Max tree depth : %llu,\n"
"Min tree depth : %llu,\n",
(unsigned long long)num_of_points_,
dimension_,
(unsigned long long)node_id_,
(unsigned long long)num_of_leafs_,
(unsigned long long)max_depth_,
(unsigned long long)min_depth_);
return string(buff);
}
TEMPLATE__
string TREE__::Computations() {
char buff[4096];
sprintf(buff,"number of comparisons: %llu\n"
"number of distances: %llu\n",
(unsigned long long)computations_.get_comparisons(),
(unsigned long long)computations_.get_distances());
return string(buff);
}
TEMPLATE__
void TREE__::set_log_file(const string &log_file) {
if (log_file_ptr_ != stderr ) {
if (fclose(log_file_ptr_)!= 0) {
fprintf(stderr, "Cannot close file %s\n", log_file_.c_str());
assert(false);
}
}
log_file_ptr_ = fopen(log_file.c_str(), "wb");
log_file_ = log_file;
}
#undef TREE__
#undef TEMPLATE__
#endif /*BINARY_TREE_IMPL_H_*/
-300
View File
@@ -1,300 +0,0 @@
/*
* =====================================================================================
*
* Filename: binary_tree_unit.cc
*
* Description:
*
* Version: 1.0
* Created: 04/27/2007 10:20:40 AM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#include <unistd.h>
#include <sys/mman.h>
#include <limits>
#include "fastlib/fastlib.h"
#include "u/nvasil/mmanager/memory_manager.h"
#include "u/nvasil/test/test.h"
#include "u/nvasil/dataset/binary_dataset.h"
#include "tree_parameters_macro.h"
#include "euclidean_metric.h"
#include "null_statistics.h"
#include "hyper_rectangle.h"
#include "point_identity_discriminator.h"
#include "kd_pivoter1.h"
#include "binary_tree.h"
using namespace std;
template<typename TYPELIST, bool diagnostic>
class BinaryTreeTest {
public:
typedef typename TYPELIST::Precision_t Precision_t;
typedef typename TYPELIST::Allocator_t Allocator_t;
typedef typename TYPELIST::Metric_t Metric_t;
typedef typename TYPELIST::BoundingBox_t BoundingBox_t;
typedef typename TYPELIST::NodeCachedStatistics_t NodeCachedStatistics_t;
typedef typename TYPELIST::PointIdDiscriminator_t PointIdDiscriminator_t;
typedef typename TYPELIST::Pivot_t Pivot_t;
typedef Point<Precision_t, Allocator_t> Point_t;
typedef BinaryTree<TYPELIST, diagnostic> BinaryTree_t;
typedef typename BinaryTree_t::Node_t Node_t;
BinaryTreeTest() {
}
void Init() {
Allocator_t::allocator_ = new Allocator_t();
Allocator_t::allocator_->Initialize();
dimension_=2;
num_of_points_=1000;
data_file_="data";
knns_=40;
range_=0.2;
result_file_="allnn";
data_.Init(data_file_, num_of_points_, dimension_);
for(index_t i=0; i<num_of_points_; i++) {
for(index_t j=0; j<dimension_; j++) {
data_.At(i,j)=Precision_t(rand())/RAND_MAX - 0.48;
}
data_.set_id(i,i);
}
tree_.Init(&data_);
}
void Destruct() {
tree_.Destruct();
data_.Destruct();
unlink(data_file_.c_str());
unlink(data_file_.append(".ind").c_str());
unlink(result_file_.c_str());
}
void BuildDepthFirst(){
printf("Testing BuildDepthFirst...\n");
tree_.BuildDepthFirst();
//tree_.Print();
printf("%s\n", tree_.Statistics().c_str());
}
void BuildBreadthFirst() {
printf("Testing BuildBreadthFirst...\n");
tree_.BuildBreadthFirst();
// tree_.Print();
printf("%s\n", tree_.Statistics().c_str());
}
void kNearestNeighbor() {
printf("Testing kNearestNeighbor...\n");
tree_.BuildDepthFirst();
//tree_.Print();
vector<pair<Precision_t, Point_t> > nearest_tree;
pair<Precision_t, index_t> nearest_naive[num_of_points_];
for(index_t i=0; i<num_of_points_; i++) {
nearest_tree.clear();
tree_.NearestNeighbor(data_.get_point(i),
&nearest_tree,
knns_);
Naive(i, nearest_naive);
for(index_t j=0; j<knns_; j++) {
TEST_DOUBLE_APPROX(nearest_naive[j+1].first,
nearest_tree[j].first,
numeric_limits<Precision_t>::epsilon());
TEST_ASSERT(nearest_tree[j].second.get_id()==
nearest_naive[j+1].second) ;
}
}
}
void RangeNearestNeighbor() {
printf("Testing RangeNearestNeighbor...\n");
tree_.BuildBreadthFirst();
//tree_.Print();
vector<pair<Precision_t, Point_t> > nearest_tree;
pair<Precision_t, index_t> nearest_naive[num_of_points_];
for(index_t i=0; i<num_of_points_; i++) {
nearest_tree.clear();
tree_.NearestNeighbor(data_.get_point(i),
&nearest_tree,
range_);
std::sort(nearest_tree.begin(), nearest_tree.end(),
typename Node_t::PairComparator());
Naive(i, nearest_naive);
for(index_t j=0; j<(index_t)nearest_tree.size(); j++) {
TEST_DOUBLE_APPROX(nearest_naive[j+1].first,
nearest_tree[j].first,
numeric_limits<Precision_t>::epsilon());
TEST_ASSERT(nearest_tree[j].second.get_id()==
nearest_naive[j+1].second) ;
}
}
}
void AllKNearestNeighbors() {
printf("Testing AllKNearestNeighbors...\n");
tree_.BuildDepthFirst();
// tree_.Print();
tree_.InitAllKNearestNeighborOutput(result_file_,
knns_);
tree_.AllNearestNeighbors(tree_.parent_, knns_);
tree_.CloseAllKNearestNeighborOutput(knns_);
struct stat info;
if (stat(result_file_.c_str(), &info)!=0) {
FATAL("Error %s file %s\n",
strerror(errno), data_file_.c_str());
}
uint64 map_size = info.st_size;
int fp=open(result_file_.c_str(), O_RDWR);
typename Node_t::NNResult *res;
res=(typename Node_t::NNResult *)mmap(NULL,
map_size,
PROT_READ | PROT_WRITE,
MAP_SHARED, fp,
0);
TEST_ASSERT(res!=MAP_FAILED);
close(fp);
std::sort(res, res+num_of_points_*knns_);
pair<Precision_t, index_t> nearest_naive[num_of_points_];
for(index_t i=0; i<num_of_points_; i++) {
Naive(i, nearest_naive);
for(index_t j=0; j<knns_; j++) {
TEST_DOUBLE_APPROX(nearest_naive[j+1].first,
res[data_.get_id(i)*knns_+j].distance_,
numeric_limits<Precision_t>::epsilon());
TEST_ASSERT(res[data_.get_id(i)*knns_+j].nearest_.get_id()==
nearest_naive[j+1].second);
}
}
munmap(res, map_size);
}
void AllRangeNearestNeighbors() {
printf("Testing AllRangeNearestNeighbors...\n");
tree_.BuildBreadthFirst();
//tree_.Print();
tree_.InitAllRangeNearestNeighborOutput(result_file_);
tree_.AllNearestNeighbors(tree_.parent_, range_);
tree_.CloseAllRangeNearestNeighborOutput();
struct stat info;
if (stat(result_file_.c_str(), &info)!=0) {
FATAL( "Error %s file %s\n",
strerror(errno), data_file_.c_str());
}
uint64 map_size = info.st_size;
int fp=open(result_file_.c_str(), O_RDWR);
typename Node_t::NNResult *res;
res=(typename Node_t::NNResult *)mmap(NULL,
map_size,
PROT_READ | PROT_WRITE,
MAP_SHARED, fp,
0);
close(fp);
TEST_ASSERT(res!=MAP_FAILED);
std::sort(res, res+map_size/sizeof(typename Node_t::NNResult));
pair<Precision_t, index_t> nearest_naive[num_of_points_];
index_t i=0;
while (i<num_of_points_) {
Naive(i, nearest_naive);
index_t j=0;
while(res[j].point_id_<(index_t)data_.get_id(i)) {
j++;
}
index_t k=1;
while (nearest_naive[k].first<=range_) {
TEST_DOUBLE_APPROX(nearest_naive[k].first,
res[j].distance_,
numeric_limits<Precision_t>::epsilon());
j++;
k++;
}
i++;
}
munmap(res, map_size);
}
void TestAll() {
Init();
BuildDepthFirst();
Destruct();
Init();
BuildBreadthFirst();
Destruct();
Init();
kNearestNeighbor();
Destruct();
Init();
RangeNearestNeighbor();
Destruct();
Init();
AllKNearestNeighbors();
Destruct();
Init();
AllRangeNearestNeighbors();
Destruct();
}
private:
BinaryTree_t tree_;
BinaryDataset<Precision_t> data_;
string data_file_;
string result_file_;
int32 dimension_;
index_t num_of_points_;
index_t knns_;
Precision_t range_;
void Naive(index_t query,
pair<Precision_t, index_t> *result) {
for(index_t i=0; i<num_of_points_; i++) {
Precision_t dist=Metric_t::Distance(data_.At(i),
data_.At(query),
dimension_);
result[i].first=dist;
result[i].second=data_.get_id(i);
}
std::sort(result, result+num_of_points_);
}
void Naive(Precision_t *query,
pair<Precision_t, index_t> *result) {
for(index_t i=0; i<num_of_points_; i++) {
Precision_t dist=Metric_t::Distance(data_.At(i),
query,
dimension_);
result[i].first=dist;
result[i].second=data_.get_id(i);
}
std::sort(result, result+num_of_points_);
}
};
TREE_PARAMETERS(float32,
MemoryManager<false>,
EuclideanMetric,
HyperRectangle,
NullStatistics,
SimpleDiscriminator,
KdPivoter1,
false)
/*struct BasicTypes {
typedef float32 Precision_t;
typedef MemoryManager<false> Allocator_t;
typedef EuclideanMetric<float32> Metric_t;
};
struct Parameters {
typedef float32 Precision_t;
typedef MemoryManager<false> Allocator_t;
typedef EuclideanMetric<float32> Metric_t;
typedef HyperRectangle<BasicTypes, false> BoundingBox_t;
typedef NullStatistics NodeCachedStatistics_t;
typedef SimpleDiscriminator PointIdDiscriminator_t;
typedef KdPivoter1<BasicTypes, false> Pivot_t;
};
*/
typedef BinaryTreeTest<Parameters, false> BinaryTreeTest_t;
int main(int argc, char *argv[]) {
BinaryTreeTest_t test;
test.TestAll();
}
-51
View File
@@ -1,51 +0,0 @@
/*
* =====================================================================================
*
* Filename: metric.h
*
* Description: Definition of different metrics
*
* Version: 1.0
* Created: 02/11/2007 04:52:54 PM EST
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#include "base/basic_types.h"
template<typename PRECISION>
class EuclideanMetric {
public:
template<typename POINTTYPE1, typename POINTTYPE2>
static inline PRECISION Distance(POINTTYPE1 p1,
POINTTYPE2 p2, int32 dimension) {
// we need to do some type checking for the POINTTYPE
PRECISION dist=0;
for(int32 i=0; i<dimension; i++) {
dist+=(p1[i]-p2[i])*(p1[i]-p2[i]);
}
return dist;
}
template<typename POINTTYPE1, typename POINTTYPE2, typename POINTTYPE3>
static inline void Addition(POINTTYPE1 &result,
POINTTYPE2 p1,
POINTTYPE3 p2,
int32 dimension) {
for(int32 i=0; i<dimension; i++) {
result[i] = p1[i]+p2[i];
}
}
template<typename POINTTYPE1, typename POINTTYPE2>
static inline void Scale(POINTTYPE1 &result, POINTTYPE2 point,
PRECISION scale_factor, int32 dimension) {
for(int32 i=0; i<dimension; i++) {
result[i]= point[i] * scale_factor;
}
}
};
-88
View File
@@ -1,88 +0,0 @@
/*
* =====================================================================================
*
* Filename: hyper_ball.h
*
* Description:
*
* Version: 1.0
* Created: 02/11/2007 05:45:21 PM EST
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#ifndef HYPER_BALL_H_
#define HYPER_BALL_H_
#include <new>
#include <math.h>
#include <string>
#include "loki/Typelist.h"
#include "fastlib/fastlib.h"
#include "computations_counter.h"
template<typename TYPELIST, bool diagnostic>
typename Precision_t, typename METRIC,
Allocator_t, bool diagnostic>
class HyperBall {
public:
typedef loki::TypeAt<TYPELIST, 0>::Result Precision_t;
typedef loki::TypeAt<TYPELIST, 1>::Result Allocator_t;
typedef loki::TypeAt<TYPELIST, 2>::Result Metric_t;
typedef Allocator_t::template ArrayPtr<Precision_t> Array_t;
typedef HyperBall<TYPELIST, diagnostic> HyperBall_t;
friend class HyperBall<TYPELIST, diagnostic>;
HyperBall();
Init(int32 dimension);
void Init(Array_t center, Precision_t radious,
Array_t pivot_left, Array_t pivot_right);
~HyperBall() {};
static void *operator new(size_t size);
static void operator delete(void *p);
HyperBall_t &operator=(const HyperBall_t & other);
void Copy(const HyperBall_t &other);
void DeepCopy(const HyperBall_t &other, int32 dimension);
template<typename POINTTYPE>
bool IsWithin(POINTTYPE point, int32 dimension, Precision_t range,
ComputationsCounter<diagnostic> &comp);
Precision_t IsWithin(HyperBall_t &hr,
int32 dimension,
Precision_t range,
ComputationsCounter<diagnostic> &comp);
template<typename POINTTYPE>
bool CrossesBoundaries(POINTTYPE point, int32 dimension, Precision_t range,
ComputationsCounter<diagnostic> &comp);
template<typename POINTTYPE1, typename POINTTYPE2>
static Precision_t Distance(POINTTYPE1 point1, POINTTYPE2 point2, int32 dimension);
static Precision_t Distance(HyperBall_t &hr1,
HyperBall_t &hr2,
int32 dimension,
ComputationsCounter<diagnostic> &comp);
static Precision_t Distance(HyperBall_t &hr1,
HyperBall_t &hr2,
Precision_t threshold_distance,
int32 dimension,
ComputationsCounter<diagnostic> &comp);
template<typename POINTTYPE, typename NODETYPE>
pair<Allocator_t::template Ptr<NODETYPE>,
Allocator_t::template Ptr<NODETYPE> >
ClosestChild(Allocator_t::template Ptr<NODETYPE> left,
Allocator_t::template Ptr<NODETYPE> right,
POINTTYPE point, int32 dimension,
ComputationsCounter<diagnostic> &comp);
string Print(int32 dimension);
private:
Array_t center_;
// This is the radious, not the square of the radious
Precision_t radious_;
Array_t pivot_left_;
Array_t pivot_right_;
};
#include "hyper_ball_impl.h"
#endif // HYPER_BALL_H_
-217
View File
@@ -1,217 +0,0 @@
/*
* =====================================================================================
*
* Filename: hyper_ball_impl.h
*
* Description:
*
* Version: 1.0
* Created: 02/11/2007 07:08:40 PM EST
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#ifndef HYPER_BALL_IMPL_H_
#define HYPER_BALL_IMPL_H_
#define __TEMPLATE__ \
template<typename TYPELIST, bool diagnostic>
#define __HYPERBALL__ \
HyperBall<TYPELIST, diagnostic>
__TEMPLATE__
__HYPERBALL__::HyperBall() {
}
__TEMPLATE__
void __HYPERBALL__::Init(int32 dimension) {
center_.Reset(Allocator_t::calloc<Precision_t>(dimension, 0));
pivot_left_.Reset(Allocator_t::calloc<Precision_t>(dimension, 0));
pivot_right_.Reset(Allocator_t::calloc<Precision_t>(dimension, 0));
}
__TEMPLATE__
void __HYPERBALL__::Init(Array_t center, Precision_t radious,
Array_t pivot_left, Array_t pivot_right) {
center_=center ;
radious_=radious;
pivot_left_=pivot_left;
pivot_right_=pivot_right;
}
__TEMPLATE__
static void *__HYPERBALL__::operator new(size_t size) {
return Allocator_t::malloc(size);
}
__TEMPLATE__
static void __HYPERBALL__::operator delete(void *p) {
}
__TEMPLATE__
inline HyperBall<TYPELIST, diagnostic> &__HYPERBALL__::operator=(
const HyperBall<TYPELIST, diagnostic> &other) {
center_ = other.center_;
radious_ = other.radious_;
pivot_left_ = other.pivot_left_;
pivot_right_ = other.pivot_right_;
return *this;
}
__TEMPLATE__
inline void __HYPERBALL__::Copy(const HyperBall_t &other) {
center_ = other.center_;
radious_ = other.radious_;
pivot_left_ = other.pivot_left_;
pivot_right_ = other.pivot_right_;
}
__TEMPLATE__
inline void __HYPERBALL__::DeepCopy(const HyperBall_t &other,
int32 dimension) {
center_.DeepCopy(other.center_, dimension);
radious_ = other.radious_;
pivot_left_.DeepCopy(other.pivot_left_, dimension);
pivot_right_.DeepCopy(other.pivot_right_, dimension);
}
__TEMPLATE__
template<typename POINTTYPE>
inline bool __HYPERBALL__::IsWithin(POINTTYPE point,
int32 dimension,
Precision_t range,
ComputationsCounter<diagnostic> &comp) {
comp.UpdateDistances();
Precision_t point_center_distance =
Metric_t::Distance(center_, point, dimension);
// Inside the ball
comp.UpdateComparisons();
if (radious_ > sqrt(point_center_distance) + sqrt(range)) {
return true;
} else {
// Completelly outside or crossing
return false;
}
}
__TEMPLATE__
inline Precision_t __HYPERBALL__::IsWithin(HyperBall_t &hr,
int32 dimension,
Precision_t range,
ComputationsCounter<diagnostic> &comp) {
return IsWithin(hr.center_, dimension, hr.radious_ * hr.radious_, comp);
}
__TEMPLATE__
template<typename POINTTYPE>
inline bool __HYPERBALL__::CrossesBoundaries(POINTTYPE point,
int32 dimension,
Precision_t range,
ComputationsCounter<diagnostic> &comp) {
comp.UpdateDistances();
Precision_t point_center_distance = Metric_t::Distance(center_, point, dimension);
comp.UpdateComparisons();
if (point_center_distance < range) {
return true;
}
comp.UpdateComparisons();
if (sqrt(point_center_distance) > radious_+ sqrt(range)) {
return false;
} else {
return true;
}
}
__TEMPLATE__
template<typename POINTTYPE1, typename POINTTYPE2>
inline Precision_t __HYPERBALL__::Distance(POINTTYPE1 point1,
POINTTYPE2 point2,
int32 dimension) {
return Metric_t::Distance(point1, point2, dimension);
}
__TEMPLATE__
inline Precision_t __HYPERBALL__::Distance(HyperBall_t &hr1,
HyperBall_t &hr2,
int32 dimension,
ComputationsCounter<diagnostic> &comp) {
comp.UpdateDistances();
Precision_t center_distances=Metric_t::Distance(hr1.center_,
hr2.center_, dimension);
comp.UpdateComparisons();
Precision_t dist=sqrt(center_distances)-(hr2.radious_+hr1.radious_);
if (dist<=0) {
return 0;
} else {
return dist*dist;
}
}
__TEMPLATE__
Precision_t __HYPERBALL__::Distance(HyperBall_t &hr1,
HyperBall_t &hr2,
Precision_t threshold_distance,
int32 dimension,
ComputationsCounter<diagnostic> &comp) {
fprintf(stderr, "Not Implemented yet\n");
assert("false");
return 0;
}
__TEMPLATE__
template<typename POINTTYPE, typename NODETYPE>
inline pair<Allocator_t::template Ptr<NODETYPE>,
Allocator_t::template Ptr<NODETYPE> >
__HYPERBALL__::ClosestChild(Allocator_t::template Ptr<NODETYPE> left,
Allocator_t::template Ptr<NODETYPE> right,
POINTTYPE point,
int32 dimension,
ComputationsCounter<diagnostic> &comp) {
comp.UpdateDistances();
comp.UpdateDistances();
Precision_t left_dist = Metric_t::Distance(pivot_left_, point, dimension);
Precision_t right_dist = Metric_t::Distance(pivot_right_, point, dimension);
if (left_dist<right_dist) {
return make_pair(left, right);
} else {
return make_pair(right, left);
}
}
__TEMPLATE__
string __HYPERBALL__::Print(int32 dimension) {
char buf[8192];
string str("center: ");
for(int32 i=0; i<dimension; i++){
sprintf(buf,"%lg ", (double) center_[i]);
str.append(buf);
}
str.append("\nradious: ");
sprintf(buf,"%lg\n", (double) radious_);
str.append(buf);
str.append("pivot_left: ");
for(int32 i=0; i<dimension; i++){
sprintf(buf,"%lg ", (double)pivot_left_[i]);
str.append(buf);
}
str.append("\npivot_right: ");
for(int32 i=0; i<dimension; i++){
sprintf(buf,"%lg ", (double)pivot_right_[i]);
str.append(buf);
}
str.append("\n");
return str;
}
#undef __TEMPLATE__
#undef __HYPERBALL__
#endif // HYPER_BALL_IMPL_H_
-161
View File
@@ -1,161 +0,0 @@
/*
* =====================================================================================
*
* Filename: hyper_ball_unit.cc
*
* Description:
*
* Version: 1.0
* Created: 04/21/2007 06:12:12 PM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#include "loki/Typelist.h"
#include "fastlib/fastlib.h"
#include "mmanager/memory_manager.h"
#include "hyper_ball.h"
template<typename TYPELIST, bool diagnostic>
class HyperBallTest {
public:
typedef TypeAt<TYPELIST, 0>::value Precision_t;
typedef TypeAt<TYPELIST, 1>::value Allocator_t;
typedef TypeAt<TYPELIST, 2>::value Metric_t;
typedef HyperBall<TYPELIST, diagnostic> HyperBall_t;
HyperBallTest();
~HyperBall() {
Destruct();
}
void Init() {
dimension_=2;
Allocator_t::allocator_ = new Allocator_t();
Allocator_t::allocator_->Initialize();
hyper_ball_= new HyperBall_t();
Allocator_t::ArrayPtr<Precision_t> center(dimension_);
center[0]=1;
center[1]=-1;
Precision_t radious=2;
Allocator_t::ArrayPtr<Precision_t> pivot_left;
Allocator_t::ArrayPtr<Precision_t> pivot_right;
hyper_ball_->Init(center, radious, pivot_left, pivot_right);
}
void Destruct() {
delete hyper_ball_;
delete Allocator_t::allocator_;
}
void AliasTest() {
printf("Alias Test\n");
Init();
HyperBall_t other;
other.Alias(*hyper_ball_);
DEBUG_ASSERT_MSG(other.center_==hyper_ball_->center_,
"Centers don't match\n");
DEBUG_ASSERT_MSG(other.radious_==hyper_ball_->radious_,
"Radious don't match\n");
DEBUG_ASSERT_MSG(other.pivot_left_==hyper_ball_->pivot_left_,
"Pivot left doesn't match\n");
DEBUG_ASSERT_MSG(other.pivot_right_==hyper_ball_->pivot_right_,
"Pivot right don't match\n");
Destruct();
}
void DeepCopyTest() {
printf("DeepCopy Test\n");
Init();
HyperBall_t other;
other.Init(dimension_);
other.DeepCopy(*hyper_ball_, dimension_);
DEBUG_ASSERT_MSG(other.radious_==hyper_ball_->radious_,
"Radious don't match\n");
DEBUG_ASSERT_MSG(other.center_!=hyper_ball_->center_,
"Centers are the same \n");
for(index_t i=0; i<dimension_; i++) {
DEBUG_ASSERT_MSG(other.center_[i]==hyper_ball_->center_[i],
"Centers don't match\n");
DEBUG_ASSERT_MSG(other.pivot_left_[i]==hyper_ball_->pivot_left_[i],
"Pivot left doesn't match\n");
DEBUG_ASSERT_MSG(other.pivot_right_[i]==hyper_ball_->pivot_right_[i],
"Pivot right don't match\n");
}
Destruct();
}
void IsWithinTest() {
Point<Precision_t, Allocator_t> point;
point[0]=1;
point[1]=0.3;
Precision_t range=0.03;
DEBUG_ASSERT_MSG(hyper_ball_->IsWithin(point, dimension_,
range, comp)==true,
"IsWithin doesn't work\n");
range=2;
DEBUG_ASSERT_MSG(hyper_ball_->IsWithin(point, dimension_,
range, comp)==false,
"IsWithin doesn't work\n");
Destruct();
}
void CrossesBoundaryTest() {
Point<Precision_t, Allocator_t> point;
point.Init(dimension_);
point[0]=2;
point[1]=-4;
Precision_t range=1;
DEBUG_ASSERT_MSG(hyper_ball_->CrossesBoundary(point, dimension_,
range, comp)==true,
"CrossesBoundary doesn't work\n");
range=0.25;
DEBUG_ASSERT_MSG(hyper_ball_->CrossesBoundary(point, dimension_,
range, comp)==false,
"CrossesBoundary doesn't work\n");
Destruct();
}
void DistanceTest(){
Point<Precision_t, Allocator_t> point1;
Point<Precision_t, Allocator_t> point2;
point1.Init(dimension_);
point1[0]=0;
point1[1]=1;
point2[0]=-1;
point2[1]=-2;
point2.Init(dimension_);
ASSERT_DEBUG_MSG(HyperBall_t::Distance(point1, point2, dimension_)==10,
"Distance between points doesn't work\n");
HyperBall_t other;
other.Init(dimension_);
other.center_[0]=1;
other.center_[1]=5;
other.radious_=3;
ASSERT_DEBUG_MSG(HyperBall_t::Distance(*hyper_ball_, other,
dimension)==31,
"Dimension doesn't work\n");
other.radious_=34;
ASSERT_DEBUG_MSG(HyperBall_t::Distance(*hyper_ball_, other,
dimension)==0,
"Dimension doesn't work\n");
Destruct();
}
private:
HyperBall<TYPELIST, diagnostic> *hyper_ball_;
int32 dimension_;
};
int main(int argc, char *argv[]) {
typdef TYPELIST_3(float32, MemoryManager<true>, EuclideanMetric<float32>)
UserTypeParameters_t;
HyperBallTest<UserTypeParameters_t, false> hyper_ball_test;
hyper_ball_test.CopyTest();
hyper_ball_test.IsWithinTest();
hyper_ball_test.CrossesBoundaryTest();
hyper_ball_test.DistanceTest();
hyper_ball_test.ClosestDistanceTest();
}
-123
View File
@@ -1,123 +0,0 @@
/*
* =====================================================================================
*
* Filename: hyper_rectangle.h
*
* Description:
*
* Version: 1.0
* Created: 04/17/2007 04:38:03 PM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#ifndef U_NVASIL_HYPER_RECTANGLE_H_
#define U_NVASIL_HYPER_RECTANGLE_H_
#include <new>
#include <limits>
#include <math.h>
#include <string>
#include "u/nvasil/loki/Typelist.h"
#include "fastlib/fastlib.h"
#include "computations_counter.h"
using namespace std;
template<typename BASICTYPES, bool diagnostic>
class HyperRectangle {
public:
typedef typename BASICTYPES::Precision_t Precision_t;
typedef typename BASICTYPES::Allocator_t Allocator_t;
typedef typename BASICTYPES::Metric_t Metric_t;
/*
typedef typename Loki::TL::TypeAt<TYPELIST, 0>::Result Precision_t;
typedef typename Loki::TL::TypeAt<TYPELIST, 1>::Result Allocator_t;
typedef typename Loki::TL::TypeAt<TYPELIST, 2>::Result Metric_t;
*/
typedef HyperRectangle<BASICTYPES, diagnostic> HyperRectangle_t;
typedef typename Allocator_t:: template ArrayPtr<Precision_t> ArrayPtr_t;
typedef typename Allocator_t:: template ArrayPtr<Precision_t> Array_t;
template<typename, bool> friend class HyperRectangleTest;
HyperRectangle();
void Init(int32 dimension);
void Init(ArrayPtr_t min, ArrayPtr_t max, int32 pivot_dimension,
Precision_t pivot_value);
~HyperRectangle() {};
void Destruct(){
}
static void *operator new(size_t size);
static void operator delete(void *p);
HyperRectangle_t &operator=(HyperRectangle_t &);
void Alias(const HyperRectangle_t &other);
void Copy(const HyperRectangle_t &other, int32 dimension);
template<typename POINTTYPE>
bool IsWithin(POINTTYPE point, int32 dimension, Precision_t range,
ComputationsCounter<diagnostic> &comp);
template <typename POINTTYPE>
bool IsWithin(POINTTYPE point, int32 dimension, Precision_t metric_matrix,
Precision_t range, ComputationsCounter<diagnostic> &comp);
Precision_t IsWithin(HyperRectangle_t &hr,
int32 dimension,
Precision_t range,
ComputationsCounter<diagnostic> &comp);
template<typename POINTTYPE>
bool CrossesBoundaries(POINTTYPE point, int32 dimension, Precision_t range,
ComputationsCounter<diagnostic> &comp);
template<typename POINTTYPE1, typename POINTTYPE2>
static Precision_t Distance(POINTTYPE1 point1, POINTTYPE2 point2,
int32 dimension);
template<typename POINTTYPE1, typename POINTTYPE2>
static Precision_t Distance(POINTTYPE1 point1, POINTTYPE2 point2,
int32 dimension, Precision_t **metric_matrix);
static Precision_t Distance(HyperRectangle_t &hr1,
HyperRectangle_t &hr2,
int32 dimension,
ComputationsCounter<diagnostic> &comp);
static Precision_t Distance(HyperRectangle_t &hr1,
HyperRectangle_t &hr2,
Precision_t threshold_distance,
int32 dimension,
ComputationsCounter<diagnostic> &comp);
template<typename POINTTYPE, typename NODETYPE>
pair<typename Allocator_t::template Ptr<NODETYPE>,
typename Allocator_t::template Ptr<NODETYPE> >
ClosestChild(typename Allocator_t::template Ptr<NODETYPE> left,
typename Allocator_t::template Ptr<NODETYPE> right,
POINTTYPE point,
int32 dimension,
ComputationsCounter<diagnostic> &comp);
string Print(int32 dimension);
Array_t &get_min() {
return min_;
}
Array_t &get_max() {
return max_;
}
int32 get_pivot_dimension() {
return pivot_dimension_;
}
Precision_t get_pivot_value() {
return pivot_value_;
}
void set_pivot_dimension(int32 pivot_dimension) {
pivot_dimension_=pivot_dimension;
}
void set_pivot_value(Precision_t pivot_value) {
pivot_value_=pivot_value;
}
private:
Array_t min_;
Array_t max_;
int32 pivot_dimension_;
Precision_t pivot_value_;
};
#include "hyper_rectangle_impl.h"
#endif
@@ -1,274 +0,0 @@
#ifndef HYPER_RECTANGLE_IMPL_H_
#define HYPER_RECTANGLE_IMPL_H_
#define TEMPLATE__ template<typename TYPELIST, bool diagnostic>
#define HYPERRECTANGLE__ HyperRectangle<TYPELIST, diagnostic>
TEMPLATE__
HYPERRECTANGLE__::HyperRectangle(){
}
TEMPLATE__
void HYPERRECTANGLE__::Init(int32 dimension) {
min_.Reset(Allocator_t:: template calloc<Precision_t>
(dimension, numeric_limits<Precision_t>::max()));
max_.Reset(Allocator_t:: template calloc<Precision_t>
(dimension, -numeric_limits<Precision_t>::max()));
pivot_dimension_=0;
pivot_value_=0;
}
TEMPLATE__
void HYPERRECTANGLE__::Init(Array_t min, Array_t max, int32 pivot_dimension,
Precision_t pivot_value) {
min_.Reset(min.get());
max_ = max;
pivot_dimension_ = pivot_dimension;
pivot_value_= pivot_value;
}
TEMPLATE__
HyperRectangle<TYPELIST, diagnostic> &HYPERRECTANGLE__::operator=
(HyperRectangle<TYPELIST, diagnostic> &hr) {
this->min_ = hr.min_;
this->max_ = hr.max_;
pivot_dimension_ = hr.pivot_dimension_;
pivot_value_ = hr.pivot_value_;
return *this;
}
TEMPLATE__
void HYPERRECTANGLE__::Alias(const HyperRectangle_t &hr) {
this->min_ = hr.min_;
this->max_ = hr.max_;
pivot_dimension_ = hr.pivot_dimension_;
pivot_value_ = hr.pivot_value_;
}
TEMPLATE__
void HYPERRECTANGLE__::Copy(const HyperRectangle_t &hr,
int32 dimension) {
this->min_.Copy(hr.min_, dimension);
this->max_.Copy(hr.max_, dimension);
pivot_dimension_ = hr.pivot_dimension_;
pivot_value_ = hr.pivot_value_;
}
TEMPLATE__
void *HYPERRECTANGLE__::operator new(size_t size) {
return Allocator_t::malloc(size);
}
TEMPLATE__
void HYPERRECTANGLE__::operator delete(void *p) {
}
TEMPLATE__
template<typename POINTTYPE>
inline bool HYPERRECTANGLE__::IsWithin(
POINTTYPE point, int32 dimension, Precision_t range,
ComputationsCounter<diagnostic> &comp) {
// non overlaping at all
for(int32 i=0; i<dimension; i++) {
comp.UpdateComparisons();
if ( point[i] > max_[i] || point[i] < min_[i]) {
return false;
}
}
Precision_t closest_projection = max_[0]-min_[0];
for(int32 i=0; i<dimension; i++) {
Precision_t projection1 = max_[i] - point[i];
Precision_t projection2 = point[i] - min_[i];
comp.UpdateComparisons();
if (closest_projection > projection1) {
closest_projection = projection1;
}
comp.UpdateComparisons();
if (closest_projection > projection2 ) {
closest_projection = projection2;
}
comp.UpdateComparisons();
if (range >= closest_projection * closest_projection) {
// Overlapping
return false ;
}
}
// Completelly inside
return true;
}
TEMPLATE__
inline typename HYPERRECTANGLE__::Precision_t HYPERRECTANGLE__::IsWithin(
HyperRectangle_t &hr,
int32 dimension,
Precision_t range,
ComputationsCounter<diagnostic> &comp) {
Precision_t closest_projection = numeric_limits<Precision_t>::max();
for(int32 i=0; i<dimension; i++) {
comp.UpdateComparisons();
comp.UpdateComparisons();
Precision_t d1=hr.min_[i] - min_[i];
Precision_t d2=max_[i] - hr.max_[i];
if (d1<0 || d2<0) {
return -1;
} else {
Precision_t dist = min(d1,d2);
if (dist < closest_projection) {
closest_projection = dist;
}
}
}
if (closest_projection * closest_projection > range) {
return 0;
}
return (sqrt(range) - closest_projection) *
(sqrt(range) - closest_projection);
}
TEMPLATE__
template<typename POINTTYPE>
inline bool HYPERRECTANGLE__::CrossesBoundaries(
POINTTYPE point, int32 dimension, HYPERRECTANGLE__::Precision_t range,
ComputationsCounter<diagnostic> &comp) {
Precision_t closest_point_coordinate;
Precision_t dist = 0;
for(int32 i=0; i<dimension; i++) {
comp.UpdateComparisons();
if (point[i] <= min_[i]) {
closest_point_coordinate = min_[i];
} else {
comp.UpdateComparisons();
if (point[i] < max_[i] && point[i] > min_[i]) {
closest_point_coordinate = point[i];
} else {
closest_point_coordinate = max_[i];
}
}
dist +=(closest_point_coordinate - point[i]) *
(closest_point_coordinate - point[i]);
comp.UpdateComparisons();
if (dist > range ) {
return false;
}
}
return dist <= range;
}
TEMPLATE__
template<typename POINTTYPE1, typename POINTTYPE2>
inline typename HYPERRECTANGLE__::Precision_t HYPERRECTANGLE__::Distance(
POINTTYPE1 point1,
POINTTYPE2 point2,
int32 dimension) {
Precision_t distance = 0;
for(int32 i=0; i< dimension; i++) {
distance+=(point1[i]-point2[i]) * (point1[i]-point2[i]);
}
return distance;
}
TEMPLATE__
inline typename HYPERRECTANGLE__::Precision_t HYPERRECTANGLE__::Distance(
typename HYPERRECTANGLE__::HyperRectangle_t &hr1,
typename HYPERRECTANGLE__::HyperRectangle_t &hr2,
int32 dimension,
ComputationsCounter<diagnostic> &comp) {
Precision_t dist=0;
comp.UpdateDistances();
for(int32 i=0; i<dimension; i++) {
Precision_t d2 = hr1.min_[i] - hr2.max_[i];
Precision_t d4 = hr1.max_[i] - hr2.min_[i];
if (d2>0) {
dist += d2*d2 ;
continue;
}
if (d4<0) {
dist += d4*d4;
}
}
return dist;
}
TEMPLATE__
inline typename HYPERRECTANGLE__::Precision_t HYPERRECTANGLE__::Distance(
typename HYPERRECTANGLE__::HyperRectangle_t &hr1,
typename HYPERRECTANGLE__::HyperRectangle_t &hr2,
typename HYPERRECTANGLE__::Precision_t threshold_distance,
int32 dimension,
ComputationsCounter<diagnostic> &comp) {
Precision_t dist=0;
comp.UpdateDistances();
for(int32 i=0; i<dimension; i++) {
Precision_t d2 = hr1.min_[i] - hr2.max_[i];
Precision_t d4 = hr1.max_[i] - hr2.min_[i];
if (d2>0) {
dist += d2*d2;
if (dist > threshold_distance) {
return numeric_limits<Precision_t>::max();
} else {
continue;
}
}
if (d4<0) {
dist += d4*d4;
if (dist > threshold_distance) {
return numeric_limits<Precision_t>::max();
}
}
}
return dist;
}
TEMPLATE__
template<typename POINTTYPE, typename NODETYPE>
inline pair<typename HYPERRECTANGLE__::Allocator_t:: template Ptr<NODETYPE>,
typename HYPERRECTANGLE__::Allocator_t:: template Ptr<NODETYPE> >
HYPERRECTANGLE__::ClosestChild(
typename HYPERRECTANGLE__::Allocator_t::template Ptr<NODETYPE> left,
typename HYPERRECTANGLE__::Allocator_t::template Ptr<NODETYPE> right,
POINTTYPE point,
int32 dimension,
ComputationsCounter<diagnostic> &comp) {
comp.UpdateComparisons();
if (point[pivot_dimension_] < pivot_value_) {
return make_pair(left, right);
} else {
return make_pair(right, left);
}
}
TEMPLATE__
string HYPERRECTANGLE__::Print(int32 dimension) {
char buf[8192];
sprintf(buf, "max: ");
string str;
str.append(buf);
for(int32 i=0; i<dimension; i++) {
sprintf(buf, " %f ", max_[i]);
str.append(buf);
}
sprintf(buf, "\n");
str.append(buf);
sprintf(buf, "min: ");
str.append(buf);
for(int32 i=0; i<dimension; i++) {
sprintf(buf, " %f ", min_[i]);
str.append(buf);
}
sprintf(buf, "\n");
str.append(buf);
return str;
}
#undef TEMPLATE__
#undef HYPERRECTANGLE__
#endif /*HYPER_RECTANGLE_IMPL_H_*/
@@ -1,173 +0,0 @@
/*
* =====================================================================================
*
* Filename: hyper_rectangle_unit.cc
*
* Description:
*
* Version: 1.0
* Created: 04/22/2007 09:45:28 PM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#include "u/nvasil/loki/Typelist.h"
#include "fastlib/fastlib.h"
#include "u/nvasil/mmanager/memory_manager.h"
#include "point.h"
#include "euclidean_metric.h"
#include "hyper_rectangle.h"
template<typename TYPELIST, bool diagnostic>
class HyperRectangleTest {
friend class HyperRectangle<TYPELIST, diagnostic>;
public:
typedef typename TYPELIST::Precision_t Precision_t;
typedef typename TYPELIST::Allocator_t Allocator_t;
typedef typename TYPELIST::Metric_t Metric_t;
typedef HyperRectangle<TYPELIST, diagnostic> HyperRectangle_t;
HyperRectangleTest() {
}
~HyperRectangleTest() {
}
void Init() {
dimension_=2;
Allocator_t::allocator_ = new Allocator_t();
Allocator_t::allocator_->Initialize();
hyper_rectangle_= new HyperRectangle_t();
hyper_rectangle_->Init(dimension_);
hyper_rectangle_->min_[0]=-1;
hyper_rectangle_->min_[1]=-1;
hyper_rectangle_->max_[0]=1;
hyper_rectangle_->max_[1]=1;
}
void Destruct() {
delete hyper_rectangle_;
delete Allocator_t::allocator_;
}
void AliasTest() {
printf("Alias Test\n");
Init();
HyperRectangle_t other;
other.Alias(*hyper_rectangle_);
DEBUG_ASSERT_MSG(other.min_==hyper_rectangle_->min_,
"Min don't match\n");
DEBUG_ASSERT_MSG(other.max_==hyper_rectangle_->max_,
"Max don't match\n");
DEBUG_ASSERT_MSG(other.pivot_dimension_==hyper_rectangle_->pivot_dimension_,
"Pivot dimension doesn't match\n");
DEBUG_ASSERT_MSG(other.pivot_value_==hyper_rectangle_->pivot_value_,
"Pivot value don't match\n");
Destruct();
}
void CopyTest() {
printf("Copy Test\n");
Init();
HyperRectangle_t other;
other.Init(dimension_);
other.Copy(*hyper_rectangle_, dimension_);
DEBUG_ASSERT_MSG(other.min_==hyper_rectangle_->min_,
"Min don't match\n");
DEBUG_ASSERT_MSG(other.max_!=hyper_rectangle_->max_,
"Max are the same \n");
for(index_t i=0; i<dimension_; i++) {
DEBUG_ASSERT_MSG(other.min_[i]==hyper_rectangle_->min_[i],
"Min don't match\n");
DEBUG_ASSERT_MSG(other.max_[i]==hyper_rectangle_->max_[i],
"Max left doesn't match\n");
}
Destruct();
}
void IsWithinTest() {
Init();
Point<Precision_t, Allocator_t> point;
point.Init(dimension_);
point[0]=-0.1;
point[1]=0.3;
Precision_t range=0.03;
DEBUG_ASSERT_MSG(hyper_rectangle_->IsWithin(point, dimension_,
range, comp_)==true,
"IsWithin doesn't work\n");
range=2;
DEBUG_ASSERT_MSG(hyper_rectangle_->IsWithin(point, dimension_,
range, comp_)==false,
"IsWithin doesn't work\n");
Destruct();
}
void CrossesBoundariesTest() {
Init();
Point<Precision_t, Allocator_t> point;
point.Init(dimension_);
point[0]=2;
point[1]=-4;
Precision_t range=11;
DEBUG_ASSERT_MSG(hyper_rectangle_->CrossesBoundaries(point, dimension_,
range, comp_)==true,
"CrossesBoundary doesn't work\n");
range=0.25;
DEBUG_ASSERT_MSG(hyper_rectangle_->CrossesBoundaries(point, dimension_,
range, comp_)==false,
"CrossesBoundary doesn't work\n");
Destruct();
}
void DistanceTest(){
Init();
Point<Precision_t, Allocator_t> point1;
Point<Precision_t, Allocator_t> point2;
point1.Init(dimension_);
point2.Init(dimension_);
point1[0]=0;
point1[1]=1;
point2[0]=-1;
point2[1]=-2;
DEBUG_ASSERT_MSG(HyperRectangle_t::Distance(point1, point2, dimension_)==10,
"Distance between points doesn't work\n");
HyperRectangle_t other;
other.Init(dimension_);
other.min_[0]=2;
other.min_[1]=2;
other.max_[0]=5;
other.max_[1]=5;
DEBUG_ASSERT_MSG(HyperRectangle_t::Distance(*hyper_rectangle_, other,
dimension_, comp_)==2,
"Distance doesn't work\n");
other.min_[0]=-0.5;
other.min_[1]=-0.5;
DEBUG_ASSERT_MSG(HyperRectangle_t::Distance(*hyper_rectangle_, other,
dimension_, comp_)==0,
"Distance doesn't work\n");
Destruct();
}
private:
HyperRectangle<TYPELIST, diagnostic> *hyper_rectangle_;
int32 dimension_;
ComputationsCounter<diagnostic> comp_;
};
/*
typedef LOKI_TYPELIST_3(float32,
MemoryManager<false>,
EuclideanMetric<float32>) UserTypeParameters_t;
*/
struct BasicTypes {
typedef float32 Precision_t;
typedef MemoryManager<false> Allocator_t;
typedef EuclideanMetric<float32> Metric_t;
};
int main(int argc, char *argv[]) {
HyperRectangleTest<BasicTypes, false> hyper_rectangle_test;
hyper_rectangle_test.AliasTest();
hyper_rectangle_test.IsWithinTest();
hyper_rectangle_test.CrossesBoundariesTest();
hyper_rectangle_test.DistanceTest();
}
-143
View File
@@ -1,143 +0,0 @@
/*
* =====================================================================================
*
* Filename: HyperRectanglePivoter.h
*
* Description:
*
* Version: 1.0
* Created: 04/28/2007 12:03:05 PM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#ifndef KD_PIVOTER1_H_
#define KD_PIVOTER1_H_
#include "fastlib/fastlib.h"
#include "u/nvasil/dataset/binary_dataset.h"
#include "hyper_rectangle.h"
using namespace std;
template<typename TYPELIST, bool diagnostic>
class KdPivoter1 {
public:
typedef typename TYPELIST::Precision_t Precision_t;
typedef typename TYPELIST::Allocator_t Allocator_t;
typedef typename TYPELIST::Metric_t Metric_t;
typedef HyperRectangle<TYPELIST, diagnostic> HyperRectangle_t;
struct PivotInfo {
public:
void Init(index_t start, index_t num_of_points, HyperRectangle_t &box) {
box_.Alias(box);
start_=start;
num_of_points_=num_of_points;
}
HyperRectangle_t box_;
NullStatistics statistics_;
index_t start_;
index_t num_of_points_;
};
void Init(BinaryDataset<Precision_t> *data) {
data_=data;
}
pair<PivotInfo*, PivotInfo*> operator()(PivotInfo *pivot) {
index_t left_start = pivot->start_;
index_t right_start = pivot->start_ + pivot->num_of_points_-1;
int32 dimension = data_->get_dimension();
int32 max_range_dimension = pivot->box_.get_pivot_dimension();
Precision_t pivot_value = pivot->box_.get_pivot_value();
Precision_t *point_left = data_->At(left_start);
Precision_t *point_right = data_->At(right_start);
index_t left_points=0;
index_t right_points=0;
HyperRectangle_t hr_left;
HyperRectangle_t hr_right;
hr_left.Init(dimension);
hr_right.Init(dimension);
while (true) {
while (left_points < pivot->num_of_points_ &&
point_left[max_range_dimension] < pivot_value) {
UpdateHyperRectangle(point_left, hr_left);
left_points++;
point_left = data_->At(left_start+left_points);
}
if (point_left > point_right || left_points == pivot->num_of_points_) {
break;
}
while (right_points < pivot->num_of_points_ &&
point_right[max_range_dimension] >= pivot_value) {
UpdateHyperRectangle(point_right, hr_right);
right_points++;
point_right = data_->At(right_start - right_points);
}
if (point_left > point_right || right_points == pivot->num_of_points_) {
break;
}
data_->Swap(left_start+left_points, right_start - right_points);
}
DEBUG_ASSERT(left_points+right_points == right_start - left_start+1);
FindPivotDimensionValue(hr_left);
FindPivotDimensionValue(hr_right);
PivotInfo* pv_left = new PivotInfo();
pv_left->Init(left_start, left_points, hr_left);
PivotInfo* pv_right = new PivotInfo();
pv_right->Init(left_start+left_points, right_points, hr_right);
return make_pair(pv_left, pv_right);
}
PivotInfo *operator()(index_t num_of_points) {
// make the parent
HyperRectangle_t hr;
hr.Init(data_->get_dimension());
for(index_t i=0; i<num_of_points; i++) {
Precision_t *point = data_->At(i);
UpdateHyperRectangle(point, hr);
}
FindPivotDimensionValue(hr);
PivotInfo *pv = new PivotInfo();
pv->Init(0, num_of_points, hr);
return pv;
}
private:
BinaryDataset<Precision_t> *data_;
void FindPivotDimensionValue(HyperRectangle_t &hr) {
Precision_t max_range = 0;
int32 max_range_dimension =0;
for(int32 j=0; j<data_->get_dimension(); j++) {
Precision_t range = hr.get_max()[j] - hr.get_min()[j];
if (range > max_range) {
max_range = range;
max_range_dimension = j;
}
}
hr.set_pivot_value((hr.get_max()[max_range_dimension] +
hr.get_min()[max_range_dimension])/2);
hr.set_pivot_dimension(max_range_dimension);
}
void UpdateHyperRectangle(Precision_t *point,
HyperRectangle_t &hr) {
for(int32 j=0; j<data_.get_dimension(); j++) {
if (point[j] > hr.get_max()[j]) {
hr.get_max()[j] = point[j];
}
if (point[j] < hr.get_min()[j]) {
hr.get_min()[j] = point[j];
}
}
}
};
#endif // KD_PIVOTER_H_
-177
View File
@@ -1,177 +0,0 @@
#ifndef NODE_H_
#define NODE_H_
#include <new>
#include <limits>
#include "u/nvasil/loki/TypeTraits.h"
#include "u/nvasil/loki/Typelist.h"
#include "fastlib/fastlib.h"
#include "point.h"
#include "point_identity_discriminator.h"
#include "computations_counter.h"
#include "u/nvasil/dataset/binary_dataset.h"
template<typename TYPELIST,
bool diagnostic>
class Node {
public:
typedef typename TYPELIST::Precision_t Precision_t;
typedef typename TYPELIST::Allocator_t Allocator_t;
typedef typename TYPELIST::Metric_t Metric_t;
typedef typename TYPELIST::BoundingBox_t BoundingBox_t;
typedef typename TYPELIST::NodeCachedStatistics_t NodeCachedStatistics_t;
typedef typename TYPELIST::PointIdDiscriminator_t PointIdDiscriminator_t;
typedef typename Allocator_t::template ArrayPtr<Precision_t> Array_t;
typedef Node<TYPELIST, diagnostic> Node_t;
typedef typename Allocator_t::template Ptr<Node> NodePtr_t;
typedef Point<Precision_t, Allocator_t> Point_t;
template<typename , bool> friend class NodeTest;
struct NNResult {
NNResult() : point_id_(0),
distance_(numeric_limits<Precision_t>::max()) {
}
bool operator<(const NNResult &other) const {
if (point_id_==other.point_id_) {
return distance_<other.distance_;
} else {
return point_id_<other.point_id_;
}
}
Precision_t get_distance() const {
return distance_;
}
index_t get_point_id() {
return point_id_;
}
index_t point_id_;
Point_t nearest_;
Precision_t distance_;
};
class PairComparator {
public:
bool operator()(const pair<Precision_t, Point_t> &a,
const pair<Precision_t, Point_t> &b) {
return a.first<b.first;
}
};
Node();
// Use this for node
void Init(const BoundingBox_t &box,
const NodeCachedStatistics_t &statistics,
index_t node_id,
index_t num_of_points);
// Use this for leaf
void Init(const BoundingBox_t &box,
const NodeCachedStatistics_t &statistics,
index_t node_id,
index_t start,
index_t num_of_points,
int32 dimension,
BinaryDataset<Precision_t> *dataset);
~Node();
static void *operator new(size_t size);
static void operator delete(void *p);
bool IsLeaf() {
return !points_.IsNULL();
}
template<typename POINTTYPE>
pair<NodePtr_t, NodePtr_t>
ClosestChild(POINTTYPE point,
int32 dimension,
ComputationsCounter<diagnostic> &comp);
pair<pair<NodePtr_t, Precision_t>,
pair<NodePtr_t, Precision_t> >
ClosestNode(NodePtr_t,
NodePtr_t,
int32 dimension,
ComputationsCounter<diagnostic> &comp);
// This one is using a custom discriminator
// We use this for timit experiments so that we exclude points
// from the same speaker
template<typename POINTTYPE, typename NEIGHBORTYPE>
void FindNearest(POINTTYPE query_point,
vector<pair<Precision_t, Point_t> > &nearest,
NEIGHBORTYPE range,
int32 dimension,
PointIdDiscriminator_t &discriminator,
ComputationsCounter<diagnostic> &comp);
// This one store the results directly on a memmory mapped file
// for k-nearest neighbors and to a normal file for range nearest neighbors
// very efficient for large datasets
// Uses a custom descriminator
template<typename NEIGHBORTYPE>
void FindAllNearest(NodePtr_t query_node,
Precision_t &max_neighbor_distance,
NEIGHBORTYPE range,
int32 dimension,
PointIdDiscriminator_t &discriminator,
ComputationsCounter<diagnostic> &comp);
NodePtr_t& get_left() {
return left_;
}
NodePtr_t& get_right() {
return right_;
}
BoundingBox_t &get_box() {
return box_;
}
typename Allocator_t::template ArrayPtr<Point_t>& get_points() {
return points_;
}
index_t get_num_of_points() {
return num_of_points_;
}
NNResult *get_kneighbors() {
return kneighbors_;
}
void set_kneighbors(NNResult *chunk, uint32 knns) {
kneighbors_=chunk;
for(index_t i=0; i< num_of_points_; i++) {
for(index_t j=0; j<(index_t)knns; j++) {
kneighbors_[i*knns+j].point_id_ =
index_[i];
kneighbors_[i*knns+j].nearest_.
set_id(numeric_limits<index_t>::max());
}
}
}
void InitKNeighbors(int32 knns);
void set_range_neighbors(FILE *fp) {
range_nn_fp_=fp;
}
FILE *get_range_nn_fp() {
return range_nn_fp_;
}
Precision_t get_min_dist_so_far() {
return min_dist_so_far_;
}
void set_min_dist_so_far(Precision_t distance) {
min_dist_so_far_=distance;
}
string Print(int32 dimension);
private:
BoundingBox_t box_;
index_t node_id_;
NodePtr_t left_;
NodePtr_t right_;
typename Allocator_t::template ArrayPtr<index_t> index_;
typename Allocator_t::template ArrayPtr<Precision_t> points_;
NodeCachedStatistics_t statistics_;
index_t num_of_points_;
union {
NNResult *kneighbors_;
FILE *range_nn_fp_;
};
Precision_t min_dist_so_far_;
};
#include "node_impl.h"
#endif /*NODE_H_*/
-277
View File
@@ -1,277 +0,0 @@
#ifndef NODE_IMPL_H_
#define NODE_IMPL_H_
#define TEMPLATE__ \
template<typename TYPELIST, bool diagnostic>
#define NODE__ \
Node<TYPELIST, diagnostic>
TEMPLATE__
NODE__::Node() {
left_.SetNULL();
right_.SetNULL();
points_.SetNULL();
kneighbors_=NULL;
node_id_ = numeric_limits<index_t>::max();
min_dist_so_far_=numeric_limits<Precision_t>::max();
}
TEMPLATE__
void NODE__::Init(const BoundingBox_t &box,
const NodeCachedStatistics_t &statistics,
index_t node_id,
index_t num_of_points) {
box_.Alias(box);
statistics_.Alias(statistics);
node_id_ = node_id;
num_of_points_ = num_of_points;
}
TEMPLATE__
void NODE__::Init(const typename NODE__::BoundingBox_t &box,
const typename NODE__::NodeCachedStatistics_t &statistics,
index_t node_id,
index_t start,
index_t num_of_points,
int32 dimension,
BinaryDataset<Precision_t> *dataset) {
box_.Alias(box);
statistics_.Alias(statistics);
node_id_ = node_id;
num_of_points_ = num_of_points;
points_.Reset(Allocator_t::template malloc<Precision_t>
(num_of_points_*dimension));
index_.Reset(Allocator_t::template malloc<index_t>(num_of_points_));
for(index_t i=start; i<start+num_of_points_; i++) {
for(int32 j=0; j<dimension; j++) {
points_[(i-start)*dimension+j]=dataset->At(i,j);
}
index_[i-start]=dataset->get_id(i);
}
}
TEMPLATE__
NODE__::~Node() {
}
TEMPLATE__
void *NODE__::operator new(size_t size) {
return Allocator_t::allocator_->AllignedAlloc(size);
}
TEMPLATE__
void NODE__::operator delete(void *p) {
}
TEMPLATE__
void NODE__::InitKNeighbors(int32 knns) {
for(index_t i=0; i<num_of_points_; i++) {
for(int32 j=0; j<knns; j++) {
kneighbors_[i*knns+j].point_id_=index_[i];
}
}
}
TEMPLATE__
template<typename POINTTYPE>
pair<typename NODE__::NodePtr_t, typename NODE__::NodePtr_t>
NODE__::ClosestChild(POINTTYPE point, int32 dimension,
ComputationsCounter<diagnostic> &comp) {
return box_.ClosestChild(left_, right_, point, dimension, comp);
}
TEMPLATE__
inline
pair<pair<typename NODE__::NodePtr_t, typename NODE__::Precision_t>,
pair<typename NODE__::NodePtr_t, typename NODE__::Precision_t> >
NODE__::ClosestNode(typename NODE__::NodePtr_t ptr1,
typename NODE__::NodePtr_t ptr2,
int32 dimension,
ComputationsCounter<diagnostic> &comp) {
Precision_t dist1 = BoundingBox_t::Distance(box_, ptr1->get_box(),
dimension, comp);
Precision_t dist2 = BoundingBox_t::Distance(box_, ptr2->get_box(),
dimension, comp);
if (dist1<dist2) {
return make_pair(make_pair(ptr1, dist1), make_pair(ptr2, dist2));
} else {
return make_pair(make_pair(ptr2,dist2), make_pair(ptr1, dist1));
}
}
TEMPLATE__
template<typename POINTTYPE, typename NEIGHBORTYPE>
inline void NODE__::FindNearest(POINTTYPE query_point,
vector<pair<typename NODE__::Precision_t,
typename NODE__::Point_t> > &nearest,
NEIGHBORTYPE range,
int32 dimension,
typename NODE__::PointIdDiscriminator_t &discriminator,
ComputationsCounter<diagnostic> &comp) {
for(index_t i=0; i<num_of_points_; i++) {
comp.UpdateDistances();
// we have to check if we are comparing the point with itself
if (unlikely(discriminator.AreTheSame(index_[i],
query_point.get_id())==true)) {
continue;
}
Precision_t dist = BoundingBox_t::
template Distance(query_point,
points_.get()+i*dimension,
dimension);
// In case it is range nearest neighbors
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==true) {
if (dist<=range){
Point_t point;
point.Alias(points_.get()+i*dimension, index_[i]);
nearest.push_back(make_pair(dist, point));
}
} else {
// for k nearest neighbors
Point_t point;
point.Alias(points_.get()+i*dimension, index_[i]);
nearest.push_back(make_pair(dist, point));
}
}
// for k-nearest neighbors
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==false) {
typename std::vector<pair<Precision_t, Point_t> >::iterator it;
//it=nearest.begin()+(index_t)range;
index_t j=0;
for(it=nearest.begin(), j=0; j<(index_t)range; j++) {
it++;
}
std::sort(nearest.begin(),
nearest.end(),
PairComparator());
if (likely(nearest.size()>(uint32)range)) {
nearest.erase(it, nearest.end());
} else {
pair<Precision_t, Point_t> dummy;
dummy.first=numeric_limits<Precision_t>::max();
index_t extra_size=(index_t)(range-nearest.size());
for(index_t i=0; i<extra_size; i++) {
nearest.push_back(dummy);
}
}
}
}
TEMPLATE__
template<typename NEIGHBORTYPE>
inline void NODE__::FindAllNearest(
NodePtr_t query_node,
typename NODE__::Precision_t &max_neighbor_distance,
NEIGHBORTYPE range,
int32 dimension,
typename NODE__::PointIdDiscriminator_t &discriminator,
ComputationsCounter<diagnostic> &comp) {
printf("%u--%u\n", query_node->get_node_id(), node_id_);
Precision_t max_local_distance = numeric_limits<Precision_t>::min();
for(index_t i=0; i<query_node->num_of_points_; i++) {
Precision_t distance;
// for k nearest neighbors
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==false) {
// get the current maximum distance for the specific point
distance = query_node->kneighbors_[i*(int32)range+(int32)range-1].distance_;
} else {
distance=range;
}
// We should check whether this speeds up or slows down
// the performance
comp.UpdateComparisons();
if (this->box_.CrossesBoundaries(query_node->points_.get()+i*dimension,
dimension,
distance,
comp)) {
// for k nearest neighbors
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==false) {
vector<pair<Precision_t, Point_t> > temp((index_t)range);
for(int32 j=0; j<range; j++) {
temp[j].first=query_node->kneighbors_[i*(index_t)range+j].distance_;
temp[j].second=query_node->kneighbors_[i*(index_t)range+j].nearest_;
}
Point_t point;
point.Alias(query_node->points_.get()+i*dimension,
query_node->index_[i]);
FindNearest(point, temp,
range, dimension,
discriminator, comp);
DEBUG_ASSERT_MSG((index_t)temp.size()==range,
"During %i-nn seach, returned %u results",(int)range,
(unsigned int)temp.size());
for(int32 j=0; j<(index_t)range; j++) {
query_node->kneighbors_[i*(index_t)range+j].distance_=temp[j].first;
query_node->kneighbors_[i*(index_t)range+j].nearest_=temp[j].second;
}
// Estimate the maximum nearest neighbor distance
comp.UpdateComparisons();
if (max_local_distance < temp.back().first) {
max_local_distance = temp.back().first;
}
} else {
// for range nearest neighbors
vector<pair<Precision_t, Point_t> > temp;
temp.clear();
Point_t point;
point.Alias(query_node->points_.get()+i*dimension,
query_node->index_[i]);
FindNearest(point, temp,
range, dimension,
discriminator, comp);
for(index_t j=0; j<(index_t)temp.size(); j++) {
NNResult result;
result.point_id_=query_node->index_[i];
result.nearest_.Alias(temp[j].second);
result.distance_=temp[j].first;
if (fwrite(&result, sizeof(NNResult), 1, range_nn_fp_)!=1) {
FATAL("Error while writing range nearest neighbors: %s\n",
strerror(errno));
}
}
}
}
}
if (Loki::TypeTraits<NEIGHBORTYPE>::isStdFloat==true) {
max_local_distance=range;
}
}
TEMPLATE__
string NODE__::Print(int32 dimension) {
char buf[8192];
string str;
if (!IsLeaf()) {
sprintf(buf, "Node: %llu\n", (unsigned long long)node_id_);
str.append(buf);
} else {
sprintf(buf, "Leaf: %llu\n", (unsigned long long)node_id_);
str.append(buf);
}
str.append(box_.Print(dimension));
str.append("num_of_points: ");
sprintf(buf,"%llu\n", (unsigned long long)num_of_points_);
str.append(buf);
if (IsLeaf()) {
for(index_t i=0; i<num_of_points_; i++) {
for(int32 j=0; j<dimension; j++) {
sprintf(buf,"%lg ", points_[i*dimension+j]);
str.append(buf);
}
sprintf(buf, "-%llu \n",(unsigned long long) index_[i]);
str.append(buf);
}
}
return str;
}
#undef TEMPLATE__
#undef NODE__
#endif /*NODE_IMPL_H_*/
-185
View File
@@ -1,185 +0,0 @@
/*
* =====================================================================================
*
* Filename: node_unit.cc
*
* Description:
*
* Version: 1.0
* Created: 04/23/2007 10:19:28 AM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#include "u/nvasil/loki/Typelist.h"
#include "fastlib/fastlib.h"
#include "u/nvasil/mmanager/memory_manager.h"
#include "u/nvasil/dataset/binary_dataset.h"
#include "hyper_rectangle.h"
#include "euclidean_metric.h"
#include "null_statistics.h"
#include "point_identity_discriminator.h"
#include "computations_counter.h"
#include "node.h"
template<typename TYPELIST, bool diagnostic>
class NodeTest {
public:
typedef typename TYPELIST::Precision_t Precision_t;
typedef typename TYPELIST::Allocator_t Allocator_t;
typedef typename TYPELIST::Metric_t Metric_t;
typedef HyperRectangle<TYPELIST, diagnostic> HyperRectangle_t;
struct NodeParameters : public TYPELIST {
typedef HyperRectangle_t BoundingBox_t;
typedef NullStatistics NodeCachedStatistics_t;
typedef SimpleDiscriminator PointIdDescriminator_t;
};
typedef Node<NodeParameters, diagnostic> Node_t;
typedef typename Allocator_t:: template ArrayPtr<Precision_t> Array_t;
typedef Point<Precision_t, Loki::NullType> Point_t;
NodeTest() {
}
~NodeTest() {
}
void Init() {
dimension_=2;
num_of_points_=30;
Allocator_t::allocator_ = new Allocator_t();
Allocator_t::allocator_->Initialize();
Array_t min(dimension_);
min[0]=-1;
min[1]=-1;
Array_t max(dimension_);
max[0]=1;
max[1]=1;
data_file_="data";
dataset_.Init(data_file_, num_of_points_, dimension_);
for(index_t i=0; i<num_of_points_; i++) {
dataset_.At(i)[0]=Precision_t(rand())/RAND_MAX;
dataset_.At(i)[1]=Precision_t(-rand())/RAND_MAX;
dataset_.set_id(i,i);
}
hyper_rectangle_.Init(min, max, 0, 0);
NullStatistics statistics;
// typename Node_t::NodeCachedStatistics_t statistics;
node_.Reset(new Node_t);
node_->Init(hyper_rectangle_,
statistics,
0,
0,
num_of_points_,
dimension_,
&dataset_);
}
void Destruct() {
hyper_rectangle_.Destruct();
delete Allocator_t::allocator_;
dataset_.Destruct();
unlink(data_file_.c_str());
unlink(data_file_.append(".ind").c_str());
}
void FindNearest() {
printf("Testing find nearest\n");
SimpleDiscriminator discriminator;
vector<pair<Precision_t, Point<Precision_t, Allocator_t> > > nearest;
ComputationsCounter<diagnostic> comp;
for(index_t i=0; i<num_of_points_; i++) {
Point_t query_point;
query_point.Alias(dataset_.At(i), dataset_.get_id(i));
nearest.clear();
node_->FindNearest(query_point,
nearest,
1,
dimension_,
discriminator,
comp);
Precision_t min_dist=numeric_limits<Precision_t>::max();
index_t min_id=0;
for(index_t j=0; j<num_of_points_; j++) {
if (unlikely(dataset_.get_id(j)==dataset_.get_id(i))) {
continue;
}
Precision_t distance = HyperRectangle_t::Distance(dataset_.At(i),
dataset_.At(j),
dimension_);
if (distance<min_dist) {
min_id=j;
min_dist=distance;
}
}
DEBUG_ASSERT_MSG(min_dist==nearest[0].first,
"Something wrong in the distance\n");
DEBUG_ASSERT_MSG(min_id==nearest[0].second.get_id(),
"Something wrong in the distance\n");
}
}
void FindAllNearest() {
printf("Testing find all nearest\n");
typename Node_t::NNResult result[num_of_points_];
node_->set_kneighbors(result, 1);
Precision_t max_neighbor_distance=numeric_limits<Precision_t>::max();
SimpleDiscriminator discriminator;
ComputationsCounter<diagnostic> comp;
node_->FindAllNearest(node_,
max_neighbor_distance,
1,
dimension_,
discriminator,
comp);
for(index_t i=0; i<num_of_points_; i++) {
Precision_t min_dist=numeric_limits<Precision_t>::max();
index_t min_id=0;
for(index_t j=0; j<num_of_points_; j++) {
if (unlikely(dataset_.get_id(j)==dataset_.get_id(i))) {
continue;
}
Precision_t distance = HyperRectangle_t::Distance(dataset_.At(i),
dataset_.At(j),
dimension_);
if (distance<min_dist) {
min_id=j;
min_dist=distance;
}
}
DEBUG_ASSERT_MSG(min_dist==result[i].distance_,
"Something wrong in the distance\n");
DEBUG_ASSERT_MSG(min_id==result[i].nearest_.get_id(),
"Something wrong in the distance\n");
}
}
void TestAll(){
Init();
FindNearest();
Destruct();
Init();
FindAllNearest();
Destruct();
}
private:
typename Allocator_t:: template Ptr<Node_t> node_;
string data_file_;
HyperRectangle_t hyper_rectangle_;
BinaryDataset<Precision_t> dataset_;
index_t num_of_points_;
int32 dimension_;
};
struct BasicParameters{
typedef float32 Precision_t;
typedef MemoryManager<false> Allocator_t;
typedef EuclideanMetric<float32> Metric_t;
};
int main(int argc, char *argv[]) {
NodeTest<BasicParameters, false> node_test;
node_test.TestAll();
}
-161
View File
@@ -1,161 +0,0 @@
#ifndef POINT_H_
#define POINT_H_
#include <new>
#include <string>
#include "u/nvasil/loki/NullType.h"
#include "fastlib/fastlib.h"
template<typename PRECISION, typename ALLOCATOR>
class Point {
public:
typedef PRECISION Precision_t;
typedef ALLOCATOR Allocator_t;
typedef Point<Precision_t, Allocator_t> Point_t;
Point() {
this->p_.Reset(NULL);
this->id_=0;
};
void *operator new(size_t size) {
return Allocator_t::allocator->AllignedAlloc(size);
}
void operator delete(void *p) {
}
void Init(int32 dim) {
p_.Reset(Allocator_t::template calloc<Precision_t>(dim, 0));
}
Precision_t &operator[](index_t i) {
return p_[i];
}
void Alias(const Point_t &point) {
this->p_ = point.p_;
this->id_ = point.id_;
}
void Alias(Precision_t *ptr, index_t point_id) {
this->p_.Reset(ptr);
this->id_=point_id;
}
template<typename POINTTYPE>
void Copy(POINTTYPE point, int32 dimension) {
for(int32 i=0; i<dimension; i++) {
p_[i] = point[i];
}
}
void Copy(Point_t point, int32 dimension) {
for(int32 i=0; i<dimension; i++) {
p_[i] = point[i];
}
id_=point.id_;
}
void SetNULL() {
p_=NULL;
}
void Print(int32 dimension) {
printf("values= ");
for(int32 i=0; i< dimension; i++) {
printf("%lg ", (double)this->operator[](i));
}
printf("; id="LI, id_);
}
index_t get_id() {
return id_;
}
void set_id(index_t id) {
id_ = id;
}
private:
typename Allocator_t::template ArrayPtr<Precision_t> p_;
index_t id_;
};
// use this for points where you don't care about the allocator
// this class stands only as alias to other types
template<typename PRECISION>
class Point<PRECISION, Loki::NullType> {
public:
typedef PRECISION Precision_t;
typedef Point<Precision_t, Loki::NullType> Point_t;
Point() {
this->p_=NULL;
this->id_=0;
};
Precision_t &operator[](index_t i) {
return p_[i];
}
void Alias(const Point_t &point) {
this->p_ = point.p_;
this->id_ = point.id_;
}
void Alias(Precision_t *ptr, index_t id) {
p_=ptr;
id_=id;
}
template<typename POINTTYPE>
void Copy(POINTTYPE point, int32 dimension) {
for(int32 i=0; i<dimension; i++) {
p_[i] = point[i];
}
}
void Copy(Point_t point, int32 dimension) {
for(int32 i=0; i<dimension; i++) {
p_[i] = point[i];
}
id_=point.id_;
}
void SetNULL() {
p_=NULL;
}
void Print(int32 dimension) {
printf("values= ");
for(int32 i=0; i< dimension; i++) {
printf("%lg ", (double)this->operator[](i));
}
printf("; id="LI, id_);
}
index_t get_id() {
return id_;
}
void set_id(index_t id) {
id_ = id;
}
private:
Precision_t *p_;
index_t id_;
};
template<class PRECISION>
class CompletePoint {
public:
typedef PRECISION Precision_t;
typedef CompletePoint<Precision_t> CompletePoint_t;
CompletePoint() {}
~CompletePoint(){}
CompletePoint(const CompletePoint_t &other) {
this->p_=other.p_;
this->id_=other.id_;
this->dimension_=other.dimension_;
dd return *this;
}
CompletePoint_t &operator=(const CompletePoint_t &other) {
DEBUG_ASSERT_MSG(this->dimension_==other.dimension_,
"Points have different dimensions "LI"!="LI"",
this->dimension_, other.dimension_);
memcpy(this->p_, other.p_, dimension_*sizeof(Precision_t));
this->id_=other.id_;
}
void Alias(Precision_t *ptr, index_t id, int32 dimension) {
p_=ptr;
id_=id;
dimension_=dimension;
}
private:
Precision_t *p_;
index_t id_;
int32 dimension_;
};
#endif /*POINT_H_*/
-186
View File
@@ -1,186 +0,0 @@
/*
* =====================================================================================
*
* Filename: tree.h
*
* Description: A generic multidimensional binary tree. Currently tested under
* kd-nodes and ball-nodes
*
* Version: 2.0
* Created: 02/09/2007 08:25:15 PM EST
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: This material is property of Georgia Tech Fastlab-ESP Lab,
* and it is not for distribution
*
* =====================================================================================
*/
#ifndef TREE_H_
#define TREE_H_
#include <stdio.h>
#include <string>
#include <errno.h>
#include <string.h>
#include <vector>
#include "loki/Typelist.h"
#include "fastlib/fastlib.h"
#include "show_progress.h"
template<typename TYPELIST, bool diagnostic>
class BinaryTree {
public:
// For testing purposes only
friend class BinaryTreeTest;
typedef Loki::TL::TypeAt<TYPELIST, 0>::Result Precision_t;
typedef Loki::TL::TypeAt<TYPELIST, 1>::Result Allocator_t;
typedef Loki::TL::TypeAt<TYPELIST, 2>::Result Metric_t;
typedef Loki::TL::TypeAt<TYPELIST, 3>::Result BoundingBox_t;
typedef Loki::TL::TypeAt<TYPELIST, 4>::Result NodeCachedStatistics_t;
typedef Allocator_t::template ArrayPtr<Precision_t> Array_t;
typedef Node<TYPELIST, diagnostic> Node_t;
typedef Allocator_t::template Ptr<Node> NodePtr_t;
typedef Point<Precision_t, Allocator_t> Point_t;
typedef Node_t::Result Result_t;
typedef BinaryTree<TYPELIST, bool> BinaryTree_t;
class OutPutAllocator {
public:
OutPutAllocator() {
num_=0;
}
void set_ptr(Result_t *ptr) {
ptr_=ptr;
}
Result_t *get_ptr() {
return ptr_;
}
Result_t *Allocate(int32 num_of_points, int32 range) {
Result_t *result=ptr_+num_;
num_+=range*num_of_points;
return result;
}
private:
Result_t *ptr_;
IDPRECISION num_;
};
BinaryTree();
~BinaryTree();
void Init(BinaryDataset &data);
// Call this function to build Depth first a tree
void BuildDepthFirst();
void BuildDepthFirst(Node_ptr &ptr, Pivot_t *pivot);
void BuildBreadthFirst();
void BuildBreadthFirst(list<pair<Node_ptr_ptr, Pivot_t *> > &fifo);
// Builds tree k depth first. It builds all the subtrees depth first up to k level
void SerialBuildKDepthFirst();
template<typename POINTTYPE, typename NEIGHBORTYPE>
void NearestNeighbor(POINTTYPE &test_point,
vector<pair<Precision_t, Point_t> > *nearest_point,
Precisio_t *distance,
NEIGHBORTYPE range);
// This is the core function doing the recursion, Use that only if you want
// to start the search from a particular node and not the parent
template<typename POINTTYPE, typename NEIGHBORTYPE>
void NearestNeighbor(Node_ptr ptr,
POINTTYPE &test_point,
vector<pair<Precision_t, Point_t> > *nearest_point,
Precision_t *distance,
NEIGHBORTYPE range,
bool &found);
// This is the duall tree nearest neighbors method, again it works
// for all cases k nearest/ range nearest
template<typename NEIGHBORTYPE>
void AllNearestNeighbors(Node_ptr query,
Node_ptr reference,
NEIGHBORTYPE range);
template<typename NEIGHBORTYPE>
void AllNearestNeighbors(Node_ptr query,
Node_ptr reference,
NEIGHBORTYPE range,
PRECISION distance);
void InitAllKNearestNeighborOutput(string file, int32 knns);
void CloseAllKNearestNeighborOutput(int32 knns);
void InitAllKNearestNeighborOutput(Node_ptr ptr,
int32 knns);
void InitAllRangeNearestNeighborOutput(string file, int32 range);
void CloseAllRangeNearestNeighborOutput(int32 range);
void InitAllRangeNearestNeighborOutput(Node_ptr ptr,
int32 range);
// Print the tree depth first
void Print();
void RecursivePrint(Node_ptr ptr);
// Resets the counters of the tree that keep the statistics of search
void ResetCounters() {
computations_.Reset();
}
string Statistics();
string Computations();
void set_log_file(const string &log_file);
int32 get_current_level() {
return current_level_;
};
uint64 get_num_of_points(){
return num_of_points_;
}
Node_ptr get_parent() {
return parent_;
}
void set_discriminator(PointIdentityDiscriminator<IDPRECISION> *disc) {
discriminator_.reset(disc);
}
void set_max_points_on_leaf(index_t max_point_on_leaf) {
max_points_on_leaf_=max_points_on_leaf;
}
index_t get_max_points_on_leaf() {
return max_points_on_leaf();
}
private:
// Maximum number of points on a leaf
index_t max_points_on_leaf_;
// Parent/Root
Node_ptr parent_;
// Source of data
BinaryDataset data_;
// Total number of points on the tree
index_t num_of_points_;
// Number of Leafs on the tree
index_t num_of_leafs_;
// Number of nodes (incuding leafs)
index_t node_id_;
// Current level of tree while we build it
index_t current_level_;
// Maximum depth of the tree
index_t max_depth_;
// Minimum depth of the tree
index_t min_depth_;
// Dimensionality of points
int32 dimension_;
// Total number of points visited during search
index_t total_nodes_visited_;
// Structure for keeping statistics on the comparisons and distances computed
// during search
ComputationsCounter<diagnostic> computations_;
// total number of nodes visited
index_t total_points_visited_;
// used for visualization of progress during tree build
ShowProgress progress_;
bool log_progress_;
// Output file for All nearest neighbors
OutPutAllocator all_nn_out_;
FILE *log_file_ptr_;
string log_file_;
// This is usefull for our timit experiments
boost::scoped_ptr<PointIdentityDiscriminator<IDPRECISION> >
discriminator_;
};
#include "tree_impl.h"
#endif /*TREE_H_*/