Separated out the naive algorithm into a separate file. Now algorithms are templatized for different primitive types
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
librule(
|
||||
name = "ortho_range_search",
|
||||
sources = [],
|
||||
headers = ["ortho_range_search.h",
|
||||
headers = ["data_aux.h",
|
||||
"naive_ortho_range_search.h",
|
||||
"ortho_range_search.h",
|
||||
"range_reader.h"],
|
||||
deplibs = ["fastlib:fastlib_int"]
|
||||
)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef DATA_AUX_H
|
||||
#define DATA_AUX_H
|
||||
|
||||
#include "fastlib/fastlib.h"
|
||||
|
||||
namespace data_aux {
|
||||
|
||||
/**
|
||||
* Loads a matrix from a file.
|
||||
*
|
||||
* This supports any type the Dataset class supports with the
|
||||
* InitFromFile function: CSV and ARFF.
|
||||
*
|
||||
* @code
|
||||
* Matrix A;
|
||||
* data::Load("foo.csv", &A);
|
||||
* @endcode
|
||||
*
|
||||
* @param fname the file name to load
|
||||
* @param matrix a pointer to an uninitialized matrix to load
|
||||
*/
|
||||
template<typename T>
|
||||
static success_t Load(const char *fname, GenMatrix<T> *matrix) {
|
||||
Matrix tmp_matrix;
|
||||
success_t result = data::Load(fname, &tmp_matrix);
|
||||
|
||||
// Allocate the matrix that is to be returned and copy all
|
||||
// entries.
|
||||
matrix->Init(tmp_matrix.n_rows(), tmp_matrix.n_cols());
|
||||
for(index_t c = 0; c < tmp_matrix.n_cols(); c++) {
|
||||
for(index_t r = 0; r < tmp_matrix.n_rows(); r++) {
|
||||
matrix->set(r, c, STATIC_CAST(T, tmp_matrix.get(r, c)));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,129 @@
|
||||
/** @file naive_ortho_range_search.h
|
||||
*
|
||||
* This file contains an implementation of a naive algorithm for
|
||||
* orthogonal range search.
|
||||
*
|
||||
* @author Dongryeol Lee (dongryel)
|
||||
*/
|
||||
|
||||
#ifndef NAIVE_ORTHO_RANGE_SEARCH_H
|
||||
#define NAIVE_ORTHO_RANGE_SEARCH_H
|
||||
|
||||
#include "range_reader.h"
|
||||
#include "fastlib/fastlib.h"
|
||||
|
||||
|
||||
/** @brief Naive orthogonal range search class.
|
||||
*
|
||||
* @code
|
||||
* NaiveOrthoRangeSearch search;
|
||||
* search.Init(dataset);
|
||||
* search.Compute(low_coord_limits, high_coord_limits);
|
||||
*
|
||||
* ArrayList<bool> naive_search_results;
|
||||
*
|
||||
* // Make sure that the vector is uninitialized before passing.
|
||||
* search.get_results(&naive_search_results);
|
||||
* @endcode
|
||||
*/
|
||||
template<typename T>
|
||||
class NaiveOrthoRangeSearch {
|
||||
|
||||
// This class object cannot be copied!
|
||||
FORBID_ACCIDENTAL_COPIES(NaiveOrthoRangeSearch);
|
||||
|
||||
private:
|
||||
|
||||
/** @brief The i-th position of this array tells whether the i-th
|
||||
* point is in the specified orthogonal range.
|
||||
*/
|
||||
ArrayList<bool> in_range_;
|
||||
|
||||
/** @brief The dataset.
|
||||
*/
|
||||
GenMatrix<T> data_;
|
||||
|
||||
public:
|
||||
|
||||
////////// Constructor/Destructor //////////
|
||||
|
||||
/** @brief Constructor which does not do anything.
|
||||
*/
|
||||
NaiveOrthoRangeSearch() {}
|
||||
|
||||
/** @brief Destructor which does not do anything.
|
||||
*/
|
||||
~NaiveOrthoRangeSearch() {}
|
||||
|
||||
////////// Getters/Setters //////////
|
||||
|
||||
/** @brief Retrieve the result of the search.
|
||||
*
|
||||
* @param results An uninitialized vector which will have the boolean
|
||||
* results representing the search results.
|
||||
*/
|
||||
void get_results(ArrayList<bool> *results) const {
|
||||
results->Init(in_range_.size());
|
||||
|
||||
for(index_t i = 0; i < in_range_.size(); i++) {
|
||||
(*results)[i] = in_range_[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////// User-level Functions //////////
|
||||
|
||||
/** @brief Initialize the computation object.
|
||||
*
|
||||
* @param data The data used for orthogonal range search.
|
||||
*/
|
||||
void Init(const GenMatrix<T> &data) {
|
||||
|
||||
// copy the incoming data
|
||||
data_.Copy(data);
|
||||
|
||||
// re-initialize boolean flag
|
||||
in_range_.Init(data_.n_cols());
|
||||
for(index_t i = 0; i < data_.n_cols(); i++) {
|
||||
in_range_[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief The main computation of naive orthogonal range search.
|
||||
*
|
||||
* @param low_coord_limits The lower coordinate range of the search window.
|
||||
* @param high_coord_limits The upper coordinate range of the search
|
||||
* window.
|
||||
*/
|
||||
void Compute(const GenVector<T> &low_coord_limits,
|
||||
const GenVector<T> &high_coord_limits) {
|
||||
|
||||
// Start the search.
|
||||
fx_timer_start(NULL, "naive_search");
|
||||
for(index_t i = 0; i < data_.n_cols(); i++) {
|
||||
|
||||
GenVector<T> pt;
|
||||
bool flag = true;
|
||||
data_.MakeColumnVector(i, &pt);
|
||||
|
||||
// Determine which one of the two cases we have: EXCLUDE, SUBSUME
|
||||
// first the EXCLUDE case: when dist is above the upper bound distance
|
||||
// of this dimension, or dist is below the lower bound distance of
|
||||
// this dimension
|
||||
for(index_t d = 0; d < data_.n_rows(); d++) {
|
||||
if(pt[d] < low_coord_limits[d] || pt[d] > high_coord_limits[d]) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
in_range_[i] = flag;
|
||||
}
|
||||
fx_timer_stop(NULL, "naive_search");
|
||||
|
||||
// Search is now finished.
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @file ortho_range_search.h
|
||||
*
|
||||
* This file contains an implementation of a tree-based and a naive
|
||||
* algorithm for orthogonal range search.
|
||||
* This file contains an implementation of a tree-based algorithm for
|
||||
* orthogonal range search.
|
||||
*
|
||||
* @author Dongryeol Lee (dongryel)
|
||||
*/
|
||||
@@ -11,115 +11,6 @@
|
||||
#include "range_reader.h"
|
||||
#include "fastlib/fastlib.h"
|
||||
|
||||
/** @brief Naive orthogonal range search class.
|
||||
*
|
||||
* @code
|
||||
* NaiveOrthoRangeSearch search;
|
||||
* search.Init(dataset);
|
||||
* search.Compute(low_coord_limits, high_coord_limits);
|
||||
*
|
||||
* Vector naive_search_results;
|
||||
*
|
||||
* // Make sure that the vector is uninitialized before passing.
|
||||
* search.get_results(&naive_search_results);
|
||||
* @endcode
|
||||
*/
|
||||
class NaiveOrthoRangeSearch {
|
||||
|
||||
// This class object cannot be copied!
|
||||
FORBID_ACCIDENTAL_COPIES(NaiveOrthoRangeSearch);
|
||||
|
||||
private:
|
||||
|
||||
/** @brief The i-th position of this array tells whether the i-th
|
||||
* point is in the specified orthogonal range.
|
||||
*/
|
||||
ArrayList<bool> in_range_;
|
||||
|
||||
/** @brief The dataset.
|
||||
*/
|
||||
Matrix data_;
|
||||
|
||||
public:
|
||||
|
||||
////////// Constructor/Destructor //////////
|
||||
|
||||
/** @brief Constructor which does not do anything.
|
||||
*/
|
||||
NaiveOrthoRangeSearch() {}
|
||||
|
||||
/** @brief Destructor which does not do anything.
|
||||
*/
|
||||
~NaiveOrthoRangeSearch() {}
|
||||
|
||||
////////// Getters/Setters //////////
|
||||
|
||||
/** @brief Retrieve the result of the search.
|
||||
*
|
||||
* @param results An uninitialized vector which will have the boolean
|
||||
* results representing the search results.
|
||||
*/
|
||||
void get_results(ArrayList<bool> *results) const {
|
||||
results->Init(in_range_.size());
|
||||
|
||||
for(index_t i = 0; i < in_range_.size(); i++) {
|
||||
(*results)[i] = in_range_[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////// User-level Functions //////////
|
||||
|
||||
/** @brief Initialize the computation object.
|
||||
*
|
||||
* @param data The data used for orthogonal range search.
|
||||
*/
|
||||
void Init(Matrix &data) {
|
||||
|
||||
// copy the incoming data
|
||||
data_.Copy(data);
|
||||
|
||||
// re-initialize boolean flag
|
||||
in_range_.Init(data_.n_cols());
|
||||
for(index_t i = 0; i < data_.n_cols(); i++) {
|
||||
in_range_[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief The main computation of naive orthogonal range search.
|
||||
*
|
||||
* @param low_coord_limits The lower coordinate range of the search window.
|
||||
* @param high_coord_limits The upper coordinate range of the search
|
||||
* window.
|
||||
*/
|
||||
void Compute(Vector &low_coord_limits, Vector &high_coord_limits) {
|
||||
|
||||
// Start the search.
|
||||
fx_timer_start(NULL, "naive_search");
|
||||
for(index_t i = 0; i < data_.n_cols(); i++) {
|
||||
|
||||
Vector pt;
|
||||
bool flag = true;
|
||||
data_.MakeColumnVector(i, &pt);
|
||||
|
||||
// Determine which one of the two cases we have: EXCLUDE, SUBSUME
|
||||
// first the EXCLUDE case: when dist is above the upper bound distance
|
||||
// of this dimension, or dist is below the lower bound distance of
|
||||
// this dimension
|
||||
for(index_t d = 0; d < data_.n_rows(); d++) {
|
||||
if(pt[d] < low_coord_limits[d] || pt[d] > high_coord_limits[d]) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
in_range_[i] = flag;
|
||||
}
|
||||
fx_timer_stop(NULL, "naive_search");
|
||||
|
||||
// Search is now finished.
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** @brief Faster orthogonal range search class using a tree.
|
||||
*
|
||||
@@ -134,6 +25,7 @@ class NaiveOrthoRangeSearch {
|
||||
* search.get_results(&search_results);
|
||||
* @endcode
|
||||
*/
|
||||
template<typename T>
|
||||
class OrthoRangeSearch {
|
||||
|
||||
// This class object cannot be copied!
|
||||
@@ -188,7 +80,8 @@ class OrthoRangeSearch {
|
||||
* @param high_coord_limits The upper coordinate range of the search
|
||||
* window.
|
||||
*/
|
||||
void Compute(Vector &low_coord_limits, Vector &high_coord_limits) {
|
||||
void Compute(const GenVector<T> &low_coord_limits,
|
||||
const GenVector<T> &high_coord_limits) {
|
||||
|
||||
fx_timer_start(NULL, "tree_range_search");
|
||||
ortho_range_search(root_, 0, low_coord_limits, high_coord_limits);
|
||||
@@ -258,7 +151,8 @@ class OrthoRangeSearch {
|
||||
* If not NULL, the tree is loaded from the
|
||||
* file whose name is given as the argument.
|
||||
*/
|
||||
void Init(Matrix &dataset, bool make_copy, const char *load_tree_file_name) {
|
||||
void Init(GenMatrix<T> &dataset, bool make_copy,
|
||||
const char *load_tree_file_name) {
|
||||
|
||||
int leaflen = fx_param_int(NULL, "leaflen", 20);
|
||||
|
||||
@@ -295,7 +189,7 @@ class OrthoRangeSearch {
|
||||
private:
|
||||
|
||||
/** @brief This defines the type of the tree used in this algorithm. */
|
||||
typedef BinarySpaceTree<DHrectBound<2>, Matrix> Tree;
|
||||
typedef BinarySpaceTree<DHrectBound<2>, GenMatrix<T> > Tree;
|
||||
|
||||
/** @brief Flag determining a prune */
|
||||
enum PruneStatus {SUBSUME, INCONCLUSIVE, EXCLUDE};
|
||||
@@ -303,7 +197,7 @@ class OrthoRangeSearch {
|
||||
////////// Private Member Variables //////////
|
||||
|
||||
/** @brief Pointer to the dataset */
|
||||
Matrix data_;
|
||||
GenMatrix<T> data_;
|
||||
|
||||
/** @brief Buffer for loading up old_from_new mapping. */
|
||||
ArrayList<index_t> *old_from_new_buffer_;
|
||||
@@ -367,11 +261,11 @@ class OrthoRangeSearch {
|
||||
printf("Tree has been loaded...\n");
|
||||
|
||||
// apply permutation to the dataset
|
||||
Matrix tmp_data;
|
||||
GenMatrix<T> tmp_data;
|
||||
tmp_data.Init(data_.n_rows(), data_.n_cols());
|
||||
|
||||
for(index_t i = 0; i < data_.n_cols(); i++) {
|
||||
Vector source, dest;
|
||||
GenVector<T> source, dest;
|
||||
data_.MakeColumnVector(i, &source);
|
||||
tmp_data.MakeColumnVector(new_from_old_[i], &dest);
|
||||
dest.CopyValues(source);
|
||||
@@ -388,8 +282,8 @@ class OrthoRangeSearch {
|
||||
* @param high_coord_limits The upper coordinate limits of the search.
|
||||
*/
|
||||
void ortho_slow_range_search(Tree *node, int start_dim,
|
||||
const Vector &low_coord_limits,
|
||||
const Vector &high_coord_limits) {
|
||||
const GenVector<T> &low_coord_limits,
|
||||
const GenVector<T> &high_coord_limits) {
|
||||
PruneStatus prune_flag;
|
||||
|
||||
for(index_t row = node->begin(); row < node->end(); row++) {
|
||||
@@ -427,8 +321,8 @@ class OrthoRangeSearch {
|
||||
* window.
|
||||
*/
|
||||
void ortho_range_search(Tree *node, int start_dim,
|
||||
const Vector &low_coord_limits,
|
||||
const Vector &high_coord_limits) {
|
||||
const GenVector<T> &low_coord_limits,
|
||||
const GenVector<T> &high_coord_limits) {
|
||||
|
||||
PruneStatus prune_flag = SUBSUME;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
*
|
||||
* @author Dongryeol Lee (dongryel)
|
||||
*/
|
||||
#include "data_aux.h"
|
||||
#include "naive_ortho_range_search.h"
|
||||
#include "ortho_range_search.h"
|
||||
|
||||
/** Main function which reads parameters and runs the orthogonal
|
||||
@@ -67,14 +69,14 @@ int main(int argc, char *argv[]) {
|
||||
const char* dataset_file_name = fx_param_str(NULL, "data", "data.ds");
|
||||
|
||||
// column-oriented dataset matrix.
|
||||
Matrix dataset;
|
||||
GenMatrix<double> dataset;
|
||||
|
||||
// data::Load inits a matrix with the contents of a .csv or .arff.
|
||||
data::Load(dataset_file_name, &dataset);
|
||||
data_aux::Load(dataset_file_name, &dataset);
|
||||
|
||||
// Read the search range from the file.
|
||||
const char *range_data_file_name = fx_param_str(NULL, "range", "range.ds");
|
||||
Vector low_coord_limits, high_coord_limits;
|
||||
GenVector<double> low_coord_limits, high_coord_limits;
|
||||
RangeReader::ReadRangeData(&low_coord_limits, &high_coord_limits,
|
||||
dataset, range_data_file_name);
|
||||
|
||||
@@ -92,7 +94,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
// Declare fast tree-based orthogonal range search algorithm object.
|
||||
OrthoRangeSearch fast_search;
|
||||
OrthoRangeSearch<double> fast_search;
|
||||
fast_search.Init(dataset, fx_param_exists(NULL, "do_naive"),
|
||||
load_tree_file_name);
|
||||
fast_search.Compute(low_coord_limits, high_coord_limits);
|
||||
@@ -108,7 +110,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// if naive option is specified, do naive algorithm
|
||||
if(do_naive) {
|
||||
NaiveOrthoRangeSearch search;
|
||||
NaiveOrthoRangeSearch<double> search;
|
||||
search.Init(dataset);
|
||||
search.Compute(low_coord_limits, high_coord_limits);
|
||||
ArrayList<bool> naive_search_results;
|
||||
|
||||
@@ -39,9 +39,10 @@ class RangeReader {
|
||||
* rows of the text file to read in).
|
||||
* @param range_data_file_name The file to read the range data from.
|
||||
*/
|
||||
static void ReadRangeData(Vector *low_coord_limits,
|
||||
Vector *high_coord_limits,
|
||||
Matrix &dataset,
|
||||
template<typename T>
|
||||
static void ReadRangeData(GenVector<T> *low_coord_limits,
|
||||
GenVector<T> *high_coord_limits,
|
||||
GenMatrix<T> &dataset,
|
||||
const char *range_data_file_name) {
|
||||
|
||||
TextTokenizer tokenizer;
|
||||
|
||||
Reference in New Issue
Block a user