Go to the documentation of this file.00001
00002 #ifndef vpdl_kernel_gaussian_sfbw_h_
00003 #define vpdl_kernel_gaussian_sfbw_h_
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <vpdl/vpdl_kernel_base.h>
00016 #include <vpdl/vpdt/vpdt_access.h>
00017 #include <vnl/vnl_erf.h>
00018 #include <vcl_limits.h>
00019 #include <vcl_cassert.h>
00020
00021
00022
00023 template<class T, unsigned int n=0>
00024 class vpdl_kernel_gaussian_sfbw : public vpdl_kernel_fbw_base<T,n>
00025 {
00026 public:
00027
00028 typedef typename vpdt_field_default<T,n>::type vector;
00029
00030 typedef typename vpdt_field_traits<vector>::matrix_type matrix;
00031
00032
00033 vpdl_kernel_gaussian_sfbw() {}
00034
00035
00036 vpdl_kernel_gaussian_sfbw(const vcl_vector<vector>& samplez,
00037 T bandwid = T(1))
00038 : vpdl_kernel_fbw_base<T,n>(samplez,bandwid) {}
00039
00040
00041 virtual vpdl_distribution<T,n>* clone() const
00042 {
00043 return new vpdl_kernel_gaussian_sfbw<T,n>(*this);
00044 }
00045
00046
00047 virtual T density(const vector& pt) const
00048 {
00049 const unsigned int nc = this->num_components();
00050 if (nc <= 0)
00051 return 0.0;
00052
00053 const unsigned int d = this->dimension();
00054 T sum = T(0);
00055 typedef typename vcl_vector<vector>::const_iterator vitr;
00056 for (vitr s=this->samples().begin(); s!=this->samples().end(); ++s) {
00057 T ssd = T(0);
00058 for (unsigned int i=0; i<d; ++i) {
00059 T tmp = (vpdt_index(pt,i)-vpdt_index(*s,i))/this->bandwidth();
00060 ssd += tmp*tmp;
00061 }
00062 sum += T(vcl_exp(-0.5*ssd));
00063 }
00064
00065 return sum;
00066 }
00067
00068
00069 virtual T prob_density(const vector& pt) const
00070 {
00071 const unsigned int nc = this->num_components();
00072 if (nc <= 0)
00073 return 0.0;
00074
00075 return density(pt)*this->norm_const();
00076 }
00077
00078
00079
00080
00081
00082 virtual T gradient_density(const vector& pt, vector& g) const
00083 {
00084 const unsigned int d = this->dimension();
00085 vpdt_set_size(g,d);
00086 vpdt_fill(g,T(0));
00087 const unsigned int nc = this->num_components();
00088 if (nc <= 0)
00089 return 0.0;
00090
00091 T sum = T(0);
00092 vector g_s;
00093 vpdt_set_size(g_s,d);
00094 typedef typename vcl_vector<vector>::const_iterator vitr;
00095 for (vitr s=this->samples().begin(); s!=this->samples().end(); ++s) {
00096 T ssd = T(0);
00097 for (unsigned int i=0; i<d; ++i) {
00098 T tmp = (vpdt_index(pt,i)-vpdt_index(*s,i))/this->bandwidth();
00099 vpdt_index(g_s,i) = tmp/this->bandwidth();
00100 ssd += tmp*tmp;
00101 }
00102 T dens = T(vcl_exp(-0.5*ssd));
00103 g_s *= -dens;
00104 sum += dens;
00105 g += g_s;
00106 }
00107
00108 return sum;
00109 }
00110
00111
00112
00113
00114 virtual T cumulative_prob(const vector& pt) const
00115 {
00116 const unsigned int nc = this->num_components();
00117 if (nc <= 0)
00118 return 0.0;
00119
00120 const unsigned int d = this->dimension();
00121 double s2 = 1/(this->bandwidth()*vcl_sqrt(2.0));
00122
00123 double sum = 0.0;
00124 typedef typename vcl_vector<vector>::const_iterator vitr;
00125 for (vitr s=this->samples().begin(); s!=this->samples().end(); ++s) {
00126 double val = 1.0;
00127 for (unsigned int i=0; i<d; ++i) {
00128 val *= 0.5*vnl_erf(s2*(vpdt_index(pt,i)-vpdt_index(*s,i))) + 0.5;
00129 }
00130 sum += val;
00131 }
00132 return static_cast<T>(sum/nc);
00133 }
00134
00135
00136
00137
00138 T box_prob(const vector& min_pt, const vector& max_pt) const
00139 {
00140 const unsigned int nc = this->num_components();
00141 if (nc <= 0)
00142 return 0.0;
00143
00144 const unsigned int dim = this->dimension();
00145 double s2 = 1/(this->bandwidth()*vcl_sqrt(2.0));
00146
00147 double sum = 0.0;
00148 typedef typename vcl_vector<vector>::const_iterator vitr;
00149 for (vitr s=this->samples().begin(); s!=this->samples().end(); ++s) {
00150 double prob = 1.0;
00151 for (unsigned int i=0; i<dim; ++i) {
00152 if (vpdt_index(max_pt,i)<=vpdt_index(min_pt,i))
00153 return T(0);
00154 prob *= (vnl_erf(s2*(vpdt_index(max_pt,i)-vpdt_index(*s,i))) -
00155 vnl_erf(s2*(vpdt_index(min_pt,i)-vpdt_index(*s,i))))/2;
00156 }
00157 sum += prob;
00158 }
00159 return static_cast<T>(sum/nc);
00160 }
00161
00162
00163 virtual void compute_covar(matrix& covar) const
00164 {
00165 const unsigned int d = this->dimension();
00166 const unsigned int nc = this->num_components();
00167 vector mean;
00168 vpdt_set_size(covar,d);
00169 vpdt_fill(covar,T(0));
00170 vpdt_set_size(mean,d);
00171 vpdt_fill(mean,T(0));
00172 typedef typename vcl_vector<vector>::const_iterator samp_itr;
00173 for (samp_itr s = this->samples().begin(); s != this->samples().end(); ++s) {
00174 covar += outer_product(*s,*s);
00175 mean += *s;
00176 }
00177 mean /= T(nc);
00178 covar /= T(nc);
00179 covar -= outer_product(mean,mean);
00180 T var = this->bandwidth()*this->bandwidth();
00181 for (unsigned int i=0; i<d; ++i)
00182 vpdt_index(covar,i,i) += var;
00183 }
00184
00185
00186 virtual T kernel_norm_const() const
00187 {
00188 const unsigned int dim = this->dimension();
00189 double v2pi = this->bandwidth()*this->bandwidth()*2.0*vnl_math::pi;
00190 double denom = v2pi;
00191 for (unsigned int i=1; i<dim; ++i)
00192 denom *= v2pi;
00193
00194 return static_cast<T>(vcl_sqrt(1/denom));
00195 }
00196 };
00197
00198
00199 #endif // vpdl_kernel_gaussian_sfbw_h_