00001
00002 #ifndef bsta_gaussian_sphere_txx_
00003 #define bsta_gaussian_sphere_txx_
00004
00005
00006
00007 #include "bsta_gaussian_sphere.h"
00008 #include <vcl_cassert.h>
00009 #include <vcl_limits.h>
00010 #include <vnl/vnl_erf.h>
00011
00012 namespace
00013 {
00014
00015 template <class T, unsigned n, unsigned index>
00016 struct bsta_gaussian_sphere_compute_dot
00017 {
00018 static inline T value(const vnl_vector_fixed<T,n>& d)
00019 {
00020 return d[index-1]*d[index-1]
00021 + bsta_gaussian_sphere_compute_dot<T,n,index-1>::value(d);
00022 }
00023 };
00024
00025
00026
00027 template <class T, unsigned n>
00028 struct bsta_gaussian_sphere_compute_dot<T,n,0>
00029 {
00030 static inline T value(const vnl_vector_fixed<T,n>& )
00031 { return 0; }
00032 };
00033
00034
00035
00036 template <class T>
00037 struct bsta_gaussian_sphere_compute_dot<T,1,1>
00038 {
00039 static inline T value(const T& d)
00040 { return d*d; }
00041 };
00042
00043
00044
00045 template <class T, unsigned n, unsigned index>
00046 struct bsta_gaussian_sphere_determinant
00047 {
00048 static inline T value(const T& var)
00049 {
00050 return var * bsta_gaussian_sphere_determinant<T,n,index-1>::value(var);
00051 }
00052 };
00053
00054
00055
00056 template <class T, unsigned n>
00057 struct bsta_gaussian_sphere_determinant<T,n,0>
00058 {
00059 static inline T value(const T& ) { return 1; }
00060 };
00061 }
00062
00063
00064
00065 template <class T, unsigned int n>
00066 T
00067 bsta_gaussian_sphere<T,n>::sqr_mahalanobis_dist(const vector_& pt) const
00068 {
00069 if (var_<=T(0))
00070 return vcl_numeric_limits<T>::infinity();
00071 vector_ d = bsta_gaussian<T,n>::mean_-pt;
00072 return bsta_gaussian_sphere_compute_dot<T,n,n>::value(d)/var_;
00073 }
00074
00075
00076
00077 template <class T, class vector_, unsigned n, unsigned index>
00078 struct bsta_gaussian_sphere_compute_probability_box
00079 {
00080 static inline T value(const vector_& min_minus_mean,
00081 const vector_& max_minus_mean,
00082 const T& var
00083 )
00084 {
00085 if (var<=T(0))
00086 return vcl_numeric_limits<T>::infinity();
00087 double sigma_sq_2 = 2.0*static_cast<double>(var);
00088 double s2 = 1/vcl_sqrt(sigma_sq_2);
00089 double temp = vnl_erf(max_minus_mean[index]*s2);
00090 temp -= vnl_erf(min_minus_mean[index]*s2);
00091 T res = static_cast<T>(0.5*temp);
00092 res *= bsta_gaussian_sphere_compute_probability_box<T,vector_,n,index-1>::value(min_minus_mean,
00093 max_minus_mean,
00094 var);
00095 return res;
00096 }
00097 };
00098
00099
00100
00101 template <class T, class vector_, unsigned n>
00102 struct bsta_gaussian_sphere_compute_probability_box<T,vector_,n,0>
00103 {
00104 static inline T value(const vector_& min_minus_mean,
00105 const vector_& max_minus_mean,
00106 const T& var)
00107 {
00108 if (var<=T(0))
00109 return vcl_numeric_limits<T>::infinity();
00110 double sigma_sq_2 = 2.0*static_cast<double>(var);
00111 double s2 = 1/vcl_sqrt(sigma_sq_2);
00112 double temp = vnl_erf(max_minus_mean[0]*s2);
00113 temp -= vnl_erf(min_minus_mean[0]*s2);
00114 return static_cast<T>(0.5*temp);
00115 }
00116 };
00117
00118
00119
00120
00121 template <class T, class vector_>
00122 struct bsta_gaussian_sphere_compute_probability_box<T,vector_,1,0>
00123 {
00124 static inline T value(const vector_& min_minus_mean,
00125 const vector_& max_minus_mean,
00126 const T& var)
00127 {
00128 if (var<=T(0))
00129 return vcl_numeric_limits<T>::infinity();
00130 double sigma_sq_2 = 2.0*static_cast<double>(var);
00131 double s2 = 1/vcl_sqrt(sigma_sq_2);
00132 double temp = vnl_erf(max_minus_mean*s2);
00133 temp -= vnl_erf(min_minus_mean*s2);
00134 return static_cast<T>(0.5*temp);
00135 };
00136 };
00137
00138
00139
00140 template <class T, unsigned int n>
00141 T bsta_gaussian_sphere<T,n>::probability(const vector_& min_pt,
00142 const vector_& max_pt) const
00143 {
00144 vector_ min_minus_mean = min_pt-bsta_gaussian<T,n>::mean_;
00145 vector_ max_minus_mean = max_pt-bsta_gaussian<T,n>::mean_;
00146 return bsta_gaussian_sphere_compute_probability_box<T, vector_, n, n-1>::value(min_minus_mean,
00147 max_minus_mean,
00148 var_);
00149 }
00150
00151
00152 template <class T, unsigned int n>
00153 void
00154 bsta_gaussian_sphere<T,n>::compute_det()
00155 {
00156 det_covar_ = bsta_gaussian_sphere_determinant<T,n,n>::value(var_);
00157 assert(det_covar_ >= 0);
00158 }
00159
00160
00161
00162
00163 template <class T, class vector_, unsigned n, unsigned index>
00164 struct var_from_dist
00165 {
00166 static inline vector_ value(const T& var, vnl_random& rng)
00167 {
00168 T s = (T)(vcl_sqrt(var)*rng.normal());
00169 vector_ res(T(0));
00170 res[index] = s;
00171 res += var_from_dist<T,vector_,n,index-1>::value(var, rng);
00172 return res;
00173 }
00174 };
00175
00176
00177
00178 template <class T, class vector_, unsigned n>
00179 struct var_from_dist<T,vector_,n,0>
00180 {
00181 static inline vector_ value(const T& var, vnl_random& rng)
00182 {
00183 T s = (T)(vcl_sqrt(var)*rng.normal());
00184 vector_ res(T(0));
00185 res[0] = s;
00186 return res;
00187 };
00188 };
00189
00190
00191
00192
00193 template <class T, class vector_>
00194 struct var_from_dist<T,vector_,1,0>
00195 {
00196 static inline vector_ value(const T& var, vnl_random& rng)
00197 {
00198 T s = (T)(vcl_sqrt(var)*rng.normal());
00199 vector_ res(s);
00200 return res;
00201 };
00202 };
00203
00204
00205
00206 template <class T, unsigned int n>
00207 typename bsta_gaussian_sphere<T,n>::vector_ bsta_gaussian_sphere<T,n>::sample(vnl_random& rng) const
00208 {
00209 vector_ mean = bsta_gaussian<T,n>::mean_;
00210 vector_ var = var_from_dist<T, vector_, n, n-1>::value(var_, rng);
00211 return mean+var;
00212 }
00213
00214 #define BSTA_GAUSSIAN_SPHERE_INSTANTIATE(T,n) \
00215 template class bsta_gaussian_sphere<T,n >
00216
00217
00218 #endif // bsta_gaussian_sphere_txx_