mlpack/contrib/nslagle: commit more changes
This commit is contained in:
@@ -3,9 +3,9 @@ cmake_minimum_required(VERSION 2.8)
|
||||
# we just want to recurse into the child directories here
|
||||
set(DIRS
|
||||
myKDE
|
||||
kdeDL
|
||||
nested_summation_template
|
||||
proximity_project
|
||||
#kdeDL
|
||||
#nested_summation_template
|
||||
#proximity_project
|
||||
)
|
||||
|
||||
foreach(dir ${DIRS})
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
#define INSIDE_DUALTREE_KDE_H
|
||||
|
||||
#include "mlpack/core.h"
|
||||
#include "mlpack/core/tree/spacetree.hpp"
|
||||
#include "mlpack/core/tree/binary_space_tree.hpp"
|
||||
//#include "contrib/nslagle/series_expansion/farfield_expansion.h"
|
||||
//#include "contrib/nslagle/series_expansion/local_expansion.h"
|
||||
//#include "contrib/nslagle/series_expansion/mult_farfield_expansion.h"
|
||||
@@ -248,7 +248,7 @@ class DualtreeKde {
|
||||
/** @brief The permutation mapping indices of references_ to
|
||||
* original order.
|
||||
*/
|
||||
arma::Col<size_t> old_from_new_references_;
|
||||
std::vector<size_t> old_from_new_references_;
|
||||
|
||||
////////// Private Member Functions //////////
|
||||
|
||||
@@ -342,13 +342,13 @@ class DualtreeKde {
|
||||
// }
|
||||
// else {
|
||||
// NOTIFY("Using the default dimension of %d", qset_.n_rows);
|
||||
mult_const_ = 1.0 / ka_.kernel_.CalcNormConstant(qset_.n_rows);
|
||||
mult_const_ = 1.0;// / ka_.kernel_.CalcNormConstant(qset_.n_rows);
|
||||
// }
|
||||
|
||||
// Set accuracy parameters.
|
||||
relative_error_ = CLI::GetParam<double>("relative_error");
|
||||
threshold_ = CLI::GetParam<double>("threshold") *
|
||||
ka_.kernel_.CalcNormConstant(qset_.n_rows);
|
||||
threshold_ = CLI::GetParam<double>("threshold");
|
||||
// * ka_.kernel_.CalcNormConstant(qset_.n_rows);
|
||||
|
||||
// initialize the lower and upper bound densities
|
||||
densities_l_.zeros();
|
||||
@@ -365,7 +365,7 @@ class DualtreeKde {
|
||||
num_local_prunes_ = 0;
|
||||
|
||||
printf("\nStarting fast KDE on bandwidth value of %g...\n",
|
||||
sqrt(ka_.kernel_.bandwidth_sq()));
|
||||
sqrt(ka_.Bandwidth()));
|
||||
CLI::StartTimer ("fast_kde_compute");
|
||||
|
||||
// Preprocessing step for initializing series expansion objects
|
||||
@@ -417,7 +417,7 @@ class DualtreeKde {
|
||||
(&queries == &references);
|
||||
|
||||
// Read in the number of points owned by a leaf.
|
||||
int leaflen = CLI::GetParam<int>("leaflen");
|
||||
// TODO :int leaflen = CLI::GetParam<int>("leaflen");
|
||||
|
||||
// Copy reference dataset and reference weights and compute its
|
||||
// sum.
|
||||
@@ -455,9 +455,7 @@ class DualtreeKde {
|
||||
// weights according to the permutation of the reference set in
|
||||
// the reference tree.
|
||||
CLI::StartTimer("tree_d");
|
||||
rroot_ = proximity::MakeGenMetricTree<Tree>(rset_, leaflen,
|
||||
&old_from_new_references_,
|
||||
NULL);
|
||||
rroot_ = new Tree(rset_, /*leaflen,*/old_from_new_references_);
|
||||
DualtreeKdeCommon::ShuffleAccordingToPermutation
|
||||
(rset_weights_, old_from_new_references_);
|
||||
|
||||
@@ -466,12 +464,10 @@ class DualtreeKde {
|
||||
old_from_new_queries_ = old_from_new_references_;
|
||||
}
|
||||
else {
|
||||
qroot_ = proximity::MakeGenMetricTree<Tree>(qset_, leaflen,
|
||||
&old_from_new_queries_,
|
||||
NULL);
|
||||
qroot_ = new Tree(qset_, /*leaflen,*/ old_from_new_queries_);
|
||||
}
|
||||
CLI::StopTimer("tree_d");
|
||||
|
||||
|
||||
// Initialize the density lists
|
||||
densities_l_ = arma::vec(qset_.n_cols);
|
||||
densities_e_ = arma::vec(qset_.n_cols);
|
||||
@@ -497,35 +493,35 @@ class DualtreeKde {
|
||||
{
|
||||
order = 7;
|
||||
}
|
||||
ka_.Init(bandwidth, order, qset_.n_rows);
|
||||
ka_ = kernel::GaussianKernel(bandwidth);// order, qset_.n_rows);
|
||||
}
|
||||
else if(qset_.n_rows <= 3) {
|
||||
if (!hasOrder)
|
||||
{
|
||||
order = 5;
|
||||
}
|
||||
ka_.Init(bandwidth, order, qset_.n_rows);
|
||||
ka_ = kernel::GaussianKernel(bandwidth);//, order, qset_.n_rows);
|
||||
}
|
||||
else if(qset_.n_rows <= 5) {
|
||||
if (!hasOrder)
|
||||
{
|
||||
order = 3;
|
||||
}
|
||||
ka_.Init(bandwidth, order, qset_.n_rows);
|
||||
ka_ = kernel::GaussianKernel(bandwidth);//, order, qset_.n_rows);
|
||||
}
|
||||
else if(qset_.n_rows <= 6) {
|
||||
if (!hasOrder)
|
||||
{
|
||||
order = 1;
|
||||
}
|
||||
ka_.Init(bandwidth, order, qset_.n_rows);
|
||||
ka_ = kernel::GaussianKernel(bandwidth);//, order, qset_.n_rows);
|
||||
}
|
||||
else {
|
||||
if (!hasOrder)
|
||||
{
|
||||
order = 0;
|
||||
}
|
||||
ka_.Init(bandwidth, order, qset_.n_rows);
|
||||
ka_ = kernel::GaussianKernel(bandwidth);//, order, qset_.n_rows);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,7 +530,7 @@ class DualtreeKde {
|
||||
FILE *stream = stdout;
|
||||
const char *fname = NULL;
|
||||
|
||||
if((fname = CLI::GetParam<std::string>("fast_kde_output")) != NULL) {
|
||||
if((fname = CLI::GetParam<std::string>("fast_kde_output").c_str()) != NULL) {
|
||||
stream = fopen(fname, "w+");
|
||||
}
|
||||
for(size_t q = 0; q < qset_.n_cols; q++) {
|
||||
|
||||
@@ -97,7 +97,7 @@ class DualtreeKdeCommon {
|
||||
* @param permutation The permutation.
|
||||
*/
|
||||
static void ShuffleAccordingToPermutation
|
||||
(arma::vec &v, const arma::Col<size_t> &permutation) {
|
||||
(arma::vec &v, const std::vector<size_t> &permutation) {
|
||||
|
||||
arma::vec v_tmp(v.size());
|
||||
for(size_t i = 0; i < v_tmp.size(); i++) {
|
||||
|
||||
@@ -27,7 +27,7 @@ void DualtreeKde<TKernelAux>::DualtreeKdeBase_(Tree *qnode, Tree *rnode,
|
||||
|
||||
// pairwise distance and kernel value
|
||||
double dsqd = kernel::LMetric<2,false>::Evaluate (q_col, r_col);
|
||||
double kernel_value = ka_.kernel_.EvalUnnormOnSq(dsqd);
|
||||
double kernel_value = ka_.kernel_.Evaluate(q_col,r_col);//EvalUnnormOnSq(dsqd);
|
||||
double weighted_kernel_value = rset_weights_[r] * kernel_value;
|
||||
|
||||
densities_l_[q] += weighted_kernel_value;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "dualtree_vkde.h"
|
||||
#include "naive_kde.h"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::kernel;
|
||||
|
||||
void VariableBandwidthKde(arma::mat &queries, arma::mat &references,
|
||||
@@ -267,18 +268,18 @@ int main(int argc, char *argv[]) {
|
||||
!strcmp(queries_file_name.c_str(), references_file_name.c_str());
|
||||
|
||||
// data::Load inits a arma::mat with the contents of a .csv or .arff.
|
||||
data::Load(references_file_name.c_str(), references);
|
||||
references.load(references_file_name.c_str());
|
||||
if(queries_equal_references) {
|
||||
queries = references;
|
||||
}
|
||||
else {
|
||||
data::Load(queries_file_name.c_str(), queries);
|
||||
queries.load(queries_file_name.c_str());
|
||||
}
|
||||
|
||||
// If the reference weight file name is specified, then read in,
|
||||
// otherwise, initialize to uniform weights.
|
||||
if(CLI::HasParam("dwgts")) {
|
||||
data::Load(CLI::GetParam<std::string>("dwgts").c_str(), reference_weights);
|
||||
reference_weights.load(CLI::GetParam<std::string>("dwgts").c_str());
|
||||
}
|
||||
else {
|
||||
reference_weights = arma::mat(1, references.n_cols);
|
||||
|
||||
@@ -61,9 +61,9 @@
|
||||
#define INSIDE_DUALTREE_VKDE_H
|
||||
|
||||
#include "mlpack/core.h"
|
||||
#include "mlpack/core/tree/spacetree.hpp"
|
||||
#include "mlpack/core/tree/binary_space_tree.hpp"
|
||||
//#include "contrib/dongryel/proximity_project/gen_metric_tree.h"
|
||||
//#include "dualtree_kde_common.h"
|
||||
#include "dualtree_kde_common.h"
|
||||
//#include "kde_stat.h"
|
||||
#include "mlpack/methods/neighbor_search/neighbor_search.h"
|
||||
|
||||
@@ -196,12 +196,12 @@ class DualtreeVKde {
|
||||
/** @brief The permutation mapping indices of queries_ to original
|
||||
* order.
|
||||
*/
|
||||
arma::Col<size_t> old_from_new_queries_;
|
||||
std::vector<size_t> old_from_new_queries_;
|
||||
|
||||
/** @brief The permutation mapping indices of references_ to
|
||||
* original order.
|
||||
*/
|
||||
arma::Col<size_t> old_from_new_references_;
|
||||
std::vector<size_t> old_from_new_references_;
|
||||
|
||||
////////// Private Member Functions //////////
|
||||
|
||||
@@ -287,7 +287,7 @@ class DualtreeVKde {
|
||||
// Set accuracy parameters.
|
||||
relative_error_ = CLI::GetParam<double>("relative_error");
|
||||
threshold_ = CLI::GetParam<double>("threshold") *
|
||||
kernels_[0].CalcNormConstant(qset_.n_rows());
|
||||
kernels_[0].Normalizer();//CalcNormConstant(qset_.n_rows);
|
||||
|
||||
// initialize the lower and upper bound densities
|
||||
densities_l_.zeros();
|
||||
@@ -352,7 +352,7 @@ class DualtreeVKde {
|
||||
(&queries == &references);
|
||||
|
||||
// read in the number of points owned by a leaf
|
||||
int leaflen = CLI::GetParam<int>("leaflen");
|
||||
//TODO int leaflen = CLI::GetParam<int>("leaflen");
|
||||
|
||||
// Copy reference dataset and reference weights and compute its
|
||||
// sum. rset_weight_sum_ should be the raw sum of the reference
|
||||
@@ -392,9 +392,7 @@ class DualtreeVKde {
|
||||
// weights according to the permutation of the reference set in
|
||||
// the reference tree.
|
||||
CLI::StartTimer("tree_d");
|
||||
rroot_ = proximity::MakeGenMetricTree<Tree>(rset_, leaflen,
|
||||
old_from_new_references_,
|
||||
NULL);
|
||||
rroot_ = new Tree(rset_, /*leaflen,*/ old_from_new_references_);
|
||||
DualtreeKdeCommon::ShuffleAccordingToPermutation
|
||||
(rset_weights_, old_from_new_references_);
|
||||
|
||||
@@ -403,9 +401,7 @@ class DualtreeVKde {
|
||||
old_from_new_queries_ = old_from_new_references_;
|
||||
}
|
||||
else {
|
||||
qroot_ = proximity::MakeGenMetricTree<Tree>(qset_, leaflen,
|
||||
&old_from_new_queries_,
|
||||
NULL);
|
||||
qroot_ = new Tree(qset_, /*leaflen*/ old_from_new_queries_);
|
||||
}
|
||||
CLI::StopTimer("tree_d");
|
||||
|
||||
@@ -420,16 +416,16 @@ class DualtreeVKde {
|
||||
|
||||
// Initialize the kernels for each reference point.
|
||||
int knns = CLI::GetParam<int>("knn");
|
||||
AllkNN all_knn = AllkNN(rset_, 20);
|
||||
kernels_.Init(rset_.n_cols());
|
||||
AllkNN all_knn = AllkNN(rset_, knns);
|
||||
arma::Mat<size_t> resulting_neighbors;
|
||||
arma::mat squared_distances;
|
||||
arma::mat squared_distances;
|
||||
|
||||
CLI::StartTimer("bandwidth_initialization");
|
||||
all_knn.ComputeNeighbors(resulting_neighbors, squared_distances);
|
||||
|
||||
for(size_t i = 0; i < squared_distances.size(); i += knns) {
|
||||
kernels_[i / knns].Init(sqrt(squared_distances[i + knns - 1]));
|
||||
for(size_t i = 0; i < squared_distances.size(); i += knns)
|
||||
{
|
||||
kernels_.push_back(kernel::GaussianKernel(sqrt(squared_distances[i + knns - 1])));
|
||||
}
|
||||
CLI::StopTimer("bandwidth_initialization");
|
||||
|
||||
@@ -437,11 +433,11 @@ class DualtreeVKde {
|
||||
// that have been chosen.
|
||||
double min_norm_const = DBL_MAX;
|
||||
for(size_t i = 0; i < rset_weights_.size(); i++) {
|
||||
double norm_const = kernels_[i].CalcNormConstant(qset_.n_rows());
|
||||
double norm_const = kernels_[i].Normalizer();//CalcNormConstant(qset_.n_rows);
|
||||
min_norm_const = std::min(min_norm_const, norm_const);
|
||||
}
|
||||
for(size_t i = 0; i < rset_weights_.size(); i++) {
|
||||
double norm_const = kernels_[i].CalcNormConstant(qset_.n_rows());
|
||||
double norm_const = kernels_[i].Normalizer();//CalcNormConstant(qset_.n_rows);
|
||||
rset_weights_[i] *= (min_norm_const / norm_const);
|
||||
}
|
||||
|
||||
@@ -454,11 +450,11 @@ class DualtreeVKde {
|
||||
FILE *stream = stdout;
|
||||
const char *fname = NULL;
|
||||
|
||||
if((fname = CLI::GetParam<std::string>("fast_kde_output")) != NULL)
|
||||
if((fname = CLI::GetParam<std::string>("fast_kde_output").c_str()) != NULL)
|
||||
{
|
||||
stream = fopen(fname, "w+");
|
||||
}
|
||||
for(size_t q = 0; q < qset_.n_cols(); q++) {
|
||||
for(size_t q = 0; q < qset_.n_cols; q++) {
|
||||
fprintf(stream, "%g\n", densities_e_[q]);
|
||||
}
|
||||
|
||||
|
||||
@@ -200,12 +200,12 @@ class KdeStat {
|
||||
/** @brief The far field expansion created by the reference points
|
||||
* in this node.
|
||||
*/
|
||||
typename TKernelAux::TFarFieldExpansion farfield_expansion_;
|
||||
|
||||
// TODO: typename TKernelAux::TFarFieldExpansion farfield_expansion_;
|
||||
|
||||
/** @brief The local expansion stored in this node.
|
||||
*/
|
||||
typename TKernelAux::TLocalExpansion local_expansion_;
|
||||
|
||||
// TODO :typename TKernelAux::TLocalExpansion local_expansion_;
|
||||
|
||||
/** @brief The subspace associated with this node.
|
||||
*/
|
||||
//SubspaceStat subspace_;
|
||||
@@ -213,9 +213,9 @@ class KdeStat {
|
||||
/** @brief Gets the weight sum.
|
||||
*/
|
||||
double get_weight_sum() {
|
||||
return farfield_expansion_.get_weight_sum();
|
||||
return 0.0;//farfield_expansion_.get_weight_sum();
|
||||
}
|
||||
|
||||
|
||||
/** @brief Adds the other postponed contributions.
|
||||
*/
|
||||
void AddPostponed(const KdeStat& parent_stat) {
|
||||
@@ -281,8 +281,8 @@ class KdeStat {
|
||||
}
|
||||
|
||||
void Init(const TKernelAux &ka) {
|
||||
farfield_expansion_.Init(ka);
|
||||
local_expansion_.Init(ka);
|
||||
// TODO: farfield_expansion_.Init(ka);
|
||||
// TODO: local_expansion_.Init(ka);
|
||||
}
|
||||
|
||||
void Init(const arma::mat& dataset, size_t &start, size_t &count) {
|
||||
@@ -300,8 +300,8 @@ class KdeStat {
|
||||
|
||||
void Init(const arma::vec& center, const TKernelAux &ka) {
|
||||
|
||||
farfield_expansion_.Init(center, ka);
|
||||
local_expansion_.Init(center, ka);
|
||||
// TODO: farfield_expansion_.Init(center, ka);
|
||||
// TODO: local_expansion_.Init(center, ka);
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
@@ -98,16 +98,16 @@ class NaiveKde {
|
||||
printf("\nStarting naive KDE...\n");
|
||||
CLI::StartTimer("naive_kde_compute");
|
||||
|
||||
for(size_t q = 0; q < qset_.n_cols(); q++) {
|
||||
for(size_t q = 0; q < qset_.n_cols; q++) {
|
||||
|
||||
const arma::vec q_col = qset_.unsafe_col(q);
|
||||
|
||||
// Compute unnormalized sum first.
|
||||
for(size_t r = 0; r < rset_.n_cols(); r++) {
|
||||
for(size_t r = 0; r < rset_.n_cols; r++) {
|
||||
const arma::vec r_col = rset_.unsafe_col(r);
|
||||
double dsqd = kernel::LMetric<2,false>::Evaluate(q_col, r_col);
|
||||
|
||||
densities_[q] += rset_weights_[r] * kernels_[r].EvalUnnormOnSq(dsqd);
|
||||
densities_[q] += rset_weights_[r] * kernels_[r].Evaluate(q_col,r_col);//EvalUnnormOnSq(dsqd);
|
||||
}
|
||||
|
||||
// Then normalize it.
|
||||
@@ -127,16 +127,16 @@ class NaiveKde {
|
||||
printf("\nStarting naive KDE...\n");
|
||||
CLI::StartTimer("naive_kde_compute");
|
||||
|
||||
for(size_t q = 0; q < qset_.n_cols(); q++) {
|
||||
for(size_t q = 0; q < qset_.n_cols; q++) {
|
||||
|
||||
const arma::vec q_col = qset_.unsafe_col(q);
|
||||
|
||||
// Compute unnormalized sum.
|
||||
for(size_t r = 0; r < rset_.n_cols(); r++) {
|
||||
for(size_t r = 0; r < rset_.n_cols; r++) {
|
||||
const arma::vec r_col = rset_.unsafe_col(r);
|
||||
double dsqd = kernel::LMetric<2,false>::Evaluate (q_col, r_col);
|
||||
//double dsqd = kernel::LMetric<2,false>::Evaluate (q_col, r_col);
|
||||
|
||||
densities_[q] += rset_weights_[r] * kernels_[r].EvalUnnormOnSq(dsqd);
|
||||
densities_[q] += rset_weights_[r] * kernels_[r].Evaluate(q_col,r_col);//EvalUnnormOnSq(dsqd);
|
||||
}
|
||||
// Then, normalize it.
|
||||
densities_[q] /= norm_const_;
|
||||
@@ -148,7 +148,7 @@ class NaiveKde {
|
||||
void Init(arma::mat &qset, arma::mat &rset, struct datanode *module_in) {
|
||||
|
||||
// Use the uniform weights for a moment.
|
||||
arma::mat uniform_weights(1, rset.n_cols());
|
||||
arma::mat uniform_weights(1, rset.n_cols);
|
||||
uniform_weights.fill(1.0);
|
||||
|
||||
Init(qset, rset, uniform_weights, module_in);
|
||||
@@ -184,7 +184,7 @@ class NaiveKde {
|
||||
rset_(r,c) = rset(r,c);
|
||||
}
|
||||
}
|
||||
rset_weights_ = arma::vec(reference_weights.n_cols());
|
||||
rset_weights_ = arma::vec(reference_weights.n_cols);
|
||||
for(size_t i = 0; i < rset_weights_.size(); i++)
|
||||
{
|
||||
rset_weights_[i] = reference_weights(0, i);
|
||||
@@ -197,20 +197,20 @@ class NaiveKde {
|
||||
}
|
||||
|
||||
// Get bandwidth and compute the normalizing constant.
|
||||
kernels_.Init(rset_.n_cols());
|
||||
if(!strcmp(CLI::GetParam<std::string>("mode").c_str(), "variablebw")) {
|
||||
|
||||
if(!strcmp(CLI::GetParam<std::string>("mode").c_str(), "variablebw"))
|
||||
{
|
||||
// Initialize the kernels for each reference point.
|
||||
int knns = CLI::GetParam<int>("knn");
|
||||
AllkNN all_knn = AllkNN(rset_, 20, knns);
|
||||
AllkNN all_knn = AllkNN(rset_, knns);
|
||||
arma::Mat<size_t> resulting_neighbors;
|
||||
arma::mat squared_distances;
|
||||
|
||||
CLI::StartTimer("bandwidth_initialization");
|
||||
all_knn.ComputeNeighbors(resulting_neighbors, squared_distances);
|
||||
|
||||
for(size_t i = 0; i < squared_distances.size(); i += knns) {
|
||||
kernels_[i / knns].Init(sqrt(squared_distances[i + knns - 1]));
|
||||
for(size_t i = 0; i < squared_distances.size(); i += knns)
|
||||
{
|
||||
kernels_.push_back(kernel::GaussianKernel(sqrt(squared_distances[i + knns - 1])));
|
||||
}
|
||||
CLI::StopTimer("bandwidth_initialization");
|
||||
|
||||
@@ -218,30 +218,32 @@ class NaiveKde {
|
||||
// that have been chosen.
|
||||
double min_norm_const = DBL_MAX;
|
||||
for(size_t i = 0; i < rset_weights_.size(); i++) {
|
||||
double norm_const = kernels_[i].CalcNormConstant(qset_.n_rows());
|
||||
double norm_const = kernels_[i].Normalizer();//CalcNormConstant(qset_.n_rows());
|
||||
min_norm_const = std::min(min_norm_const, norm_const);
|
||||
}
|
||||
for(size_t i = 0; i < rset_weights_.size(); i++) {
|
||||
double norm_const = kernels_[i].CalcNormConstant(qset_.n_rows());
|
||||
double norm_const = kernels_[i].Normalizer();//CalcNormConstant(qset_.n_rows());
|
||||
rset_weights_[i] *= (min_norm_const / norm_const);
|
||||
}
|
||||
|
||||
|
||||
// Compute normalization constant.
|
||||
norm_const_ = weight_sum * min_norm_const;
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < kernels_.size(); i++) {
|
||||
kernels_[i].Init(CLI::GetParam<double>("bandwidth"));
|
||||
else
|
||||
{
|
||||
for(size_t i = 0; i < kernels_.size(); i++)
|
||||
{
|
||||
kernels_[i] = kernel::GaussianKernel(CLI::GetParam<double>("bandwidth"));
|
||||
}
|
||||
norm_const_ = kernels_[0].CalcNormConstant(qset_.n_rows()) * weight_sum;
|
||||
norm_const_ = kernels_[0].Normalizer();//CalcNormConstant(qset_.n_rows()) * weight_sum;
|
||||
}
|
||||
|
||||
// Allocate density storage.
|
||||
densities_ = arma::vec(qset.n_cols());
|
||||
densities_ = arma::vec(qset.n_cols);
|
||||
densities_.zeros();
|
||||
}
|
||||
|
||||
/** @brief Output KDE results to a stream
|
||||
/** @brief Output KDE results to a stream
|
||||
*
|
||||
* If the user provided "--naive_kde_output=" argument, then the
|
||||
* output will be directed to a file whose name is provided after
|
||||
@@ -254,10 +256,10 @@ class NaiveKde {
|
||||
const char *fname = NULL;
|
||||
|
||||
{
|
||||
fname = CLI::GetParam<std::string>("naive_kde_output");
|
||||
fname = CLI::GetParam<std::string>("naive_kde_output").c_str();
|
||||
stream = fopen(fname, "w+");
|
||||
}
|
||||
for(size_t q = 0; q < qset_.n_cols(); q++) {
|
||||
for(size_t q = 0; q < qset_.n_cols; q++) {
|
||||
fprintf(stream, "%g\n", densities_[q]);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ cmake_minimum_required(VERSION 2.8)
|
||||
# Anything not in this list will not be compiled into the output library
|
||||
# Do not include test programs here
|
||||
set(SOURCES
|
||||
test_tree.cc
|
||||
kde_dual_tree.hpp
|
||||
kde_dual_tree_impl.hpp
|
||||
test_kde_dual_tree.cpp
|
||||
)
|
||||
|
||||
# add directory name to sources
|
||||
@@ -18,10 +18,10 @@ endforeach()
|
||||
set(MLPACK_CONTRIB_SRCS ${MLPACK_CONTRIB_SRCS} ${DIR_SRCS} PARENT_SCOPE)
|
||||
|
||||
# link dependencies of test executable
|
||||
add_executable(test_tree
|
||||
add_executable(test_kde_dual_tree
|
||||
EXCLUDE_FROM_ALL
|
||||
test_tree.cc
|
||||
test_kde_dual_tree.cpp
|
||||
)
|
||||
target_link_libraries(test_tree
|
||||
target_link_libraries(test_kde_dual_tree
|
||||
mlpack
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define KDE_DUAL_TREE_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <priority_queue>
|
||||
#include <queue>
|
||||
|
||||
#include <mlpack/core.h>
|
||||
#include <mlpack/core/kernels/gaussian_kernel.hpp>
|
||||
@@ -17,6 +17,7 @@ namespace mlpack
|
||||
namespace kde
|
||||
{
|
||||
/* structure within the priority queue */
|
||||
template <typename TTree = tree::BinarySpaceTree<bound::HRectBound<2> > >
|
||||
struct queueNode
|
||||
{
|
||||
TTree* T;
|
||||
@@ -28,13 +29,14 @@ struct queueNode
|
||||
size_t bLowerIndex;
|
||||
size_t bUpperIndex;
|
||||
};
|
||||
template <typename TTree = tree::BinarySpaceTree<bound::HRectBound<2> > >
|
||||
class QueueNodeCompare
|
||||
{
|
||||
bool reverse;
|
||||
public:
|
||||
QueueNodeCompare(const bool& revparam=false) : reverse(revparam) {}
|
||||
bool operator() (const struct queueNode& lhs,
|
||||
const struct queueNode& rhs) const
|
||||
bool operator() (const struct queueNode<TTree>& lhs,
|
||||
const struct queueNode<TTree>& rhs) const
|
||||
{
|
||||
if (reverse)
|
||||
return (lhs.priority>rhs.priority);
|
||||
@@ -52,6 +54,8 @@ class KdeDualTree
|
||||
/* possibly, these refer to the same object */
|
||||
TTree* referenceRoot;
|
||||
TTree* queryRoot;
|
||||
std::map<void*, size_t> nodeIndices;
|
||||
size_t nextAvailableNodeIndex;
|
||||
std::vector<size_t> referenceShuffledIndices;
|
||||
std::vector<size_t> queryShuffledIndices;
|
||||
arma::mat referenceData;
|
||||
@@ -66,17 +70,19 @@ class KdeDualTree
|
||||
double delta;
|
||||
/* relative error with respect to the density estimate */
|
||||
double epsilon;
|
||||
math::Range bandwidths;
|
||||
std::priority_queue<struct queueNode,
|
||||
std::vector<struct queueNode>,
|
||||
QueueNodeCompare> nodePriorityQueue;
|
||||
std::priority_queue<struct queueNode<TTree>,
|
||||
std::vector<struct queueNode<TTree> >,
|
||||
QueueNodeCompare<TTree> > nodePriorityQueue;
|
||||
size_t bandwidthCount;
|
||||
std::vector<double> bandwidths;
|
||||
std::vector<double> inverseBandwidths;
|
||||
double lowBandwidth;
|
||||
double highBandwidth;
|
||||
size_t levelsInTree;
|
||||
size_t queryTreeSize;
|
||||
|
||||
void SetDefaults();
|
||||
void MultiBandwidthDualTree();
|
||||
size_t MultiBandwidthDualTree();
|
||||
void MultiBandwidthDualTreeBase(TTree* Q,
|
||||
TTree* T, size_t QIndex,
|
||||
size_t lowerBIndex, size_t upperBIndex);
|
||||
@@ -88,22 +94,24 @@ class KdeDualTree
|
||||
{
|
||||
return levelsInTree - node->levelsBelow();
|
||||
}
|
||||
void Winnow(size_t bLower, size_t bUpper, size_t* newLower, size_t* newUpper);
|
||||
void Winnow(size_t level, size_t* newLower, size_t* newUpper);
|
||||
public:
|
||||
/* the two data sets are different */
|
||||
KdeDualTree (arma::mat& referenceData, arma::mat& queryData);
|
||||
/* the reference data is also the query data */
|
||||
KdeDualTree (arma::mat& referenceData);
|
||||
std::vector<double> Calculate();
|
||||
/* setters and getters */
|
||||
const math::Range& BandwidthRange() const { return bandwidthRange; }
|
||||
const size_t& BandwidthCount() const { return bandwidthCount; }
|
||||
const double& Delta() const { return delta; }
|
||||
const double& Epsilon() const { return epsilon; }
|
||||
const double& LowBandwidth() const { return lowBandwidth; }
|
||||
const double& HighBandwidth() const { return highBandwidth; }
|
||||
|
||||
void BandwidthRange(double l, double u) { bandwidthRange = math::Range(l,u); }
|
||||
size_t& BandwidthCount() { return bandwidthCount; }
|
||||
double& Delta() { return delta; }
|
||||
double& Epsilon() { return epsilon; }
|
||||
void SetBandwidthBounds(double l, double u);
|
||||
};
|
||||
}; /* end namespace kde */
|
||||
}; /* end namespace mlpack */
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MADEIT std::cout<<"made it to "<<__LINE__<<" in "<<__FILE__<<std::endl
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::kde;
|
||||
|
||||
@@ -20,8 +22,8 @@ template<typename TKernel, typename TTree>
|
||||
KdeDualTree<TKernel, TTree>::KdeDualTree (arma::mat& reference,
|
||||
arma::mat& query)
|
||||
{
|
||||
referenceRoot (new TTree (reference)),
|
||||
queryRoot (new TTree (query))
|
||||
referenceRoot = new TTree (reference, referenceShuffledIndices),
|
||||
queryRoot = new TTree (query, queryShuffledIndices);
|
||||
referenceData = reference;
|
||||
queryData = query;
|
||||
levelsInTree = queryRoot->levelsBelow();
|
||||
@@ -37,27 +39,121 @@ KdeDualTree<TKernel, TTree>::KdeDualTree (arma::mat& reference)
|
||||
|
||||
referenceRoot = new TTree (reference, referenceShuffledIndices);
|
||||
queryRoot = referenceRoot;
|
||||
queryShuffledIndices = referenceShuffledIndices;
|
||||
levelsInTree = queryRoot->levelsBelow();
|
||||
queryTreeSize = queryRoot->treeSize();
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TTree>
|
||||
KdeDualTree<TKernel, TTree>::SetDefaults()
|
||||
void KdeDualTree<TKernel, TTree>::SetDefaults()
|
||||
{
|
||||
BandwidthRange(0.01, 100.0);
|
||||
SetBandwidthBounds(0.01, 100.0);
|
||||
bandwidthCount = 10;
|
||||
delta = epsilon = 0.05;
|
||||
kernel = TKernel(1.0);
|
||||
nextAvailableNodeIndex = 0;
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TTree>
|
||||
void KdeDualTree<TKernel, TTree>::MultiBandwidthDualTree()
|
||||
std::vector<double> KdeDualTree<TKernel, TTree>::Calculate()
|
||||
{
|
||||
/* calculate the bandwidths */
|
||||
bandwidths.clear();
|
||||
inverseBandwidths.clear();
|
||||
|
||||
if (bandwidthCount > 1)
|
||||
{
|
||||
double bandwidthDelta = (highBandwidth - lowBandwidth) / (bandwidthCount - 1);
|
||||
for (size_t bIndex = 0; bIndex < bandwidthCount; ++bIndex)
|
||||
{
|
||||
bandwidths.push_back(lowBandwidth + bandwidthDelta * bIndex);
|
||||
inverseBandwidths.push_back(1.0 / bandwidths.back());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bandwidths.push_back(lowBandwidth);
|
||||
inverseBandwidths.push_back(1.0 / lowBandwidth);
|
||||
}
|
||||
|
||||
/* resize the critical matrices */
|
||||
upperBoundLevelByBandwidth.zeros(levelsInTree,bandwidthCount);
|
||||
for (size_t bIndex = 0; bIndex < bandwidthCount; ++bIndex)
|
||||
{
|
||||
arma::vec col = upperBoundLevelByBandwidth.unsafe_col(bIndex);
|
||||
col.fill(referenceRoot->count() * inverseBandwidths[bIndex]);
|
||||
}
|
||||
upperBoundLevelByBandwidth.fill(referenceRoot->count());
|
||||
lowerBoundLevelByBandwidth.zeros(levelsInTree,bandwidthCount);
|
||||
upperBoundQPointByBandwidth.zeros(queryRoot->count(),bandwidthCount);
|
||||
for (size_t bIndex = 0; bIndex < bandwidthCount; ++bIndex)
|
||||
{
|
||||
arma::vec col = upperBoundQPointByBandwidth.unsafe_col(bIndex);
|
||||
col.fill(referenceRoot->count() * inverseBandwidths[bIndex]);
|
||||
}
|
||||
lowerBoundQPointByBandwidth.zeros(queryRoot->count(),bandwidthCount);
|
||||
upperBoundQNodeByBandwidth.zeros(queryTreeSize,bandwidthCount);
|
||||
for (size_t bIndex = 0; bIndex < bandwidthCount; ++bIndex)
|
||||
{
|
||||
arma::vec col = upperBoundQNodeByBandwidth.unsafe_col(bIndex);
|
||||
col.fill(referenceRoot->count() * inverseBandwidths[bIndex]);
|
||||
}
|
||||
lowerBoundQNodeByBandwidth.zeros(queryTreeSize,bandwidthCount);
|
||||
|
||||
arma::vec dl;
|
||||
arma::vec du;
|
||||
dl.zeros(bandwidthCount);
|
||||
du.zeros(bandwidthCount);
|
||||
double priority = pow(
|
||||
queryRoot->bound().MinDistance(referenceRoot->bound()),
|
||||
0.5);
|
||||
struct queueNode<TTree> firstNode =
|
||||
{referenceRoot,queryRoot, nextAvailableNodeIndex, dl, du,
|
||||
priority, 0, bandwidthCount - 1};
|
||||
nodeIndices[queryRoot] = nextAvailableNodeIndex;
|
||||
++nextAvailableNodeIndex;
|
||||
nodePriorityQueue.push(firstNode);
|
||||
size_t finalLevel = MultiBandwidthDualTree();
|
||||
|
||||
size_t maxIndex = 0;
|
||||
double maxLogLikelihood = (upperBoundLevelByBandwidth(finalLevel,0) +
|
||||
lowerBoundLevelByBandwidth(finalLevel,0)) / 2.0;
|
||||
for (size_t bIndex = 1; bIndex < bandwidthCount; ++bIndex)
|
||||
{
|
||||
double currentLogLikelihood = (upperBoundLevelByBandwidth(finalLevel,bIndex) +
|
||||
lowerBoundLevelByBandwidth(finalLevel,bIndex)) / 2.0;
|
||||
if (currentLogLikelihood > maxLogLikelihood)
|
||||
{
|
||||
currentLogLikelihood = maxLogLikelihood;
|
||||
maxIndex = bIndex;
|
||||
}
|
||||
}
|
||||
std::cout << upperBoundLevelByBandwidth << "\n";
|
||||
std::cout << lowerBoundLevelByBandwidth << "\n";
|
||||
std::cout << "best bandwidth " << bandwidths[maxIndex] << ";\n";
|
||||
exit(1);
|
||||
std::vector<double> densities;
|
||||
for (std::vector<size_t>::iterator shuffIt = queryShuffledIndices.begin();
|
||||
shuffIt != queryShuffledIndices.end(); ++shuffIt)
|
||||
{
|
||||
densities.push_back((upperBoundQPointByBandwidth(*shuffIt, maxIndex) +
|
||||
lowerBoundQPointByBandwidth(*shuffIt, maxIndex)) / (2.0 * referenceRoot->count()));
|
||||
|
||||
}
|
||||
return densities;
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TTree>
|
||||
size_t KdeDualTree<TKernel, TTree>::MultiBandwidthDualTree()
|
||||
{
|
||||
/* current level */
|
||||
size_t v = 0;
|
||||
while (!nodePriorityQueue.empty())
|
||||
{
|
||||
/* get the first structure in the queue */
|
||||
struct queueNode queueCurrent = nodePriorityQueue.pop();
|
||||
struct queueNode<TTree> queueCurrent = nodePriorityQueue.top();
|
||||
nodePriorityQueue.pop();
|
||||
TTree* Q = queueCurrent.Q;
|
||||
TTree* T = queueCurrent.T;
|
||||
size_t sizeOfTNode = T->count();
|
||||
@@ -66,7 +162,7 @@ void KdeDualTree<TKernel, TTree>::MultiBandwidthDualTree()
|
||||
arma::vec deltaLower = queueCurrent.deltaLower;
|
||||
arma::vec deltaUpper = queueCurrent.deltaUpper;
|
||||
/* v is the level of the Q node */
|
||||
size_t v = GetLevelOfNode(Q);
|
||||
v = GetLevelOfNode(Q);
|
||||
size_t bUpper = queueCurrent.bUpperIndex;
|
||||
size_t bLower = queueCurrent.bLowerIndex;
|
||||
/* check to see whether we've reached the epsilon condition */
|
||||
@@ -96,7 +192,7 @@ void KdeDualTree<TKernel, TTree>::MultiBandwidthDualTree()
|
||||
/* return */
|
||||
if (epsilonCondition)
|
||||
{
|
||||
return;
|
||||
return v;
|
||||
}
|
||||
/* we didn't meet the criteria; let's narrow the bandwidth range */
|
||||
Winnow(v, &bLower, &bUpper);
|
||||
@@ -109,11 +205,13 @@ void KdeDualTree<TKernel, TTree>::MultiBandwidthDualTree()
|
||||
std::vector<bool> deltaCondition;
|
||||
for (size_t bIndex = bLower; bIndex <= bUpper; ++bIndex)
|
||||
{
|
||||
double bandwidth = bandwidths[bIndex];
|
||||
double dl = sizeOfTNode * kernel(dMax / bandwidth);
|
||||
double du = sizeOfTNode * kernel(dMin / bandwidth);
|
||||
double inverseBandwidth = inverseBandwidths[bIndex];
|
||||
double dl = sizeOfTNode * inverseBandwidth * kernel.Evaluate(dMax * inverseBandwidth);
|
||||
double du = sizeOfTNode * inverseBandwidth * kernel.Evaluate(dMin * inverseBandwidth);
|
||||
deltaLower(bIndex) = dl;
|
||||
deltaUpper(bIndex) = du - sizeOfTNode;
|
||||
//std::cout << "QIndex: " << QIndex << " bIndex: " << bIndex << std::endl;
|
||||
//std::cout << "max QIndex: " << queryTreeSize - 1 << std::endl;
|
||||
if ((du - dl)/(lowerBoundQNodeByBandwidth(QIndex, bIndex) + dl) < delta)
|
||||
{
|
||||
for (size_t q = Q->begin(); q < Q->end(); ++q)
|
||||
@@ -151,12 +249,12 @@ void KdeDualTree<TKernel, TTree>::MultiBandwidthDualTree()
|
||||
if (meetsDeltaCondition)
|
||||
{
|
||||
/* adjust the current structure, then reinsert it into the queue */
|
||||
queueCurrent.dl = deltaLower;
|
||||
queueCurrent.du = deltaUpper;
|
||||
queueCurrent.deltaLower = deltaLower;
|
||||
queueCurrent.deltaUpper = deltaUpper;
|
||||
queueCurrent.bUpperIndex = bUpper;
|
||||
queueCurrent.bLowerIndex = bLower;
|
||||
queueCurrent.priority += PRIORITY_MAX;
|
||||
nodePriorityQueue.insert(queueCurrent);
|
||||
nodePriorityQueue.push(queueCurrent);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -208,28 +306,45 @@ void KdeDualTree<TKernel, TTree>::MultiBandwidthDualTree()
|
||||
MultiBandwidthDualTreeBase(Q, T, QIndex, bLower, bUpper);
|
||||
}
|
||||
double priority = pow(Q->bound().MinDistance(T->bound()), 0.5);
|
||||
if (!Q->is_left() && !T->is_leaf())
|
||||
if (!Q->is_leaf() && !T->is_leaf())
|
||||
{
|
||||
struct queueNode leftLeft =
|
||||
{T->left(),Q->left(), 2*QIndex + 1, arma::vec(deltaUpper),
|
||||
arma::vec(deltaLower), priority, bLower, bUpper};
|
||||
struct queueNode leftRight =
|
||||
{T->left(),Q->right(), 2*QIndex + 2, arma::vec(deltaUpper),
|
||||
arma::vec(deltaLower), priority, bLower, bUpper};
|
||||
struct queueNode rightLeft =
|
||||
{T->right(),Q->left(), 2*QIndex + 1, arma::vec(deltaUpper),
|
||||
arma::vec(deltaLower), priority, bLower, bUpper};
|
||||
struct queueNode rightRight =
|
||||
{T->right(),Q->right(), 2*QIndex + 2, arma::vec(deltaUpper),
|
||||
arma::vec(deltaLower), priority, bLower, bUpper};
|
||||
nodePriorityQueue.insert(leftLeft);
|
||||
nodePriorityQueue.insert(leftRight);
|
||||
nodePriorityQueue.insert(rightLeft);
|
||||
nodePriorityQueue.insert(rightRight);
|
||||
//std::cout << "QIndex for the current non-leaf : " << QIndex << std::endl;
|
||||
TTree* QLeft = Q->left();
|
||||
TTree* QRight = Q->right();
|
||||
if (nodeIndices.find(QLeft) == nodeIndices.end())
|
||||
{
|
||||
nodeIndices[QLeft] = nextAvailableNodeIndex;
|
||||
++nextAvailableNodeIndex;
|
||||
}
|
||||
if (nodeIndices.find(QRight) == nodeIndices.end())
|
||||
{
|
||||
nodeIndices[QRight] = nextAvailableNodeIndex;
|
||||
++nextAvailableNodeIndex;
|
||||
}
|
||||
size_t QLeftIndex = (*(nodeIndices.find(QLeft))).second;
|
||||
size_t QRightIndex = (*(nodeIndices.find(QRight))).second;
|
||||
struct queueNode<TTree> leftLeft =
|
||||
{T->left(),Q->left(), QLeftIndex, arma::vec(deltaLower),
|
||||
arma::vec(deltaUpper), priority, bLower, bUpper};
|
||||
struct queueNode<TTree> leftRight =
|
||||
{T->left(),Q->right(), QRightIndex, arma::vec(deltaLower),
|
||||
arma::vec(deltaUpper), priority, bLower, bUpper};
|
||||
struct queueNode<TTree> rightLeft =
|
||||
{T->right(),Q->left(), QLeftIndex, arma::vec(deltaLower),
|
||||
arma::vec(deltaUpper), priority, bLower, bUpper};
|
||||
struct queueNode<TTree> rightRight =
|
||||
{T->right(),Q->right(), QRightIndex, arma::vec(deltaLower),
|
||||
arma::vec(deltaUpper), priority, bLower, bUpper};
|
||||
nodePriorityQueue.push(leftLeft);
|
||||
nodePriorityQueue.push(leftRight);
|
||||
nodePriorityQueue.push(rightLeft);
|
||||
nodePriorityQueue.push(rightRight);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TTree>
|
||||
void KdeDualTree<TKernel, TTree>::Winnow(size_t level,
|
||||
size_t* bLower,
|
||||
size_t* bUpper)
|
||||
@@ -310,14 +425,14 @@ void KdeDualTree<TKernel, TTree>::MultiBandwidthDualTreeBase(TTree* Q,
|
||||
{
|
||||
arma::vec diff = queryPoint - referenceData.unsafe_col(t);
|
||||
double distSquared = arma::dot(diff, diff);
|
||||
size_t bandwidthIndex = upperBIndex;
|
||||
size_t bandwidthIndex = upperBIndex + 1;
|
||||
while (bandwidthIndex > lowerBIndex)
|
||||
{
|
||||
--bandwidthIndex;
|
||||
double bandwidth = bandwidths[bandwidthIndex];
|
||||
double scaledProduct = pow(distSquared, 0.5) / bandwidth;
|
||||
double inverseBandwidth = inverseBandwidths[bandwidthIndex];
|
||||
double scaledProduct = pow(distSquared, 0.5) * inverseBandwidth;
|
||||
/* TODO: determine the power of the incoming argument */
|
||||
double contribution = kernel(scaledProduct);
|
||||
double contribution = inverseBandwidth * kernel.Evaluate(scaledProduct);
|
||||
if (contribution > DBL_EPSILON)
|
||||
{
|
||||
upperBoundQPointByBandwidth(q, bandwidthIndex) += contribution;
|
||||
@@ -368,6 +483,16 @@ void KdeDualTree<TKernel, TTree>::MultiBandwidthDualTreeBase(TTree* Q,
|
||||
sizeOfQNode * log(lowerBoundQNodeByBandwidth(QIndex, bIndex));
|
||||
}
|
||||
}
|
||||
template<typename TKernel, typename TTree>
|
||||
void KdeDualTree<TKernel, TTree>::SetBandwidthBounds(double l, double u)
|
||||
{
|
||||
if (u <= l + DBL_EPSILON || l <= DBL_EPSILON)
|
||||
{
|
||||
Log::Fatal << "Incorrect bandwidth range assignment" << std::endl;
|
||||
}
|
||||
lowBandwidth = l;
|
||||
highBandwidth = u;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#include <mlpack/core.h>
|
||||
#include "kde_dual_tree.hpp"
|
||||
|
||||
PROGRAM_INFO("Kernel Density Estimation Multibandwidth Dual Tree",
|
||||
"KDE multibandwidth dual tree calculates density estimates for each "
|
||||
"query point, given a collection of reference points, using a collection "
|
||||
"of equidistantly spaced bandwidths\n\n"
|
||||
"$ kde_dual_tree --reference_file=reference.csv --query_file=query.csv\n"
|
||||
" --output_file=output.csv --low_bandwidth=0.1 --high_bandwidth=100.0\n"
|
||||
" --bandwidth_count=10 --epsilon=0.01 --delta=0.01", "kde_dual_tree");
|
||||
|
||||
PARAM_STRING_REQ("reference_file", "CSV file containing the reference dataset.",
|
||||
"");
|
||||
PARAM_STRING("query_file", "CSV file containing query points",
|
||||
"", "");
|
||||
PARAM_STRING("output_file", "File to output CSV-formatted results into.", "",
|
||||
"kde_dual_tree_output.csv");
|
||||
PARAM_DOUBLE("low_bandwidth", "Low bandwidth", "", 0.1);
|
||||
PARAM_DOUBLE("high_bandwidth", "Low bandwidth", "", 100.0);
|
||||
PARAM_INT("bandwidth_count", "Low bandwidth", "", 10);
|
||||
PARAM_DOUBLE("epsilon", "error tolerance", "", 0.01);
|
||||
PARAM_DOUBLE("delta", "reversibility tolerance", "", 0.01);
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
CLI::ParseCommandLine(argc, argv);
|
||||
std::string referenceFile = CLI::GetParam<std::string>("reference_file");
|
||||
std::string queryFile = CLI::GetParam<std::string>("query_file");
|
||||
std::string outputFile = CLI::GetParam<std::string>("output_file");
|
||||
arma::mat referenceData;
|
||||
arma::mat queryData;
|
||||
double epsilon = CLI::GetParam<double>("epsilon");
|
||||
double delta = CLI::GetParam<double>("delta");
|
||||
int bandwidthCount = CLI::GetParam<int>("bandwidth_count");
|
||||
double lowBandwidth = CLI::GetParam<double>("low_bandwidth");
|
||||
double highBandwidth = CLI::GetParam<double>("high_bandwidth");
|
||||
|
||||
/* check the parameters */
|
||||
if (delta < 0.0)
|
||||
{
|
||||
Log::Fatal << "Improper delta: " << delta <<
|
||||
"; delta must be positive" << std::endl;
|
||||
}
|
||||
if (epsilon < 0.0)
|
||||
{
|
||||
Log::Fatal << "Improper epsilon: " << epsilon <<
|
||||
"; epsilon must be positive" << std::endl;
|
||||
}
|
||||
if (bandwidthCount <= 0)
|
||||
{
|
||||
Log::Fatal << "Improper bandwidth_count: " << bandwidthCount <<
|
||||
"; bandwidth_count must be positive" << std::endl;
|
||||
}
|
||||
if (highBandwidth <= lowBandwidth + DBL_EPSILON || lowBandwidth <= 0.0)
|
||||
{
|
||||
Log::Fatal << "Improper bandwidth range: " << lowBandwidth << ", " <<
|
||||
highBandwidth << "; bandwidth range must be a positive interval" << std::endl;
|
||||
}
|
||||
|
||||
if (!data::Load(referenceFile.c_str(), referenceData))
|
||||
{
|
||||
Log::Fatal << "Failed to load the reference file " << referenceFile << std::endl;
|
||||
}
|
||||
|
||||
Log::Info << "Loaded reference data from " << referenceFile << std::endl;
|
||||
|
||||
std::vector<double> densities;
|
||||
if (queryFile == "")
|
||||
{
|
||||
/* invoke KDE without specific query data */
|
||||
KdeDualTree<> kde = KdeDualTree<>(referenceData);
|
||||
kde.Epsilon() = epsilon;
|
||||
kde.Delta() = delta;
|
||||
kde.BandwidthCount() = bandwidthCount;
|
||||
kde.SetBandwidthBounds(lowBandwidth, highBandwidth);
|
||||
densities = kde.Calculate();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* invoke KDE without specific query data */
|
||||
KdeDualTree<> kde = KdeDualTree<>(referenceData, queryData);
|
||||
kde.Epsilon() = epsilon;
|
||||
kde.Delta() = delta;
|
||||
kde.BandwidthCount() = bandwidthCount;
|
||||
kde.SetBandwidthBounds(lowBandwidth, highBandwidth);
|
||||
densities = kde.Calculate();
|
||||
}
|
||||
size_t index = 0;
|
||||
for (std::vector<double>::iterator dIt = densities.begin();
|
||||
dIt != densities.end();
|
||||
++dIt)
|
||||
{
|
||||
if (*dIt != 0.0)
|
||||
{
|
||||
std::cout << "density[" << index << "]=" << *dIt << std::endl;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user