kernel.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00038 #ifndef MATH_KERNEL_H
00039 #define MATH_KERNEL_H
00040
00041 #include "fastlib/base/base.h"
00042 #include "fastlib/math/geometry.h"
00043 #include "fastlib/math/math_lib.h"
00044
00045 #include <math.h>
00046
00047
00048
00053 class GaussianKernel {
00054 private:
00055 double neg_inv_bandwidth_2sq_;
00056 double bandwidth_sq_;
00057
00058 OBJECT_TRAVERSAL(GaussianKernel) {
00059 OT_OBJ(neg_inv_bandwidth_2sq_);
00060 OT_OBJ(bandwidth_sq_);
00061 }
00062
00063 public:
00064 static const bool HAS_CUTOFF = false;
00065
00066 public:
00067 double bandwidth_sq() const {
00068 return bandwidth_sq_;
00069 }
00070
00071 void Init(double bandwidth_in, index_t dims) {
00072 Init(bandwidth_in);
00073 }
00074
00080 void Init(double bandwidth_in) {
00081 bandwidth_sq_ = bandwidth_in * bandwidth_in;
00082 neg_inv_bandwidth_2sq_ = -1.0 / (2.0 * bandwidth_sq_);
00083 }
00084
00089 double EvalUnnorm(double dist) const {
00090 return EvalUnnormOnSq(dist * dist);
00091 }
00092
00097 double EvalUnnormOnSq(double sqdist) const {
00098 double d = exp(sqdist * neg_inv_bandwidth_2sq_);
00099 return d;
00100 }
00101
00103 DRange RangeUnnormOnSq(const DRange& range) const {
00104 return DRange(EvalUnnormOnSq(range.hi), EvalUnnormOnSq(range.lo));
00105 }
00106
00110 double MaxUnnormValue() {
00111 return 1;
00112 }
00113
00117 double CalcNormConstant(index_t dims) const {
00118
00119
00120 return pow(2 * math::PI * bandwidth_sq_, dims / 2.0);
00121 }
00122 };
00123
00128 class GaussianStarKernel {
00129 private:
00130 double neg_inv_bandwidth_2sq_;
00131 double factor_;
00132 double bandwidth_sq_;
00133 double critical_point_sq_;
00134 double critical_point_value_;
00135
00136 OBJECT_TRAVERSAL(GaussianStarKernel) {
00137 OT_OBJ(neg_inv_bandwidth_2sq_);
00138 OT_OBJ(factor_);
00139 OT_OBJ(bandwidth_sq_);
00140 OT_OBJ(critical_point_sq_);
00141 OT_OBJ(critical_point_value_);
00142 }
00143
00144 public:
00145 static const bool HAS_CUTOFF = false;
00146
00147 public:
00148 double bandwidth_sq() const {
00149 return bandwidth_sq_;
00150 }
00151
00157 void Init(double bandwidth_in, index_t dims) {
00158 bandwidth_sq_ = bandwidth_in * bandwidth_in;
00159 neg_inv_bandwidth_2sq_ = -1.0 / (2.0 * bandwidth_sq_);
00160 factor_ = pow(2.0, -dims / 2.0 - 1);
00161 critical_point_sq_ = 4 * bandwidth_sq_ * (dims / 2.0 + 2) * math::LN_2;
00162 critical_point_value_ = EvalUnnormOnSq(critical_point_sq_);
00163 }
00164
00169 double EvalUnnorm(double dist) const {
00170 return EvalUnnormOnSq(dist * dist);
00171 }
00172
00177 double EvalUnnormOnSq(double sqdist) const {
00178 double d =
00179 factor_ * exp(sqdist * neg_inv_bandwidth_2sq_ * 0.5)
00180 - exp(sqdist * neg_inv_bandwidth_2sq_);
00181 return d;
00182 }
00183
00185 DRange RangeUnnormOnSq(const DRange& range) const {
00186 double eval_lo = EvalUnnormOnSq(range.lo);
00187 double eval_hi = EvalUnnormOnSq(range.hi);
00188 if (range.lo < critical_point_sq_) {
00189 if (range.hi < critical_point_sq_) {
00190
00191 return DRange(eval_lo, eval_hi);
00192 } else {
00193
00194 return DRange(std::min(eval_lo, eval_hi), critical_point_value_);
00195 }
00196 } else {
00197 return DRange(eval_hi, eval_lo);
00198 }
00199 }
00200
00206 double CalcNormConstant(index_t dims) const {
00207 return pow(math::PI_2*bandwidth_sq_, dims / 2) / 2;
00208 }
00209
00213 double CalcMultiplicativeNormConstant(index_t dims) const {
00214 return 1.0 / CalcNormConstant(dims);
00215 }
00216 };
00217
00224 class EpanKernel {
00225 private:
00226 double inv_bandwidth_sq_;
00227 double bandwidth_sq_;
00228
00229 OBJECT_TRAVERSAL(EpanKernel) {
00230 OT_OBJ(inv_bandwidth_sq_);
00231 OT_OBJ(bandwidth_sq_);
00232 }
00233
00234 public:
00235 static const bool HAS_CUTOFF = true;
00236
00237 public:
00238 void Init(double bandwidth_in, index_t dims) {
00239 Init(bandwidth_in);
00240 }
00241
00245 void Init(double bandwidth_in) {
00246 bandwidth_sq_ = (bandwidth_in * bandwidth_in);
00247 inv_bandwidth_sq_ = 1.0 / bandwidth_sq_;
00248 }
00249
00254 double EvalUnnorm(double dist) const {
00255 return EvalUnnormOnSq(dist * dist);
00256 }
00257
00262 double EvalUnnormOnSq(double sqdist) const {
00263
00264 if (sqdist < bandwidth_sq_) {
00265 return 1 - sqdist * inv_bandwidth_sq_;
00266 } else {
00267 return 0;
00268 }
00269 }
00270
00272 DRange RangeUnnormOnSq(const DRange& range) const {
00273 return DRange(EvalUnnormOnSq(range.hi), EvalUnnormOnSq(range.lo));
00274 }
00275
00279 double MaxUnnormValue() {
00280 return 1.0;
00281 }
00282
00286 double CalcNormConstant(index_t dims) const {
00287 return 2.0 * math::SphereVolume(sqrt(bandwidth_sq_), dims)
00288 / (dims + 2.0);
00289 }
00290
00294 double bandwidth_sq() const {
00295 return bandwidth_sq_;
00296 }
00297
00301 double inv_bandwidth_sq() const {
00302 return inv_bandwidth_sq_;
00303 }
00304 };
00305
00306
00307 #endif