Combined error bound computation and derivative computations into a single class
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
#include "fastlib/fastlib_int.h"
|
||||
#include "u/dongryel/series_expansion/farfield_expansion.h"
|
||||
#include "u/dongryel/series_expansion/local_expansion.h"
|
||||
#include "u/dongryel/series_expansion/kernel_derivative.h"
|
||||
#include "u/dongryel/series_expansion/kernel_aux.h"
|
||||
|
||||
template<typename TKernel>
|
||||
class NaiveKde {
|
||||
@@ -105,7 +105,7 @@ class NaiveKde {
|
||||
};
|
||||
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
class FastKde {
|
||||
|
||||
public:
|
||||
@@ -156,12 +156,12 @@ class FastKde {
|
||||
/**
|
||||
* Far field expansion created by the reference points in this node.
|
||||
*/
|
||||
FarFieldExpansion<TKernel, TKernelDerivative> farfield_expansion_;
|
||||
FarFieldExpansion<TKernel, TKernelAux> farfield_expansion_;
|
||||
|
||||
/**
|
||||
* Local expansion stored in this node.
|
||||
*/
|
||||
LocalExpansion<TKernel, TKernelDerivative> local_expansion_;
|
||||
LocalExpansion<TKernel, TKernelAux> local_expansion_;
|
||||
|
||||
/** Initialize the statistics */
|
||||
void Init() {
|
||||
@@ -213,7 +213,7 @@ class FastKde {
|
||||
|
||||
void PushDownTokens(KdeStat &left_stat, KdeStat &right_stat,
|
||||
double *de,
|
||||
LocalExpansion<TKernel, TKernelDerivative>
|
||||
LocalExpansion<TKernel, TKernelAux>
|
||||
*local_expansion, double *dt) {
|
||||
|
||||
if(de != NULL) {
|
||||
@@ -434,9 +434,9 @@ class FastKde {
|
||||
KdeStat &rstat = rnode->stat();
|
||||
|
||||
// expansion objects
|
||||
FarFieldExpansion<TKernel, TKernelDerivative> &farfield_expansion
|
||||
FarFieldExpansion<TKernel, TKernelAux> &farfield_expansion
|
||||
= rstat.farfield_expansion_;
|
||||
LocalExpansion<TKernel, TKernelDerivative> &local_expansion
|
||||
LocalExpansion<TKernel, TKernelAux> &local_expansion
|
||||
= qstat.local_expansion_;
|
||||
|
||||
// number of reference points
|
||||
@@ -460,7 +460,7 @@ class FastKde {
|
||||
|
||||
// get the order of approximations
|
||||
order_farfield_to_local_ =
|
||||
farfield_expansion.OrderForConvertingtoLocal(rnode->bound(),
|
||||
farfield_expansion.OrderForConvertingToLocal(rnode->bound(),
|
||||
qnode->bound(),
|
||||
dsqd_range.lo, allowed_err,
|
||||
&actual_err);
|
||||
|
||||
@@ -8,7 +8,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
bool do_naive = fx_param_exists(NULL, "do_naive");
|
||||
|
||||
FastKde<GaussianKernel, GaussianKernelDerivative> fast_kde;
|
||||
FastKde<GaussianKernel, GaussianKernelAux> fast_kde;
|
||||
fast_kde.Init();
|
||||
fast_kde.Compute(fx_param_double(NULL, "tau", 0.1));
|
||||
|
||||
@@ -31,10 +31,11 @@ int main(int argc, char *argv[]) {
|
||||
naive_kde.ComputeMaximumRelativeError(fast_kde_results);
|
||||
}
|
||||
|
||||
/*
|
||||
FFTKde fft_kde;
|
||||
fft_kde.Init(fast_kde.get_query_dataset(),
|
||||
fast_kde.get_reference_dataset());
|
||||
|
||||
*/
|
||||
fx_done();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
|
||||
if(!strcmp(kernel, "gaussianthreebody")) {
|
||||
fx_timer_start(NULL, "multibody");
|
||||
MultitreeMultibody<GaussianThreeBodyKernel,
|
||||
GaussianKernel, GaussianKernelDerivative> mtmb;
|
||||
GaussianKernel, GaussianKernelAux> mtmb;
|
||||
mtmb.Init(bandwidth);
|
||||
mtmb.Compute(tau);
|
||||
fx_timer_stop(NULL, "multibody");
|
||||
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
|
||||
else if(!strcmp(kernel, "axilrodteller")) {
|
||||
fx_timer_start(NULL, "multibody");
|
||||
MultitreeMultibody<AxilrodTellerKernel,
|
||||
GaussianKernel, GaussianKernelDerivative> mtmb;
|
||||
GaussianKernel, GaussianKernelAux> mtmb;
|
||||
mtmb.Init(bandwidth);
|
||||
mtmb.Compute(tau);
|
||||
fx_timer_stop(NULL, "multibody");
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define MULTIBODY_KERNEL_H
|
||||
|
||||
#include "fastlib/fastlib_int.h"
|
||||
#include "u/dongryel/series_expansion/kernel_derivative.h"
|
||||
#include "u/dongryel/series_expansion/kernel_aux.h"
|
||||
|
||||
class GaussianThreeBodyKernel {
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ class PCAStat {
|
||||
// extract the relevant part of the dataset and mean-center it
|
||||
ExtractSubMatrix(dataset, start, count, orig_mean_centered_);
|
||||
ComputeColumnMeanVector(orig_mean_centered_, means_);
|
||||
SubtractVectorFromMatrix(orig_mean_centered_, means_, orig_mean_centered_);
|
||||
//SubtractVectorFromMatrix(orig_mean_centered_, means_, orig_mean_centered_);
|
||||
|
||||
// compute PCA on the extracted submatrix
|
||||
Matrix U, VT;
|
||||
@@ -144,7 +144,7 @@ class PCAStat {
|
||||
|
||||
// reduce the dimension in half
|
||||
Matrix U_trunc;
|
||||
int new_dimension = U.n_cols();
|
||||
int new_dimension = U.n_cols() / 2;
|
||||
U_trunc.Init(new_dimension, U.n_rows());
|
||||
for(index_t i = 0; i < new_dimension; i++) {
|
||||
Vector s;
|
||||
@@ -280,8 +280,6 @@ class PCAStat {
|
||||
right_pca_transformed.PrintDebug();
|
||||
pca_transformed_.PrintDebug();
|
||||
|
||||
printf("Checking!\n");
|
||||
Init(dataset, start, count);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ librule(
|
||||
name = "series_expansion", # this line can be safely omitted
|
||||
sources = ["series_expansion_aux.cc"], # files that must be compiled
|
||||
headers = ["farfield_expansion.h",
|
||||
"kernel_derivative.h",
|
||||
"kernel_aux.h",
|
||||
"local_expansion.h",
|
||||
"series_expansion_aux.h"], # include files part of the 'lib'
|
||||
deplibs = ["fastlib:fastlib_int"] # depends on fastlib core
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
#include <values.h>
|
||||
|
||||
#include "fastlib/fastlib.h"
|
||||
#include "kernel_derivative.h"
|
||||
#include "kernel_aux.h"
|
||||
#include "series_expansion_aux.h"
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
class LocalExpansion;
|
||||
|
||||
/**
|
||||
* Far field expansion class
|
||||
*/
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
class FarFieldExpansion {
|
||||
FORBID_COPY(FarFieldExpansion);
|
||||
|
||||
@@ -27,7 +27,7 @@ class FarFieldExpansion {
|
||||
|
||||
typedef TKernel Kernel;
|
||||
|
||||
typedef TKernelDerivative KernelDerivative;
|
||||
typedef TKernelAux KernelAux;
|
||||
|
||||
private:
|
||||
|
||||
@@ -46,8 +46,8 @@ class FarFieldExpansion {
|
||||
/** precomputed quantities */
|
||||
SeriesExpansionAux *sea_;
|
||||
|
||||
/** Derivative computer based on the kernel passed in */
|
||||
KernelDerivative kd_;
|
||||
/** auxilirary methods for the kernel (derivative, truncation error bound) */
|
||||
KernelAux ka_;
|
||||
|
||||
public:
|
||||
|
||||
@@ -116,8 +116,8 @@ class FarFieldExpansion {
|
||||
*/
|
||||
double MixField(const Matrix &data, int node1_begin, int node1_end,
|
||||
int node2_begin, int node2_end,
|
||||
const FarFieldExpansion<TKernel, TKernelDerivative> &fe2,
|
||||
const FarFieldExpansion<TKernel, TKernelDerivative> &fe3,
|
||||
const FarFieldExpansion<TKernel, TKernelAux> &fe2,
|
||||
const FarFieldExpansion<TKernel, TKernelAux> &fe3,
|
||||
int order2, int order3) const;
|
||||
|
||||
/**
|
||||
@@ -125,8 +125,8 @@ class FarFieldExpansion {
|
||||
* expansions
|
||||
*/
|
||||
double ConvolveField
|
||||
(const FarFieldExpansion<TKernel, TKernelDerivative> &fe2,
|
||||
const FarFieldExpansion<TKernel, TKernelDerivative> &fe3,
|
||||
(const FarFieldExpansion<TKernel, TKernelAux> &fe2,
|
||||
const FarFieldExpansion<TKernel, TKernelAux> &fe3,
|
||||
int order1, int order2, int order3) const;
|
||||
|
||||
/**
|
||||
@@ -155,7 +155,7 @@ class FarFieldExpansion {
|
||||
* @return the minimum approximation order required for the error,
|
||||
* -1 if approximation up to the maximum order is not possible
|
||||
*/
|
||||
int OrderForConvertingtoLocal(const DHrectBound<2> &far_field_region,
|
||||
int OrderForConvertingToLocal(const DHrectBound<2> &far_field_region,
|
||||
const DHrectBound<2> &local_field_region,
|
||||
double min_dist_sqd_regions,
|
||||
double required_bound,
|
||||
@@ -177,12 +177,12 @@ class FarFieldExpansion {
|
||||
* are added up to the passed-in local expansion coefficients.
|
||||
*/
|
||||
void TranslateToLocal
|
||||
(LocalExpansion<TKernel, TKernelDerivative> &se);
|
||||
(LocalExpansion<TKernel, TKernelAux> &se);
|
||||
|
||||
};
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void FarFieldExpansion<TKernel, TKernelDerivative>::AccumulateCoeffs
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void FarFieldExpansion<TKernel, TKernelAux>::AccumulateCoeffs
|
||||
(const Matrix& data, const Vector& weights, int begin, int end,
|
||||
int order) {
|
||||
|
||||
@@ -192,7 +192,7 @@ void FarFieldExpansion<TKernel, TKernelDerivative>::AccumulateCoeffs
|
||||
int r, i, j, k, t, tail;
|
||||
Vector heads;
|
||||
Vector x_r;
|
||||
double bandwidth_factor = kd_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
|
||||
// initialize temporary variables
|
||||
tmp.Init(total_num_coeffs);
|
||||
@@ -259,8 +259,8 @@ void FarFieldExpansion<TKernel, TKernelDerivative>::AccumulateCoeffs
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void FarFieldExpansion<TKernel, TKernelDerivative>::RefineCoeffs
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void FarFieldExpansion<TKernel, TKernelAux>::RefineCoeffs
|
||||
(const Matrix& data, const Vector& weights, int begin, int end,
|
||||
int order) {
|
||||
|
||||
@@ -276,7 +276,7 @@ void FarFieldExpansion<TKernel, TKernelDerivative>::RefineCoeffs
|
||||
double tmp;
|
||||
int r, i, j;
|
||||
Vector x_r;
|
||||
double bandwidth_factor = kd_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
|
||||
// initialize temporary variables
|
||||
x_r.Init(dim);
|
||||
@@ -335,8 +335,8 @@ void FarFieldExpansion<TKernel, TKernelDerivative>::RefineCoeffs
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
double FarFieldExpansion<TKernel, TKernelDerivative>::
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
double FarFieldExpansion<TKernel, TKernelAux>::
|
||||
EvaluateField(Matrix* data, int row_num, Vector* x_q) const {
|
||||
|
||||
// dimension
|
||||
@@ -346,7 +346,7 @@ double FarFieldExpansion<TKernel, TKernelDerivative>::
|
||||
int total_num_coeffs = sea_->get_total_num_coeffs(order_);
|
||||
|
||||
// square root times bandwidth
|
||||
double bandwidth_factor = kd_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
|
||||
// the evaluated sum
|
||||
double pos_multipole_sum = 0;
|
||||
@@ -377,12 +377,12 @@ double FarFieldExpansion<TKernel, TKernelDerivative>::
|
||||
}
|
||||
|
||||
// compute deriative maps based on coordinate difference.
|
||||
kd_.ComputeDirectionalDerivatives(x_q_minus_x_R, derivative_map);
|
||||
ka_.ComputeDirectionalDerivatives(x_q_minus_x_R, derivative_map);
|
||||
|
||||
// compute h_{\alpha}((x_q - x_R)/sqrt(2h^2)) ((x_r - x_R)/h)^{\alpha}
|
||||
for(index_t j = 0; j < total_num_coeffs; j++) {
|
||||
ArrayList<int> mapping = sea_->get_multiindex(j);
|
||||
double arrtmp = kd_.ComputePartialDerivative(derivative_map, mapping);
|
||||
double arrtmp = ka_.ComputePartialDerivative(derivative_map, mapping);
|
||||
double prod = coeffs_[j] * arrtmp;
|
||||
|
||||
if(prod > 0) {
|
||||
@@ -397,17 +397,17 @@ double FarFieldExpansion<TKernel, TKernelDerivative>::
|
||||
return multipole_sum;
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
double FarFieldExpansion<TKernel, TKernelDerivative>::MixField
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
double FarFieldExpansion<TKernel, TKernelAux>::MixField
|
||||
(const Matrix &data, int node1_begin, int node1_end,
|
||||
int node2_begin, int node2_end,
|
||||
const FarFieldExpansion<TKernel, TKernelDerivative> &fe2,
|
||||
const FarFieldExpansion<TKernel, TKernelDerivative> &fe3,
|
||||
const FarFieldExpansion<TKernel, TKernelAux> &fe2,
|
||||
const FarFieldExpansion<TKernel, TKernelAux> &fe3,
|
||||
int order2, int order3) const {
|
||||
|
||||
// bandwidth factor and multiindex mapping stuffs
|
||||
double result;
|
||||
double bandwidth_factor = kd_.BandwidthFactor(bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(bandwidth_sq());
|
||||
const ArrayList<int> *multiindex_mapping = sea_->get_multiindex_mapping();
|
||||
const ArrayList<int> *lower_mapping_index = sea_->get_lower_mapping_index();
|
||||
|
||||
@@ -454,8 +454,8 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
xI_xK[d] = (center_[d] - xK_center[d]) / bandwidth_factor;
|
||||
xJ_xK[d] = (xJ_center[d] - xK_center[d]) / bandwidth_factor;
|
||||
}
|
||||
kd_.ComputeDirectionalDerivatives(xI_xK, derivative_map_beta);
|
||||
kd_.ComputeDirectionalDerivatives(xJ_xK, derivative_map_gamma);
|
||||
ka_.ComputeDirectionalDerivatives(xI_xK, derivative_map_beta);
|
||||
ka_.ComputeDirectionalDerivatives(xJ_xK, derivative_map_gamma);
|
||||
|
||||
// inverse factorials
|
||||
Vector inv_multiindex_factorials;
|
||||
@@ -481,7 +481,7 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
|
||||
ArrayList <int> beta_mapping = multiindex_mapping[beta];
|
||||
ArrayList <int> lower_mappings_for_beta = lower_mapping_index[beta];
|
||||
double beta_derivative = kd_.ComputePartialDerivative
|
||||
double beta_derivative = ka_.ComputePartialDerivative
|
||||
(derivative_map_beta, beta_mapping);
|
||||
|
||||
for(index_t nu = 0; nu < lower_mappings_for_beta.size(); nu++) {
|
||||
@@ -499,7 +499,7 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
ArrayList <int> gamma_mapping = multiindex_mapping[gamma];
|
||||
ArrayList <int> lower_mappings_for_gamma =
|
||||
lower_mapping_index[gamma];
|
||||
double gamma_derivative = kd_.ComputePartialDerivative
|
||||
double gamma_derivative = ka_.ComputePartialDerivative
|
||||
(derivative_map_gamma, gamma_mapping);
|
||||
|
||||
for(index_t eta = 0; eta < lower_mappings_for_gamma.size();
|
||||
@@ -577,15 +577,15 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
double FarFieldExpansion<TKernel, TKernelDerivative>::ConvolveField
|
||||
(const FarFieldExpansion<TKernel, TKernelDerivative> &fe2,
|
||||
const FarFieldExpansion<TKernel, TKernelDerivative> &fe3,
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
double FarFieldExpansion<TKernel, TKernelAux>::ConvolveField
|
||||
(const FarFieldExpansion<TKernel, TKernelAux> &fe2,
|
||||
const FarFieldExpansion<TKernel, TKernelAux> &fe3,
|
||||
int order1, int order2, int order3) const {
|
||||
|
||||
// bandwidth factor and multiindex mapping stuffs
|
||||
double result;
|
||||
double bandwidth_factor = kd_.BandwidthFactor(bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(bandwidth_sq());
|
||||
const ArrayList<int> *multiindex_mapping = sea_->get_multiindex_mapping();
|
||||
const ArrayList<int> *lower_mapping_index = sea_->get_lower_mapping_index();
|
||||
|
||||
@@ -642,9 +642,9 @@ double FarFieldExpansion<TKernel, TKernelDerivative>::ConvolveField
|
||||
xI_xK[d] = (center_[d] - xK_center[d]) / bandwidth_factor;
|
||||
xJ_xK[d] = (xJ_center[d] - xK_center[d]) / bandwidth_factor;
|
||||
}
|
||||
kd_.ComputeDirectionalDerivatives(xI_xJ, derivative_map_alpha);
|
||||
kd_.ComputeDirectionalDerivatives(xI_xK, derivative_map_beta);
|
||||
kd_.ComputeDirectionalDerivatives(xJ_xK, derivative_map_gamma);
|
||||
ka_.ComputeDirectionalDerivatives(xI_xJ, derivative_map_alpha);
|
||||
ka_.ComputeDirectionalDerivatives(xI_xK, derivative_map_beta);
|
||||
ka_.ComputeDirectionalDerivatives(xJ_xK, derivative_map_gamma);
|
||||
|
||||
// inverse factorials
|
||||
Vector inv_multiindex_factorials;
|
||||
@@ -655,7 +655,7 @@ double FarFieldExpansion<TKernel, TKernelDerivative>::ConvolveField
|
||||
|
||||
ArrayList <int> alpha_mapping = multiindex_mapping[alpha];
|
||||
ArrayList <int> lower_mappings_for_alpha = lower_mapping_index[alpha];
|
||||
double alpha_derivative = kd_.ComputePartialDerivative
|
||||
double alpha_derivative = ka_.ComputePartialDerivative
|
||||
(derivative_map_alpha, alpha_mapping);
|
||||
|
||||
for(index_t mu = 0; mu < lower_mappings_for_alpha.size(); mu++) {
|
||||
@@ -672,7 +672,7 @@ double FarFieldExpansion<TKernel, TKernelDerivative>::ConvolveField
|
||||
|
||||
ArrayList <int> beta_mapping = multiindex_mapping[beta];
|
||||
ArrayList <int> lower_mappings_for_beta = lower_mapping_index[beta];
|
||||
double beta_derivative = kd_.ComputePartialDerivative
|
||||
double beta_derivative = ka_.ComputePartialDerivative
|
||||
(derivative_map_beta, beta_mapping);
|
||||
|
||||
for(index_t nu = 0; nu < lower_mappings_for_beta.size(); nu++) {
|
||||
@@ -691,7 +691,7 @@ double FarFieldExpansion<TKernel, TKernelDerivative>::ConvolveField
|
||||
ArrayList <int> gamma_mapping = multiindex_mapping[gamma];
|
||||
ArrayList <int> lower_mappings_for_gamma =
|
||||
lower_mapping_index[gamma];
|
||||
double gamma_derivative = kd_.ComputePartialDerivative
|
||||
double gamma_derivative = ka_.ComputePartialDerivative
|
||||
(derivative_map_gamma, gamma_mapping);
|
||||
|
||||
for(index_t eta = 0; eta < lower_mappings_for_gamma.size();
|
||||
@@ -763,8 +763,8 @@ double FarFieldExpansion<TKernel, TKernelDerivative>::ConvolveField
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void FarFieldExpansion<TKernel, TKernelDerivative>::Init
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void FarFieldExpansion<TKernel, TKernelAux>::Init
|
||||
(double bandwidth, const Vector& center, SeriesExpansionAux *sea) {
|
||||
|
||||
// copy kernel type, center, and bandwidth squared
|
||||
@@ -773,13 +773,18 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
order_ = -1;
|
||||
sea_ = sea;
|
||||
|
||||
// pass in the pointer to the kernel and the series expansion auxiliary
|
||||
// object
|
||||
ka_.kernel_ = &kernel_;
|
||||
ka_.sea_ = sea_;
|
||||
|
||||
// initialize coefficient array
|
||||
coeffs_.Init(sea_->get_max_total_num_coeffs());
|
||||
coeffs_.SetZero();
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void FarFieldExpansion<TKernel, TKernelDerivative>::Init
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void FarFieldExpansion<TKernel, TKernelAux>::Init
|
||||
(double bandwidth, SeriesExpansionAux *sea) {
|
||||
|
||||
// copy kernel type, center, and bandwidth squared
|
||||
@@ -789,144 +794,42 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
order_ = -1;
|
||||
sea_ = sea;
|
||||
|
||||
// pass in the pointer to the kernel and the series expansion auxiliary
|
||||
// object
|
||||
ka_.kernel_ = &kernel_;
|
||||
ka_.sea_ = sea_;
|
||||
|
||||
// initialize coefficient array
|
||||
coeffs_.Init(sea_->get_max_total_num_coeffs());
|
||||
coeffs_.SetZero();
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
int FarFieldExpansion<TKernel, TKernelDerivative>::OrderForEvaluating
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
int FarFieldExpansion<TKernel, TKernelAux>::OrderForEvaluating
|
||||
(const DHrectBound<2> &far_field_region, double min_dist_sqd_regions,
|
||||
double max_error, double *actual_error) const {
|
||||
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4 * kernel_.bandwidth_sq()));
|
||||
double widest_width = 0;
|
||||
int dim = far_field_region.dim();
|
||||
int max_order = sea_->get_max_order();
|
||||
|
||||
// find out the widest dimension and its length
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
DRange range = far_field_region.get(d);
|
||||
widest_width = max(widest_width, range.width());
|
||||
}
|
||||
|
||||
double two_bandwidth = 2 * sqrt(kernel_.bandwidth_sq());
|
||||
double r = widest_width / two_bandwidth;
|
||||
|
||||
// This is not really necessary for O(D^p) expansion, but it is for
|
||||
// speeding up the convergence of the Taylor expansion.
|
||||
if(r >= 1.0)
|
||||
return -1;
|
||||
|
||||
double r_raised_to_p_alpha = 1.0;
|
||||
double ret;
|
||||
int p_alpha = 0;
|
||||
double floor_fact, ceil_fact;
|
||||
int remainder;
|
||||
|
||||
do {
|
||||
|
||||
if(p_alpha > max_order - 1)
|
||||
return -1;
|
||||
|
||||
r_raised_to_p_alpha *= r;
|
||||
|
||||
floor_fact =
|
||||
sea_->factorial((int)floor(((double) p_alpha) / ((double) dim)));
|
||||
ceil_fact =
|
||||
sea_->factorial((int)ceil(((double) p_alpha) / ((double) dim)));
|
||||
|
||||
if(floor_fact < 0.0 || ceil_fact < 0.0)
|
||||
return -1;
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret = frontfactor *
|
||||
(sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha)) * r_raised_to_p_alpha /
|
||||
sqrt(pow(floor_fact, dim - remainder) * pow(ceil_fact, remainder));
|
||||
|
||||
if(ret > max_error) {
|
||||
p_alpha++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
*actual_error = ret;
|
||||
return p_alpha;
|
||||
return ka_.OrderForEvaluatingFarField(far_field_region,
|
||||
min_dist_sqd_regions, max_error,
|
||||
actual_error);
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
int FarFieldExpansion<TKernel, TKernelDerivative>::
|
||||
OrderForConvertingtoLocal(const DHrectBound<2> &far_field_region,
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
int FarFieldExpansion<TKernel, TKernelAux>::
|
||||
OrderForConvertingToLocal(const DHrectBound<2> &far_field_region,
|
||||
const DHrectBound<2> &local_field_region,
|
||||
double min_dist_sqd_regions,
|
||||
double max_error,
|
||||
double *actual_error) const {
|
||||
|
||||
double max_ref_length = 0;
|
||||
double max_query_length = 0;
|
||||
int dim = sea_->get_dimension();
|
||||
|
||||
for(index_t i = 0; i < dim; i++) {
|
||||
DRange far_field_range = far_field_region.get(i);
|
||||
DRange local_range = local_field_region.get(i);
|
||||
max_ref_length = max(max_ref_length, far_field_range.width());
|
||||
max_query_length = max(max_query_length, local_range.width());
|
||||
}
|
||||
|
||||
double two_times_bandwidth = sqrt(kernel_.bandwidth_sq()) * 2;
|
||||
double r_R = max_ref_length / two_times_bandwidth;
|
||||
double r_Q = max_query_length / two_times_bandwidth;
|
||||
double sqrt_two_r_R = sqrt(2.0) * r_R;
|
||||
double sqrt_two_r_Q = sqrt(2.0) * r_Q;
|
||||
|
||||
if(sqrt_two_r_R >= 1.0 || sqrt_two_r_Q >= 1.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int p_alpha = -1;
|
||||
double sqrt_two_r_R_raised_to_p = 1.0;
|
||||
double r_Q_raised_to_p = 1.0;
|
||||
int remainder;
|
||||
double ret2;
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4.0 * kernel_.bandwidth_sq()));
|
||||
double floor_fact, ceil_fact;
|
||||
|
||||
do {
|
||||
p_alpha++;
|
||||
|
||||
r_Q_raised_to_p *= r_Q;
|
||||
sqrt_two_r_R_raised_to_p *= sqrt_two_r_R;
|
||||
floor_fact =
|
||||
sea_->factorial((int) floor((double) p_alpha / (double) dim));
|
||||
ceil_fact =
|
||||
sea_->factorial((int) ceil((double)p_alpha / (double)dim));
|
||||
|
||||
if(floor_fact < 0 || ceil_fact < 0 || p_alpha > sea_->get_max_order() - 1)
|
||||
return -1;
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret2 = (sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha))
|
||||
/ sqrt(pow(floor_fact, dim - remainder) *
|
||||
pow(ceil_fact, remainder));
|
||||
ret2 *= (r_Q_raised_to_p + sqrt_two_r_R_raised_to_p *
|
||||
sea_->get_total_num_coeffs(p_alpha)) * frontfactor;
|
||||
|
||||
} while(ret2 >= max_error);
|
||||
|
||||
*actual_error = ret2;
|
||||
return p_alpha;
|
||||
return ka_.OrderForConvertingFromFarFieldToLocal(far_field_region,
|
||||
local_field_region,
|
||||
min_dist_sqd_regions,
|
||||
max_error, actual_error);
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void FarFieldExpansion<TKernel, TKernelDerivative>::PrintDebug
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void FarFieldExpansion<TKernel, TKernelAux>::PrintDebug
|
||||
(const char *name, FILE *stream) const {
|
||||
|
||||
|
||||
@@ -975,11 +878,11 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void FarFieldExpansion<TKernel, TKernelDerivative>::TranslateFromFarField
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void FarFieldExpansion<TKernel, TKernelAux>::TranslateFromFarField
|
||||
(const FarFieldExpansion &se) {
|
||||
|
||||
double bandwidth_factor = kd_.BandwidthFactor(se.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(se.bandwidth_sq());
|
||||
int dim = sea_->get_dimension();
|
||||
int order = se.get_order();
|
||||
int total_num_coeffs = sea_->get_total_num_coeffs(order);
|
||||
@@ -1065,9 +968,9 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
} // end of j-loop
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void FarFieldExpansion<TKernel, TKernelDerivative>::TranslateToLocal
|
||||
(LocalExpansion<TKernel, TKernelDerivative> &se) {
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void FarFieldExpansion<TKernel, TKernelAux>::TranslateToLocal
|
||||
(LocalExpansion<TKernel, TKernelAux> &se) {
|
||||
|
||||
Vector pos_arrtmp, neg_arrtmp;
|
||||
Matrix derivative_map;
|
||||
@@ -1078,7 +981,7 @@ void FarFieldExpansion<TKernel, TKernelDerivative>::TranslateToLocal
|
||||
int dimension = sea_->get_dimension();
|
||||
int total_num_coeffs = sea_->get_total_num_coeffs(order_);
|
||||
int limit;
|
||||
double bandwidth_factor = kd_.BandwidthFactor(se.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(se.bandwidth_sq());
|
||||
|
||||
// get center and coefficients for local expansion
|
||||
local_center.Alias(se.get_center());
|
||||
@@ -1103,7 +1006,7 @@ void FarFieldExpansion<TKernel, TKernelDerivative>::TranslateToLocal
|
||||
}
|
||||
|
||||
// compute required partial derivatives
|
||||
kd_.ComputeDirectionalDerivatives(cent_diff, derivative_map);
|
||||
ka_.ComputeDirectionalDerivatives(cent_diff, derivative_map);
|
||||
ArrayList<int> beta_plus_alpha;
|
||||
beta_plus_alpha.Init(dimension);
|
||||
|
||||
@@ -1119,7 +1022,7 @@ void FarFieldExpansion<TKernel, TKernelDerivative>::TranslateToLocal
|
||||
beta_plus_alpha[d] = beta_mapping[d] + alpha_mapping[d];
|
||||
}
|
||||
double derivative_factor =
|
||||
kd_.ComputePartialDerivative(derivative_map, beta_plus_alpha);
|
||||
ka_.ComputePartialDerivative(derivative_map, beta_plus_alpha);
|
||||
|
||||
double prod = coeffs_[k] * derivative_factor;
|
||||
|
||||
|
||||
@@ -0,0 +1,545 @@
|
||||
/**
|
||||
* @file kernel_aux.h
|
||||
*
|
||||
* The header file for the class for computing auxiliary stuffs for the kernel
|
||||
* functions (derivative, truncation error bound)
|
||||
*/
|
||||
|
||||
#ifndef KERNEL_AUX
|
||||
#define KERNEL_AUX
|
||||
|
||||
#include "fastlib/fastlib.h"
|
||||
|
||||
#include "series_expansion_aux.h"
|
||||
|
||||
/**
|
||||
* Auxiliary computer class for Gaussian kernel
|
||||
*/
|
||||
class GaussianKernelAux {
|
||||
FORBID_COPY(GaussianKernelAux);
|
||||
|
||||
public:
|
||||
|
||||
/** pointer to the Gaussian kernel */
|
||||
GaussianKernel *kernel_;
|
||||
|
||||
/** pointer to the series expansion auxiliary object */
|
||||
SeriesExpansionAux *sea_;
|
||||
|
||||
GaussianKernelAux() {}
|
||||
|
||||
~GaussianKernelAux() {}
|
||||
|
||||
double BandwidthFactor(double bandwidth_sq) const {
|
||||
return sqrt(2 * bandwidth_sq);
|
||||
}
|
||||
|
||||
void ComputeDirectionalDerivatives(const Vector &x,
|
||||
Matrix &derivative_map) const {
|
||||
|
||||
int dim = derivative_map.n_rows();
|
||||
int order = derivative_map.n_cols() - 1;
|
||||
|
||||
// precompute necessary Hermite polynomials based on coordinate difference
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
|
||||
double coord_div_band = x[d];
|
||||
double d2 = 2 * coord_div_band;
|
||||
double facj = exp(-coord_div_band * coord_div_band);
|
||||
|
||||
derivative_map.set(d, 0, facj);
|
||||
|
||||
if(order > 0) {
|
||||
|
||||
derivative_map.set(d, 1, d2 * facj);
|
||||
|
||||
if(order > 1) {
|
||||
for(index_t k = 1; k < order; k++) {
|
||||
int k2 = k * 2;
|
||||
derivative_map.set(d, k + 1, d2 * derivative_map.get(d, k) -
|
||||
k2 * derivative_map.get(d, k - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end of looping over each dimension
|
||||
}
|
||||
|
||||
double ComputePartialDerivative(const Matrix &derivative_map,
|
||||
ArrayList<int> mapping) const {
|
||||
|
||||
double partial_derivative = 1.0;
|
||||
|
||||
for(index_t d = 0; d < mapping.size(); d++) {
|
||||
partial_derivative *= derivative_map.get(d, mapping[d]);
|
||||
}
|
||||
return partial_derivative;
|
||||
}
|
||||
|
||||
int OrderForEvaluatingFarField
|
||||
(const DHrectBound<2> &far_field_region, double min_dist_sqd_regions,
|
||||
double max_error, double *actual_error) const {
|
||||
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4 * kernel_->bandwidth_sq()));
|
||||
double widest_width = 0;
|
||||
int dim = far_field_region.dim();
|
||||
int max_order = sea_->get_max_order();
|
||||
|
||||
// find out the widest dimension and its length
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
DRange range = far_field_region.get(d);
|
||||
widest_width = max(widest_width, range.width());
|
||||
}
|
||||
|
||||
double two_bandwidth = 2 * sqrt(kernel_->bandwidth_sq());
|
||||
double r = widest_width / two_bandwidth;
|
||||
|
||||
// This is not really necessary for O(D^p) expansion, but it is for
|
||||
// speeding up the convergence of the Taylor expansion.
|
||||
if(r >= 1.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
double r_raised_to_p_alpha = 1.0;
|
||||
double ret;
|
||||
int p_alpha = 0;
|
||||
double floor_fact, ceil_fact;
|
||||
int remainder;
|
||||
|
||||
do {
|
||||
|
||||
if(p_alpha > max_order - 1)
|
||||
return -1;
|
||||
|
||||
r_raised_to_p_alpha *= r;
|
||||
|
||||
floor_fact =
|
||||
sea_->factorial((int)floor(((double) p_alpha) / ((double) dim)));
|
||||
ceil_fact =
|
||||
sea_->factorial((int)ceil(((double) p_alpha) / ((double) dim)));
|
||||
|
||||
if(floor_fact < 0.0 || ceil_fact < 0.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret = frontfactor *
|
||||
(sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha)) * r_raised_to_p_alpha /
|
||||
sqrt(pow(floor_fact, dim - remainder) * pow(ceil_fact, remainder));
|
||||
|
||||
if(ret > max_error) {
|
||||
p_alpha++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
*actual_error = ret;
|
||||
return p_alpha;
|
||||
}
|
||||
|
||||
int OrderForConvertingFromFarFieldToLocal
|
||||
(const DHrectBound<2> &far_field_region,
|
||||
const DHrectBound<2> &local_field_region, double min_dist_sqd_regions,
|
||||
double max_error, double *actual_error) const {
|
||||
|
||||
double max_ref_length = 0;
|
||||
double max_query_length = 0;
|
||||
int dim = sea_->get_dimension();
|
||||
|
||||
for(index_t i = 0; i < dim; i++) {
|
||||
DRange far_field_range = far_field_region.get(i);
|
||||
DRange local_range = local_field_region.get(i);
|
||||
max_ref_length = max(max_ref_length, far_field_range.width());
|
||||
max_query_length = max(max_query_length, local_range.width());
|
||||
}
|
||||
|
||||
double two_times_bandwidth = sqrt(kernel_->bandwidth_sq()) * 2;
|
||||
double r_R = max_ref_length / two_times_bandwidth;
|
||||
double r_Q = max_query_length / two_times_bandwidth;
|
||||
double sqrt_two_r_R = sqrt(2.0) * r_R;
|
||||
double sqrt_two_r_Q = sqrt(2.0) * r_Q;
|
||||
|
||||
if(sqrt_two_r_R >= 1.0 || sqrt_two_r_Q >= 1.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int p_alpha = -1;
|
||||
double sqrt_two_r_R_raised_to_p = 1.0;
|
||||
double r_Q_raised_to_p = 1.0;
|
||||
int remainder;
|
||||
double ret2;
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4.0 * kernel_->bandwidth_sq()));
|
||||
double floor_fact, ceil_fact;
|
||||
|
||||
do {
|
||||
p_alpha++;
|
||||
|
||||
r_Q_raised_to_p *= r_Q;
|
||||
sqrt_two_r_R_raised_to_p *= sqrt_two_r_R;
|
||||
floor_fact =
|
||||
sea_->factorial((int) floor((double) p_alpha / (double) dim));
|
||||
ceil_fact =
|
||||
sea_->factorial((int) ceil((double)p_alpha / (double)dim));
|
||||
|
||||
if(floor_fact < 0 || ceil_fact < 0 ||
|
||||
p_alpha > sea_->get_max_order() - 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret2 = (sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha))
|
||||
/ sqrt(pow(floor_fact, dim - remainder) *
|
||||
pow(ceil_fact, remainder));
|
||||
ret2 *= (r_Q_raised_to_p + sqrt_two_r_R_raised_to_p *
|
||||
sea_->get_total_num_coeffs(p_alpha)) * frontfactor;
|
||||
|
||||
} while(ret2 >= max_error);
|
||||
|
||||
*actual_error = ret2;
|
||||
return p_alpha;
|
||||
}
|
||||
|
||||
int OrderForEvaluatingLocal
|
||||
(const DHrectBound<2> &local_region, double min_dist_sqd_regions,
|
||||
double max_error, double *actual_error) const {
|
||||
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4 * kernel_->bandwidth_sq()));
|
||||
double widest_width = 0;
|
||||
int dim = local_region.dim();
|
||||
int max_order = sea_->get_max_order();
|
||||
|
||||
// find out the widest dimension and its length
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
DRange range = local_region.get(d);
|
||||
widest_width = max(widest_width, range.width());
|
||||
}
|
||||
|
||||
double two_bandwidth = 2 * sqrt(kernel_->bandwidth_sq());
|
||||
double r = widest_width / two_bandwidth;
|
||||
|
||||
// This is not really necessary for O(D^p) expansion, but it is for
|
||||
// speeding up the convergence of the Taylor expansion.
|
||||
if(r >= 1.0)
|
||||
return -1;
|
||||
|
||||
double r_raised_to_p_alpha = 1.0;
|
||||
double ret;
|
||||
int p_alpha = 0;
|
||||
double floor_fact, ceil_fact;
|
||||
int remainder;
|
||||
|
||||
do {
|
||||
|
||||
if(p_alpha > max_order - 1)
|
||||
return -1;
|
||||
|
||||
r_raised_to_p_alpha *= r;
|
||||
|
||||
floor_fact =
|
||||
sea_->factorial((int)floor(((double) p_alpha) / ((double) dim)));
|
||||
ceil_fact =
|
||||
sea_->factorial((int)ceil(((double) p_alpha) / ((double) dim)));
|
||||
|
||||
if(floor_fact < 0.0 || ceil_fact < 0.0)
|
||||
return -1;
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret = frontfactor *
|
||||
(sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha)) * r_raised_to_p_alpha /
|
||||
sqrt(pow(floor_fact, dim - remainder) * pow(ceil_fact, remainder));
|
||||
|
||||
if(ret > max_error) {
|
||||
p_alpha++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
*actual_error = ret;
|
||||
return p_alpha;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Auxilairy computer class for Epanechnikov kernel
|
||||
*/
|
||||
class EpanKernelAux {
|
||||
FORBID_COPY(EpanKernelAux);
|
||||
|
||||
public:
|
||||
|
||||
EpanKernel *kernel_;
|
||||
|
||||
SeriesExpansionAux *sea_;
|
||||
|
||||
EpanKernelAux() {}
|
||||
|
||||
~EpanKernelAux() {}
|
||||
|
||||
double BandwidthFactor(double bandwidth_sq) const {
|
||||
return sqrt(bandwidth_sq);
|
||||
}
|
||||
|
||||
void ComputeDirectionalDerivatives(const Vector &x,
|
||||
Matrix &derivative_map) const {
|
||||
|
||||
int dim = derivative_map.n_rows();
|
||||
int order = derivative_map.n_cols() - 1;
|
||||
|
||||
// precompute necessary Hermite polynomials based on coordinate difference
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
|
||||
double coord_div_band = x[d];
|
||||
|
||||
derivative_map.set(d, 0, coord_div_band * coord_div_band);
|
||||
|
||||
if(order > 0) {
|
||||
derivative_map.set(d, 1, 2 * coord_div_band);
|
||||
|
||||
if(order > 1) {
|
||||
derivative_map.set(d, 2, -2);
|
||||
|
||||
for(index_t k = 3; k <= order; k++) {
|
||||
derivative_map.set(d, k, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end of looping over each dimension
|
||||
}
|
||||
|
||||
double ComputePartialDerivative(const Matrix &derivative_map,
|
||||
ArrayList<int> mapping) const {
|
||||
|
||||
int nonzero_count = 0;
|
||||
int nonzero_index = 0;
|
||||
|
||||
for(index_t d = 0; d < mapping.size(); d++) {
|
||||
if(mapping[d] > 0) {
|
||||
nonzero_count++;
|
||||
nonzero_index = d;
|
||||
}
|
||||
|
||||
if(nonzero_count > 1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(nonzero_count == 0) {
|
||||
double prod = 0;
|
||||
for(index_t d = 0; d < mapping.size(); d++) {
|
||||
prod += derivative_map.get(d, 0);
|
||||
}
|
||||
return 1.0 - prod;
|
||||
}
|
||||
|
||||
return derivative_map.get(nonzero_index, mapping[nonzero_index]);
|
||||
}
|
||||
|
||||
int OrderForEvaluatingFarField
|
||||
(const DHrectBound<2> &far_field_region, double min_dist_sqd_regions,
|
||||
double max_error, double *actual_error) const {
|
||||
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4 * kernel_->bandwidth_sq()));
|
||||
double widest_width = 0;
|
||||
int dim = far_field_region.dim();
|
||||
int max_order = sea_->get_max_order();
|
||||
|
||||
// find out the widest dimension and its length
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
DRange range = far_field_region.get(d);
|
||||
widest_width = max(widest_width, range.width());
|
||||
}
|
||||
|
||||
double two_bandwidth = 2 * sqrt(kernel_->bandwidth_sq());
|
||||
double r = widest_width / two_bandwidth;
|
||||
|
||||
// This is not really necessary for O(D^p) expansion, but it is for
|
||||
// speeding up the convergence of the Taylor expansion.
|
||||
if(r >= 1.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
double r_raised_to_p_alpha = 1.0;
|
||||
double ret;
|
||||
int p_alpha = 0;
|
||||
double floor_fact, ceil_fact;
|
||||
int remainder;
|
||||
|
||||
do {
|
||||
|
||||
if(p_alpha > max_order - 1)
|
||||
return -1;
|
||||
|
||||
r_raised_to_p_alpha *= r;
|
||||
|
||||
floor_fact =
|
||||
sea_->factorial((int)floor(((double) p_alpha) / ((double) dim)));
|
||||
ceil_fact =
|
||||
sea_->factorial((int)ceil(((double) p_alpha) / ((double) dim)));
|
||||
|
||||
if(floor_fact < 0.0 || ceil_fact < 0.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret = frontfactor *
|
||||
(sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha)) * r_raised_to_p_alpha /
|
||||
sqrt(pow(floor_fact, dim - remainder) * pow(ceil_fact, remainder));
|
||||
|
||||
if(ret > max_error) {
|
||||
p_alpha++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
*actual_error = ret;
|
||||
return p_alpha;
|
||||
}
|
||||
|
||||
int OrderForConvertingFromFarFieldToLocal
|
||||
(const DHrectBound<2> &far_field_region,
|
||||
const DHrectBound<2> &local_field_region, double min_dist_sqd_regions,
|
||||
double max_error, double *actual_error) const {
|
||||
|
||||
double max_ref_length = 0;
|
||||
double max_query_length = 0;
|
||||
int dim = sea_->get_dimension();
|
||||
|
||||
for(index_t i = 0; i < dim; i++) {
|
||||
DRange far_field_range = far_field_region.get(i);
|
||||
DRange local_range = local_field_region.get(i);
|
||||
max_ref_length = max(max_ref_length, far_field_range.width());
|
||||
max_query_length = max(max_query_length, local_range.width());
|
||||
}
|
||||
|
||||
double two_times_bandwidth = sqrt(kernel_->bandwidth_sq()) * 2;
|
||||
double r_R = max_ref_length / two_times_bandwidth;
|
||||
double r_Q = max_query_length / two_times_bandwidth;
|
||||
double sqrt_two_r_R = sqrt(2.0) * r_R;
|
||||
double sqrt_two_r_Q = sqrt(2.0) * r_Q;
|
||||
|
||||
if(sqrt_two_r_R >= 1.0 || sqrt_two_r_Q >= 1.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int p_alpha = -1;
|
||||
double sqrt_two_r_R_raised_to_p = 1.0;
|
||||
double r_Q_raised_to_p = 1.0;
|
||||
int remainder;
|
||||
double ret2;
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4.0 * kernel_->bandwidth_sq()));
|
||||
double floor_fact, ceil_fact;
|
||||
|
||||
do {
|
||||
p_alpha++;
|
||||
|
||||
r_Q_raised_to_p *= r_Q;
|
||||
sqrt_two_r_R_raised_to_p *= sqrt_two_r_R;
|
||||
floor_fact =
|
||||
sea_->factorial((int) floor((double) p_alpha / (double) dim));
|
||||
ceil_fact =
|
||||
sea_->factorial((int) ceil((double)p_alpha / (double)dim));
|
||||
|
||||
if(floor_fact < 0 || ceil_fact < 0 ||
|
||||
p_alpha > sea_->get_max_order() - 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret2 = (sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha))
|
||||
/ sqrt(pow(floor_fact, dim - remainder) *
|
||||
pow(ceil_fact, remainder));
|
||||
ret2 *= (r_Q_raised_to_p + sqrt_two_r_R_raised_to_p *
|
||||
sea_->get_total_num_coeffs(p_alpha)) * frontfactor;
|
||||
|
||||
} while(ret2 >= max_error);
|
||||
|
||||
*actual_error = ret2;
|
||||
return p_alpha;
|
||||
}
|
||||
|
||||
int OrderForEvaluatingLocal
|
||||
(const DHrectBound<2> &local_region, double min_dist_sqd_regions,
|
||||
double max_error, double *actual_error) const {
|
||||
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4 * kernel_->bandwidth_sq()));
|
||||
double widest_width = 0;
|
||||
int dim = local_region.dim();
|
||||
int max_order = sea_->get_max_order();
|
||||
|
||||
// find out the widest dimension and its length
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
DRange range = local_region.get(d);
|
||||
widest_width = max(widest_width, range.width());
|
||||
}
|
||||
|
||||
double two_bandwidth = 2 * sqrt(kernel_->bandwidth_sq());
|
||||
double r = widest_width / two_bandwidth;
|
||||
|
||||
// This is not really necessary for O(D^p) expansion, but it is for
|
||||
// speeding up the convergence of the Taylor expansion.
|
||||
if(r >= 1.0)
|
||||
return -1;
|
||||
|
||||
double r_raised_to_p_alpha = 1.0;
|
||||
double ret;
|
||||
int p_alpha = 0;
|
||||
double floor_fact, ceil_fact;
|
||||
int remainder;
|
||||
|
||||
do {
|
||||
|
||||
if(p_alpha > max_order - 1)
|
||||
return -1;
|
||||
|
||||
r_raised_to_p_alpha *= r;
|
||||
|
||||
floor_fact =
|
||||
sea_->factorial((int)floor(((double) p_alpha) / ((double) dim)));
|
||||
ceil_fact =
|
||||
sea_->factorial((int)ceil(((double) p_alpha) / ((double) dim)));
|
||||
|
||||
if(floor_fact < 0.0 || ceil_fact < 0.0)
|
||||
return -1;
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret = frontfactor *
|
||||
(sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha)) * r_raised_to_p_alpha /
|
||||
sqrt(pow(floor_fact, dim - remainder) * pow(ceil_fact, remainder));
|
||||
|
||||
if(ret > max_error) {
|
||||
p_alpha++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
*actual_error = ret;
|
||||
return p_alpha;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,144 +0,0 @@
|
||||
/**
|
||||
* @file kernel_derivative.h
|
||||
*
|
||||
* The header file for the class for computing derivatives of kernel functions
|
||||
*/
|
||||
|
||||
#ifndef KERNEL_DERIVATIVE
|
||||
#define KERNEL_DERIVATIVE
|
||||
|
||||
#include "fastlib/fastlib.h"
|
||||
|
||||
/**
|
||||
* Derivative computer class for Gaussian kernel
|
||||
*/
|
||||
class GaussianKernelDerivative {
|
||||
FORBID_COPY(GaussianKernelDerivative);
|
||||
|
||||
public:
|
||||
|
||||
GaussianKernelDerivative() {}
|
||||
|
||||
~GaussianKernelDerivative() {}
|
||||
|
||||
double BandwidthFactor(double bandwidth_sq) const {
|
||||
return sqrt(2 * bandwidth_sq);
|
||||
}
|
||||
|
||||
void ComputeDirectionalDerivatives(const Vector &x,
|
||||
Matrix &derivative_map) const {
|
||||
|
||||
int dim = derivative_map.n_rows();
|
||||
int order = derivative_map.n_cols() - 1;
|
||||
|
||||
// precompute necessary Hermite polynomials based on coordinate difference
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
|
||||
double coord_div_band = x[d];
|
||||
double d2 = 2 * coord_div_band;
|
||||
double facj = exp(-coord_div_band * coord_div_band);
|
||||
|
||||
derivative_map.set(d, 0, facj);
|
||||
|
||||
if(order > 0) {
|
||||
|
||||
derivative_map.set(d, 1, d2 * facj);
|
||||
|
||||
if(order > 1) {
|
||||
for(index_t k = 1; k < order; k++) {
|
||||
int k2 = k * 2;
|
||||
derivative_map.set(d, k + 1, d2 * derivative_map.get(d, k) -
|
||||
k2 * derivative_map.get(d, k - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end of looping over each dimension
|
||||
}
|
||||
|
||||
double ComputePartialDerivative(const Matrix &derivative_map,
|
||||
ArrayList<int> mapping) const {
|
||||
|
||||
double partial_derivative = 1.0;
|
||||
|
||||
for(index_t d = 0; d < mapping.size(); d++) {
|
||||
partial_derivative *= derivative_map.get(d, mapping[d]);
|
||||
}
|
||||
return partial_derivative;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Derivative computer class for Epanechnikov kernel
|
||||
*/
|
||||
class EpanKernelDerivative {
|
||||
FORBID_COPY(EpanKernelDerivative);
|
||||
|
||||
public:
|
||||
|
||||
EpanKernelDerivative() {}
|
||||
|
||||
~EpanKernelDerivative() {}
|
||||
|
||||
double BandwidthFactor(double bandwidth_sq) const {
|
||||
return sqrt(bandwidth_sq);
|
||||
}
|
||||
|
||||
void ComputeDirectionalDerivatives(const Vector &x,
|
||||
Matrix &derivative_map) const {
|
||||
|
||||
int dim = derivative_map.n_rows();
|
||||
int order = derivative_map.n_cols() - 1;
|
||||
|
||||
// precompute necessary Hermite polynomials based on coordinate difference
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
|
||||
double coord_div_band = x[d];
|
||||
|
||||
derivative_map.set(d, 0, coord_div_band * coord_div_band);
|
||||
|
||||
if(order > 0) {
|
||||
derivative_map.set(d, 1, 2 * coord_div_band);
|
||||
|
||||
if(order > 1) {
|
||||
derivative_map.set(d, 2, -2);
|
||||
|
||||
for(index_t k = 3; k <= order; k++) {
|
||||
derivative_map.set(d, k, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end of looping over each dimension
|
||||
}
|
||||
|
||||
double ComputePartialDerivative(const Matrix &derivative_map,
|
||||
ArrayList<int> mapping) const {
|
||||
|
||||
int nonzero_count = 0;
|
||||
int nonzero_index = 0;
|
||||
|
||||
for(index_t d = 0; d < mapping.size(); d++) {
|
||||
if(mapping[d] > 0) {
|
||||
nonzero_count++;
|
||||
nonzero_index = d;
|
||||
}
|
||||
|
||||
if(nonzero_count > 1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(nonzero_count == 0) {
|
||||
double prod = 0;
|
||||
for(index_t d = 0; d < mapping.size(); d++) {
|
||||
prod += derivative_map.get(d, 0);
|
||||
}
|
||||
return 1.0 - prod;
|
||||
}
|
||||
|
||||
return derivative_map.get(nonzero_index, mapping[nonzero_index]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -10,16 +10,16 @@
|
||||
#include <values.h>
|
||||
|
||||
#include "fastlib/fastlib.h"
|
||||
#include "kernel_derivative.h"
|
||||
#include "kernel_aux.h"
|
||||
#include "series_expansion_aux.h"
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
class FarFieldExpansion;
|
||||
|
||||
/**
|
||||
* Local expansion class
|
||||
*/
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
class LocalExpansion {
|
||||
FORBID_COPY(LocalExpansion);
|
||||
|
||||
@@ -27,7 +27,7 @@ class LocalExpansion {
|
||||
|
||||
typedef TKernel Kernel;
|
||||
|
||||
typedef TKernelDerivative KernelDerivative;
|
||||
typedef TKernelAux KernelAux;
|
||||
|
||||
private:
|
||||
|
||||
@@ -46,9 +46,11 @@ class LocalExpansion {
|
||||
/** precomputed quantities */
|
||||
SeriesExpansionAux *sea_;
|
||||
|
||||
/** Derivative computer based on the kernel passed in */
|
||||
KernelDerivative kd_;
|
||||
/** auxiliary methods for the kernel (derivative, truncation error bound) */
|
||||
KernelAux ka_;
|
||||
|
||||
/** error bound computer for the kernel */
|
||||
|
||||
public:
|
||||
|
||||
LocalExpansion() {}
|
||||
@@ -125,19 +127,19 @@ class LocalExpansion {
|
||||
* The translated coefficients are added up to the ones here.
|
||||
*/
|
||||
void TranslateFromFarField
|
||||
(const FarFieldExpansion<TKernel, TKernelDerivative> &se);
|
||||
(const FarFieldExpansion<TKernel, TKernelAux> &se);
|
||||
|
||||
/**
|
||||
* Translate to the given local expansion. The translated coefficients
|
||||
* are added up to the passed-in local expansion coefficients.
|
||||
*/
|
||||
void TranslateToLocal
|
||||
(LocalExpansion<TKernel, TKernelDerivative> &se);
|
||||
(LocalExpansion<TKernel, TKernelAux> &se);
|
||||
|
||||
};
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void LocalExpansion<TKernel, TKernelDerivative>::AccumulateCoeffs
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void LocalExpansion<TKernel, TKernelAux>::AccumulateCoeffs
|
||||
(const Matrix& data, const Vector& weights,
|
||||
int begin, int end, int order) {
|
||||
|
||||
@@ -164,7 +166,7 @@ void LocalExpansion<TKernel, TKernelDerivative>::AccumulateCoeffs
|
||||
x_r_minus_x_Q.Init(dim);
|
||||
|
||||
// sqrt two times bandwidth
|
||||
double bandwidth_factor = kd_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
|
||||
// for each data point,
|
||||
for(index_t r = begin; r < end; r++) {
|
||||
@@ -176,12 +178,12 @@ void LocalExpansion<TKernel, TKernelDerivative>::AccumulateCoeffs
|
||||
}
|
||||
|
||||
// precompute necessary partial derivatives based on coordinate difference
|
||||
kd_.ComputeDirectionalDerivatives(x_r_minus_x_Q, derivative_map);
|
||||
ka_.ComputeDirectionalDerivatives(x_r_minus_x_Q, derivative_map);
|
||||
|
||||
// compute h_{beta}((x_r - x_Q) / sqrt(2h^2))
|
||||
for(index_t j = 0; j < total_num_coeffs; j++) {
|
||||
ArrayList<int> mapping = sea_->get_multiindex(j);
|
||||
arrtmp[j] = kd_.ComputePartialDerivative(derivative_map, mapping);
|
||||
arrtmp[j] = ka_.ComputePartialDerivative(derivative_map, mapping);
|
||||
}
|
||||
|
||||
for(index_t j = 0; j < total_num_coeffs; j++) {
|
||||
@@ -191,8 +193,8 @@ void LocalExpansion<TKernel, TKernelDerivative>::AccumulateCoeffs
|
||||
} // End of looping through each reference point.
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void LocalExpansion<TKernel, TKernelDerivative>::PrintDebug
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void LocalExpansion<TKernel, TKernelAux>::PrintDebug
|
||||
(const char *name, FILE *stream) const {
|
||||
|
||||
|
||||
@@ -231,8 +233,8 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
double LocalExpansion<TKernel, TKernelDerivative>::
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
double LocalExpansion<TKernel, TKernelAux>::
|
||||
EvaluateField(Matrix* data, int row_num, Vector* x_q) const {
|
||||
|
||||
index_t k, t, tail;
|
||||
@@ -247,7 +249,7 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
double sum = 0;
|
||||
|
||||
// sqrt two bandwidth
|
||||
double bandwidth_factor = kd_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
|
||||
// temporary variable
|
||||
Vector x_Q_to_x_q;
|
||||
@@ -294,8 +296,8 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void LocalExpansion<TKernel, TKernelDerivative>::Init
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void LocalExpansion<TKernel, TKernelAux>::Init
|
||||
(double bandwidth, const Vector& center, SeriesExpansionAux *sea) {
|
||||
|
||||
// copy kernel type, center, and bandwidth squared
|
||||
@@ -304,13 +306,18 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
order_ = 0;
|
||||
sea_ = sea;
|
||||
|
||||
// pass in the pointer to the kernel and the series expansion auxiliary
|
||||
// object
|
||||
ka_.kernel_ = &kernel_;
|
||||
ka_.sea_ = sea_;
|
||||
|
||||
// initialize coefficient array
|
||||
coeffs_.Init(sea_->get_max_total_num_coeffs());
|
||||
coeffs_.SetZero();
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void LocalExpansion<TKernel, TKernelDerivative>::Init
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void LocalExpansion<TKernel, TKernelAux>::Init
|
||||
(double bandwidth, SeriesExpansionAux *sea) {
|
||||
|
||||
// copy kernel type, center, and bandwidth squared
|
||||
@@ -319,79 +326,28 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
order_ = 0;
|
||||
sea_ = sea;
|
||||
|
||||
// pass in the pointer to the kernel and the series expansion auxiliary
|
||||
// object
|
||||
ka_.kernel_ = &kernel_;
|
||||
ka_.sea_ = sea_;
|
||||
|
||||
// initialize coefficient array
|
||||
coeffs_.Init(sea_->get_max_total_num_coeffs());
|
||||
coeffs_.SetZero();
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
int LocalExpansion<TKernel, TKernelDerivative>::OrderForEvaluating
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
int LocalExpansion<TKernel, TKernelAux>::OrderForEvaluating
|
||||
(const DHrectBound<2> &local_region, double min_dist_sqd_regions,
|
||||
double max_error, double *actual_error) const {
|
||||
|
||||
double frontfactor =
|
||||
exp(-min_dist_sqd_regions / (4 * kernel_.bandwidth_sq()));
|
||||
double widest_width = 0;
|
||||
int dim = local_region.dim();
|
||||
int max_order = sea_->get_max_order();
|
||||
|
||||
// find out the widest dimension and its length
|
||||
for(index_t d = 0; d < dim; d++) {
|
||||
DRange range = local_region.get(d);
|
||||
widest_width = max(widest_width, range.width());
|
||||
}
|
||||
|
||||
double two_bandwidth = 2 * sqrt(kernel_.bandwidth_sq());
|
||||
double r = widest_width / two_bandwidth;
|
||||
|
||||
// This is not really necessary for O(D^p) expansion, but it is for
|
||||
// speeding up the convergence of the Taylor expansion.
|
||||
if(r >= 1.0)
|
||||
return -1;
|
||||
|
||||
double r_raised_to_p_alpha = 1.0;
|
||||
double ret;
|
||||
int p_alpha = 0;
|
||||
double floor_fact, ceil_fact;
|
||||
int remainder;
|
||||
|
||||
do {
|
||||
|
||||
if(p_alpha > max_order - 1)
|
||||
return -1;
|
||||
|
||||
r_raised_to_p_alpha *= r;
|
||||
|
||||
floor_fact =
|
||||
sea_->factorial((int)floor(((double) p_alpha) / ((double) dim)));
|
||||
ceil_fact =
|
||||
sea_->factorial((int)ceil(((double) p_alpha) / ((double) dim)));
|
||||
|
||||
if(floor_fact < 0.0 || ceil_fact < 0.0)
|
||||
return -1;
|
||||
|
||||
remainder = p_alpha % dim;
|
||||
|
||||
ret = frontfactor *
|
||||
(sea_->get_total_num_coeffs(p_alpha + 1) -
|
||||
sea_->get_total_num_coeffs(p_alpha)) * r_raised_to_p_alpha /
|
||||
sqrt(pow(floor_fact, dim - remainder) * pow(ceil_fact, remainder));
|
||||
|
||||
if(ret > max_error) {
|
||||
p_alpha++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
*actual_error = ret;
|
||||
return p_alpha;
|
||||
|
||||
return ka_.OrderForEvaluatingLocal(local_region, min_dist_sqd_regions,
|
||||
max_error, actual_error);
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void LocalExpansion<TKernel, TKernelDerivative>::TranslateFromFarField
|
||||
(const FarFieldExpansion<TKernel, TKernelDerivative> &se) {
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void LocalExpansion<TKernel, TKernelAux>::TranslateFromFarField
|
||||
(const FarFieldExpansion<TKernel, TKernelAux> &se) {
|
||||
|
||||
Vector pos_arrtmp, neg_arrtmp;
|
||||
Matrix derivative_map;
|
||||
@@ -402,7 +358,7 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
int far_order = se.get_order();
|
||||
int total_num_coeffs = sea_->get_total_num_coeffs(far_order);
|
||||
int limit;
|
||||
double bandwidth_factor = kd_.BandwidthFactor(se.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(se.bandwidth_sq());
|
||||
|
||||
// get center and coefficients for far field expansion
|
||||
far_center.Alias(se.get_center());
|
||||
@@ -427,7 +383,7 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
}
|
||||
|
||||
// compute required partial derivatives
|
||||
kd_.ComputeDirectionalDerivatives(cent_diff, derivative_map);
|
||||
ka_.ComputeDirectionalDerivatives(cent_diff, derivative_map);
|
||||
ArrayList<int> beta_plus_alpha;
|
||||
beta_plus_alpha.Init(dimension);
|
||||
|
||||
@@ -443,7 +399,7 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
beta_plus_alpha[d] = beta_mapping[d] + alpha_mapping[d];
|
||||
}
|
||||
double derivative_factor =
|
||||
kd_.ComputePartialDerivative(derivative_map, beta_plus_alpha);
|
||||
ka_.ComputePartialDerivative(derivative_map, beta_plus_alpha);
|
||||
|
||||
double prod = far_coeffs[k] * derivative_factor;
|
||||
|
||||
@@ -462,9 +418,9 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TKernel, typename TKernelDerivative>
|
||||
void LocalExpansion<TKernel, TKernelDerivative>::TranslateToLocal
|
||||
(LocalExpansion<TKernel, TKernelDerivative> &se) {
|
||||
template<typename TKernel, typename TKernelAux>
|
||||
void LocalExpansion<TKernel, TKernelAux>::TranslateToLocal
|
||||
(LocalExpansion<TKernel, TKernelAux> &se) {
|
||||
|
||||
// get the center and the order and the total number of coefficients of
|
||||
// the expansion we are translating from. Also get coefficients we
|
||||
@@ -486,7 +442,7 @@ template<typename TKernel, typename TKernelDerivative>
|
||||
tmp_storage.Init(dim);
|
||||
|
||||
// sqrt two times bandwidth
|
||||
double bandwidth_factor = kd_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
double bandwidth_factor = ka_.BandwidthFactor(kernel_.bandwidth_sq());
|
||||
|
||||
// center difference between the old center and the new one
|
||||
Vector center_diff;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "fastlib/fastlib.h"
|
||||
#include "kernel_derivative.h"
|
||||
#include "kernel_aux.h"
|
||||
#include "farfield_expansion.h"
|
||||
#include "local_expansion.h"
|
||||
#include "series_expansion_aux.h"
|
||||
@@ -36,7 +36,7 @@ int TestEpanKernelEvaluateFarField(const Matrix &data, const Vector &weights,
|
||||
evaluate_here[0] = evaluate_here[1] = 0.1;
|
||||
|
||||
// declare expansion object
|
||||
FarFieldExpansion<EpanKernel, EpanKernelDerivative> se;
|
||||
FarFieldExpansion<EpanKernel, EpanKernelAux> se;
|
||||
|
||||
// initialize expansion objects with respective center and the bandwidth
|
||||
se.Init(bandwidth, center, &sea);
|
||||
@@ -124,7 +124,7 @@ int TestEvaluateFarField(const Matrix &data, const Vector &weights,
|
||||
evaluate_here[0] = evaluate_here[1] = 3;
|
||||
|
||||
// declare expansion objects at (0,0) and other centers
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se;
|
||||
|
||||
// initialize expansion objects with respective centers and the bandwidth
|
||||
// squared of 0.5
|
||||
@@ -180,7 +180,7 @@ int TestEvaluateLocalField(const Matrix &data, const Vector &weights,
|
||||
evaluate_here[0] = evaluate_here[1] = 3.5;
|
||||
|
||||
// declare expansion objects at (0,0) and other centers
|
||||
LocalExpansion<GaussianKernel, GaussianKernelDerivative> se;
|
||||
LocalExpansion<GaussianKernel, GaussianKernelAux> se;
|
||||
|
||||
// initialize expansion objects with respective centers and the bandwidth
|
||||
// squared of 1
|
||||
@@ -247,9 +247,9 @@ int TestTransFarToFar(const Matrix &data, const Vector &weights,
|
||||
new_center[1] = -2;
|
||||
|
||||
// declare expansion objects at (0,0) and other centers
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se_translated;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se_cmp;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se_translated;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se_cmp;
|
||||
|
||||
// initialize expansion objects with respective centers and the bandwidth
|
||||
// squared of 0.1
|
||||
@@ -309,8 +309,8 @@ int TestTransLocalToLocal(const Matrix &data, const Vector &weights,
|
||||
new_center[0] = new_center[1] = 3.5;
|
||||
|
||||
// declare expansion objects at (0,0) and other centers
|
||||
LocalExpansion<GaussianKernel, GaussianKernelDerivative> se;
|
||||
LocalExpansion<GaussianKernel, GaussianKernelDerivative> se_translated;
|
||||
LocalExpansion<GaussianKernel, GaussianKernelAux> se;
|
||||
LocalExpansion<GaussianKernel, GaussianKernelAux> se_translated;
|
||||
|
||||
// initialize expansion objects with respective centers and the bandwidth
|
||||
// squared of 0.1
|
||||
@@ -389,9 +389,9 @@ int TestMixFarField(const Matrix &data, const Vector &weights,
|
||||
data_comb.PrintDebug();
|
||||
|
||||
// declare expansion objects at (0,0) and other centers
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se2;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se3;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se2;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se3;
|
||||
|
||||
// initialize expansion objects with respective centers and the bandwidth
|
||||
// squared of 0.5
|
||||
@@ -479,9 +479,9 @@ int TestConvolveFarField(const Matrix &data, const Vector &weights,
|
||||
data3.PrintDebug();
|
||||
|
||||
// declare expansion objects at (0,0) and other centers
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se2;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelDerivative> se3;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se2;
|
||||
FarFieldExpansion<GaussianKernel, GaussianKernelAux> se3;
|
||||
|
||||
// initialize expansion objects with respective centers and the bandwidth
|
||||
// squared of 0.5
|
||||
|
||||
Reference in New Issue
Block a user