From 0f0eef79f081d502b8a2d20b4a4acd67aa9c4a82 Mon Sep 17 00:00:00 2001 From: Dongryeol Lee Date: Mon, 21 Jan 2008 01:53:59 +0000 Subject: [PATCH] Fast KDE is now using submodule for organizing parameters --- fastlib/u/dongryel/kde/dataset_scaler.h | 12 +++- fastlib/u/dongryel/kde/kde.h | 93 +++++++++++++++++-------- fastlib/u/dongryel/kde/kde_main.cc | 48 +++++++------ fastlib/u/dongryel/kde/naive_kde.h | 26 ++++--- fastlib/u/dongryel/kde/thor_kde.h | 44 +++++++++++- 5 files changed, 160 insertions(+), 63 deletions(-) diff --git a/fastlib/u/dongryel/kde/dataset_scaler.h b/fastlib/u/dongryel/kde/dataset_scaler.h index 18f816c0f6..82e2128a96 100644 --- a/fastlib/u/dongryel/kde/dataset_scaler.h +++ b/fastlib/u/dongryel/kde/dataset_scaler.h @@ -1,7 +1,17 @@ +/** + * @file dataset_scaler.h + * + * This file contains utility functions to scale the given query and + * reference dataset pair. + * + * @author Dongryeol Lee (dongryel) + * @bug No known bugs. + */ + #ifndef DATASET_SCALER_H #define DATASET_SACLER_H -#include "fastlib/fastlib_int.h" +#include class DatasetScaler { diff --git a/fastlib/u/dongryel/kde/kde.h b/fastlib/u/dongryel/kde/kde.h index 63513e8ec6..520b138978 100644 --- a/fastlib/u/dongryel/kde/kde.h +++ b/fastlib/u/dongryel/kde/kde.h @@ -5,33 +5,61 @@ * for a linkable library component. It implements a rudimentary * depth-first dual-tree algorithm with finite difference and * series-expansion approximations, using the formalized GNP framework - * by Ryan and Garry. + * by Ryan and Garry. Currently, it supports a fixed-bandwidth, + * uniform weight kernel density estimation with no multi-bandwidth + * optimizations. We assume that users will be able to cross-validate + * for the optimal bandwidth using a black-box optimizer which is not + * implemented in this code. * * For more details on mathematical details, please take a look at the - * published conference papers: + * published conference papers (in chronological order): + * + * @inproceedings{DBLP:conf/sdm/GrayM03, + * author = {Alexander G. Gray and + * Andrew W. Moore}, + * title = {Nonparametric Density Estimation: Toward Computational + * Tractability}, + * booktitle = {SDM}, + * year = {2003}, + * ee = {http://www.siam.org/meetings/sdm03/proceedings/sdm03_19.pdf}, + * crossref = {DBLP:conf/sdm/2003}, + * bibsource = {DBLP, http://dblp.uni-trier.de} + * } + * + * @misc{ gray03rapid, + * author = "A. Gray and A. Moore", + * title = "Rapid evaluation of multiple density models", + * booktitle = "In C. M. Bishop and B. J. Frey, editors, + * Proceedings of the Ninth International Workshop on + * Artificial Intelligence and Statistics", + * year = "2003", + * url = "citeseer.ist.psu.edu/gray03rapid.html" + * } * * @incollection{NIPS2005_570, - * title = {Dual-Tree Fast Gauss Transforms}, - * author = {Dongryeol Lee and Alexander Gray and Andrew Moore}, - * booktitle = {Advances in Neural Information Processing Systems 18}, - * editor = {Y. Weiss and B. Sch\"{o}lkopf and J. Platt}, - * publisher = {MIT Press}, - * address = {Cambridge, MA}, - * pages = {747--754}, - * year = {2006} + * title = {Dual-Tree Fast Gauss Transforms}, + * author = {Dongryeol Lee and Alexander Gray and Andrew Moore}, + * booktitle = {Advances in Neural Information Processing Systems 18}, + * editor = {Y. Weiss and B. Sch\"{o}lkopf and J. Platt}, + * publisher = {MIT Press}, + * address = {Cambridge, MA}, + * pages = {747--754}, + * year = {2006} * } * * @inproceedings{DBLP:conf/uai/LeeG06, - * author = {Dongryeol Lee and - * Alexander G. Gray}, - * title = {Faster Gaussian Summation: Theory and Experiment}, - * booktitle = {UAI}, - * year = {2006}, - * crossref = {DBLP:conf/uai/2006}, - * bibsource = {DBLP, http://dblp.uni-trier.de} + * author = {Dongryeol Lee and + * Alexander G. Gray}, + * title = {Faster Gaussian Summation: Theory and Experiment}, + * booktitle = {UAI}, + * year = {2006}, + * crossref = {DBLP:conf/uai/2006}, + * bibsource = {DBLP, http://dblp.uni-trier.de} * } * + * @author Dongryeol Lee (dongryel) * @see kde_main.cc + * @bugs No known bugs. */ #ifndef KDE_H @@ -120,7 +148,7 @@ class FastKde { // get bandwidth and relative error bandwidth_ = fx_param_double_req(module, "bandwidth"); - relative_error_ = fx_param_double(module, "tau", 0.1); + relative_error_ = fx_param_double(module, "relative_error", 0.1); // temporarily initialize these to -1's dimension_ = reference_count_ = query_count_ = -1; @@ -390,22 +418,17 @@ class FastKde { summary_result_.Init(param); } - void Init() { - } - void Init(const TKernelAux &ka) { farfield_expansion_.Init(ka); local_expansion_.Init(ka); } void Init(const Matrix& dataset, index_t &start, index_t &count) { - Init(); } void Init(const Matrix& dataset, index_t &start, index_t &count, const KdeStat& left_stat, const KdeStat& right_stat) { - Init(); } void Init(const Vector& center, const TKernelAux &ka) { @@ -425,6 +448,9 @@ class FastKde { ////////// Private Member Variables ////////// + /** module used to pass parameters into the FastKde object */ + struct datanode *module_; + /** parameter list */ Param parameters_; @@ -861,6 +887,8 @@ class FastKde { FastKde() { qroot_ = NULL; rroot_ = NULL; + + DEBUG_POISON_PTR(module_); } /** destructor */ @@ -956,10 +984,17 @@ class FastKde { /** initialize query and reference sets and construct trees */ void Init(Matrix &queries, Matrix &references, - bool queries_equal_references) { + bool queries_equal_references, struct datanode *module_in) { + + // the datasets need to have the same dimensionality + DEBUG_SAME_SIZE(queries.n_rows(), references.n_rows()); + + // set class module pointer to the incoming one + module_ = module_in; // read in the number of points owned by a leaf - int leaflen = fx_param_int(NULL, "leaflen", 20); + int leaflen = fx_param_int(module_, "leaflen", 20); + DEBUG_ASSERT(leaflen > 0); // copy the datasetsread reference dataset rset_.Copy(references); @@ -975,7 +1010,7 @@ class FastKde { rset_weights_.SetAll(1); // construct query and reference trees - fx_timer_start(NULL, "tree_d"); + fx_timer_start(module_, "tree_building"); rroot_ = tree::MakeKdTreeMidpoint(rset_, leaflen, &old_from_new_references_, NULL); @@ -987,7 +1022,7 @@ class FastKde { qroot_ = tree::MakeKdTreeMidpoint(qset_, leaflen, &old_from_new_queries_, NULL); } - fx_timer_stop(NULL, "tree_d"); + fx_timer_stop(module_, "tree_building"); // initialize the density lists q_results_.Init(qset_.n_cols()); @@ -996,7 +1031,7 @@ class FastKde { } // initialize parameter list - parameters_.Init(fx_root); + parameters_.Init(module_); parameters_.reference_count_ = rset_.n_cols(); parameters_.query_count_ = qset_.n_cols(); parameters_.FinalizeInit(fx_root, rset_.n_rows()); @@ -1008,7 +1043,7 @@ class FastKde { FILE *stream = stdout; const char *fname = NULL; - if((fname = fx_param_str(NULL, "fast_kde_output", NULL)) != NULL) { + if((fname = fx_param_str(module_, "fast_kde_output", NULL)) != NULL) { stream = fopen(fname, "w+"); } for(index_t q = 0; q < qset_.n_cols(); q++) { diff --git a/fastlib/u/dongryel/kde/kde_main.cc b/fastlib/u/dongryel/kde/kde_main.cc index 7f06db339b..4ebc80feac 100644 --- a/fastlib/u/dongryel/kde/kde_main.cc +++ b/fastlib/u/dongryel/kde/kde_main.cc @@ -9,6 +9,13 @@ int main(int argc, char *argv[]) { ////////// READING PARAMETERS AND LOADING DATA ///////////////////// + // FASTexec organizes parameters and results into submodules. Think + // of this as creating a new folder named "kde_module" under the + // root directory (NULL) for the Kde object to work inside. Here, + // we initialize it with all parameters defined "--kde/...=...". + struct datanode* kde_module = + fx_submodule(NULL, "kde", "kde_module"); + // The reference data file is a required parameter. const char* references_file_name = fx_param_str_req(NULL, "data"); @@ -17,10 +24,9 @@ int main(int argc, char *argv[]) { fx_param_str(NULL, "query", references_file_name); // flag for determining whether to compute naively - bool do_naive = fx_param_exists(NULL, "do_naive"); + bool do_naive = fx_param_exists(kde_module, "do_naive"); - // FASTlib classes only poison data in their default constructors; - // declarations must be followed by Init or an equivalent function. + // query and reference datasets Matrix references; Matrix queries; @@ -36,26 +42,27 @@ int main(int argc, char *argv[]) { else { data::Load(queries_file_name, &queries); } - + // confirm whether the user asked for scaling of the dataset - if(!strcmp(fx_param_str(NULL, "scaling", "none"), "range")) { - DatasetScaler::ScaleDataByMinMax(queries, references, - queries_equal_references); + if(!strcmp(fx_param_str(kde_module, "scaling", "none"), "range")) { + DatasetScaler::ScaleDataByMinMax(queries, references, + queries_equal_references); } - if(!strcmp(fx_param_str(NULL, "kernel", "gaussian"), "gaussian")) { + if(!strcmp(fx_param_str(kde_module, "kernel", "gaussian"), "gaussian")) { Vector fast_kde_results; // for O(p^D) expansion - if(fx_param_exists(NULL, "multiplicative_expansion")) { + if(fx_param_exists(kde_module, "multiplicative_expansion")) { printf("O(p^D) expansion KDE\n"); FastKde fast_kde; - fast_kde.Init(queries, references, queries_equal_references); + fast_kde.Init(queries, references, queries_equal_references, + kde_module); fast_kde.Compute(); - if(fx_param_exists(NULL, "fast_kde_output")) { + if(fx_param_exists(kde_module, "fast_kde_output")) { fast_kde.PrintDebug(); } @@ -67,10 +74,11 @@ int main(int argc, char *argv[]) { printf("O(D^p) expansion KDE\n"); FastKde fast_kde; - fast_kde.Init(queries, references, queries_equal_references); + fast_kde.Init(queries, references, queries_equal_references, + kde_module); fast_kde.Compute(); - if(fx_param_exists(NULL, "fast_kde_output")) { + if(fx_param_exists(kde_module, "fast_kde_output")) { fast_kde.PrintDebug(); } @@ -79,22 +87,22 @@ int main(int argc, char *argv[]) { if(do_naive) { NaiveKde naive_kde; - naive_kde.Init(queries, references); + naive_kde.Init(queries, references, kde_module); naive_kde.Compute(); - if(fx_param_exists(NULL, "naive_kde_output")) { + if(fx_param_exists(kde_module, "naive_kde_output")) { naive_kde.PrintDebug(); } naive_kde.ComputeMaximumRelativeError(fast_kde_results); } } - else if(!strcmp(fx_param_str(NULL, "kernel", "epan"), "epan")) { + else if(!strcmp(fx_param_str(kde_module, "kernel", "epan"), "epan")) { FastKde fast_kde; - fast_kde.Init(queries, references, queries_equal_references); + fast_kde.Init(queries, references, queries_equal_references, kde_module); fast_kde.Compute(); - if(fx_param_exists(NULL, "fast_kde_output")) { + if(fx_param_exists(kde_module, "fast_kde_output")) { fast_kde.PrintDebug(); } Vector fast_kde_results; @@ -102,10 +110,10 @@ int main(int argc, char *argv[]) { if(do_naive) { NaiveKde naive_kde; - naive_kde.Init(queries, references); + naive_kde.Init(queries, references, kde_module); naive_kde.Compute(); - if(fx_param_exists(NULL, "naive_kde_output")) { + if(fx_param_exists(kde_module, "naive_kde_output")) { naive_kde.PrintDebug(); } naive_kde.ComputeMaximumRelativeError(fast_kde_results); diff --git a/fastlib/u/dongryel/kde/naive_kde.h b/fastlib/u/dongryel/kde/naive_kde.h index 6facacb4c1..b6b701c286 100644 --- a/fastlib/u/dongryel/kde/naive_kde.h +++ b/fastlib/u/dongryel/kde/naive_kde.h @@ -8,6 +8,9 @@ class NaiveKde { private: + /** pointer to the module */ + struct datanode *module_; + /** query dataset */ Matrix qset_; @@ -22,16 +25,18 @@ class NaiveKde { public: - NaiveKde() { + /** constructor - does not do anything */ + NaiveKde() { } + /** destructor - does not do anything */ ~NaiveKde() { } void Compute() { printf("\nStarting naive KDE...\n"); - fx_timer_start(NULL, "naive_kde_compute"); + fx_timer_start(module_, "naive_kde_compute"); // compute unnormalized sum for(index_t q = 0; q < qset_.n_cols(); q++) { @@ -51,22 +56,21 @@ class NaiveKde { for(index_t q = 0; q < qset_.n_cols(); q++) { densities_[q] /= norm_const; } - fx_timer_stop(NULL, "naive_kde_compute"); + fx_timer_stop(module_, "naive_kde_compute"); printf("\nNaive KDE completed...\n"); } - void Init() { - densities_.SetZero(); - } + void Init(Matrix &qset, Matrix &rset, struct datanode *module_in) { - void Init(Matrix &qset, Matrix &rset) { + // set the datanode module to be the incoming one + module_ = module_in; // get datasets qset_.Copy(qset); rset_.Copy(rset); // get bandwidth - kernel_.Init(fx_param_double_req(NULL, "bandwidth")); + kernel_.Init(fx_param_double_req(module_, "bandwidth")); // allocate density storage densities_.Init(qset.n_cols()); @@ -78,8 +82,8 @@ class NaiveKde { FILE *stream = stdout; const char *fname = NULL; - if(fx_param_exists(NULL, "naive_kde_output")) { - fname = fx_param_str(NULL, "naive_kde_output", NULL); + if(fx_param_exists(module_, "naive_kde_output")) { + fname = fx_param_str(module_, "naive_kde_output", NULL); stream = fopen(fname, "w+"); } for(index_t q = 0; q < qset_.n_cols(); q++) { @@ -103,7 +107,7 @@ class NaiveKde { } } - fx_format_result(NULL, "maxium_relative_error_for_fast_KDE", "%g", + fx_format_result(module_, "maximum_relative_error_for_fast_KDE", "%g", max_rel_err); } diff --git a/fastlib/u/dongryel/kde/thor_kde.h b/fastlib/u/dongryel/kde/thor_kde.h index 6f4ff43dcc..bb9f4a4172 100644 --- a/fastlib/u/dongryel/kde/thor_kde.h +++ b/fastlib/u/dongryel/kde/thor_kde.h @@ -1,11 +1,51 @@ +/** + * @file thor_kde.h + * + * This file contains an implementation of kernel density estimation + * (vanilla finite-difference only) for a linkable library component + * using the THOR library by Ryan and Garry. Currently, it supports a + * fixed-bandwidth, uniform weight kernel density estimation with no + * multi-bandwidth optimizations. We assume that users will be able to + * cross-validate for the optimal bandwidth using a black-box + * optimizer which is not implemented in this code. + * + * For more details on mathematical details, please take a look at the + * published conference papers (in chronological order): + * + * @inproceedings{DBLP:conf/sdm/GrayM03, + * author = {Alexander G. Gray and + * Andrew W. Moore}, + * title = {Nonparametric Density Estimation: Toward Computational + * Tractability}, + * booktitle = {SDM}, + * year = {2003}, + * ee = {http://www.siam.org/meetings/sdm03/proceedings/sdm03_19.pdf}, + * crossref = {DBLP:conf/sdm/2003}, + * bibsource = {DBLP, http://dblp.uni-trier.de} + * } + * + * @misc{ gray03rapid, + * author = "A. Gray and A. Moore", + * title = "Rapid evaluation of multiple density models", + * booktitle = "In C. M. Bishop and B. J. Frey, editors, + * Proceedings of the Ninth International Workshop on + * Artificial Intelligence and Statistics", + * year = "2003", + * url = "citeseer.ist.psu.edu/gray03rapid.html" + * } + * + * @author Dongryeol Lee (dongryel) + * @see thor_kde_main.cc + * @bugs No known bugs. + */ + #ifndef THOR_KDE_H #define THOR_KDE_H -#include "fastlib/fastlib_int.h" +#include #include "thor/thor.h" #include "u/dongryel/series_expansion/kernel_aux.h" - /** * THOR-based KDE */