00001
00002 #ifndef bsta_gaussian_indep_txx_
00003 #define bsta_gaussian_indep_txx_
00004
00005
00006
00007 #include "bsta_gaussian_indep.h"
00008 #include <vcl_limits.h>
00009 #include <vnl/vnl_erf.h>
00010
00011 namespace
00012 {
00013
00014 template <class T, unsigned n, unsigned index>
00015 struct bsta_gaussian_indep_compute_sqr_mahalanobis
00016 {
00017 static inline T value(const vnl_vector_fixed<T,n>& d,
00018 const vnl_vector_fixed<T,n>& covar)
00019 {
00020 return d[index-1]*d[index-1]/covar[index-1]
00021 + bsta_gaussian_indep_compute_sqr_mahalanobis<T,n,index-1>::value(d,covar);
00022 }
00023 };
00024
00025
00026
00027 template <class T, unsigned n>
00028 struct bsta_gaussian_indep_compute_sqr_mahalanobis<T,n,0>
00029 {
00030 static inline T value(const vnl_vector_fixed<T,n>& ,
00031 const vnl_vector_fixed<T,n>& )
00032 { return 0; }
00033 };
00034
00035
00036
00037 template <class T, unsigned n, unsigned index>
00038 struct bsta_gaussian_indep_determinant
00039 {
00040 static inline T value(const vnl_vector_fixed<T,n>& covar)
00041 {
00042 return covar[index-1]*bsta_gaussian_indep_determinant<T,n,index-1>::value(covar);
00043 }
00044 };
00045
00046
00047
00048 template <class T, unsigned n>
00049 struct bsta_gaussian_indep_determinant<T,n,0>
00050 {
00051 static inline T value(const vnl_vector_fixed<T,n>& )
00052 { return 1; }
00053 };
00054 };
00055
00056
00057
00058 template <class T, unsigned int n>
00059 T
00060 bsta_gaussian_indep<T,n>::sqr_mahalanobis_dist(const vnl_vector_fixed<T,n>& pt) const
00061 {
00062 if (det_covar_<=T(0))
00063 return vcl_numeric_limits<T>::infinity();
00064 vnl_vector_fixed<T,n> d = bsta_gaussian<T,n>::mean_-pt;
00065 return bsta_gaussian_indep_compute_sqr_mahalanobis<T,n,n>::value(d,diag_covar_);
00066 }
00067
00068
00069
00070 template <class T, unsigned int n>
00071 void
00072 bsta_gaussian_indep<T,n>::compute_det()
00073 {
00074 det_covar_ = bsta_gaussian_indep_determinant<T,n,n>::value(diag_covar_);
00075 }
00076
00077
00078
00079 template <class T, unsigned n, unsigned index>
00080 struct bsta_gaussian_indep_compute_probability_box
00081 {
00082 static inline T value(const vnl_vector_fixed<T,n>& min_minus_mean,
00083 const vnl_vector_fixed<T,n>& max_minus_mean,
00084 const vnl_vector_fixed<T,n>& covar
00085 )
00086 {
00087 if (covar[index]<=T(0))
00088 return vcl_numeric_limits<T>::infinity();
00089 double sigma_sq_2 = 2.0*static_cast<double>(covar[index]);
00090 double s2 = 1/vcl_sqrt(sigma_sq_2);
00091 double temp = vnl_erf(max_minus_mean[index]*s2);
00092 temp -= vnl_erf(min_minus_mean[index]*s2);
00093 T res = static_cast<T>(0.5*temp);
00094 res *= bsta_gaussian_indep_compute_probability_box<T,n,index-1>::value(min_minus_mean,
00095 max_minus_mean,
00096 covar);
00097 return res;
00098 }
00099 };
00100
00101
00102
00103 template <class T, unsigned n>
00104 struct bsta_gaussian_indep_compute_probability_box<T,n,0>
00105 {
00106 static inline T value(const vnl_vector_fixed<T,n>& min_minus_mean,
00107 const vnl_vector_fixed<T,n>& max_minus_mean,
00108 const vnl_vector_fixed<T,n>& covar)
00109 {
00110 if (covar[0]<=T(0))
00111 return vcl_numeric_limits<T>::infinity();
00112 double sigma_sq_2 = 2.0*static_cast<double>(covar[0]);
00113 double s2 = 1/vcl_sqrt(sigma_sq_2);
00114 double temp = vnl_erf(max_minus_mean[0]*s2);
00115 temp -= vnl_erf(min_minus_mean[0]*s2);
00116 return static_cast<T>(0.5*temp);
00117 };
00118 };
00119
00120
00121
00122 template <class T, unsigned int n>
00123 T bsta_gaussian_indep<T,n>::probability(const vnl_vector_fixed<T,n>& min_pt,
00124 const vnl_vector_fixed<T,n>& max_pt) const
00125 {
00126 vnl_vector_fixed<T,n> min_minus_mean = min_pt-bsta_gaussian<T,n>::mean_;
00127 vnl_vector_fixed<T,n> max_minus_mean = max_pt-bsta_gaussian<T,n>::mean_;
00128 return bsta_gaussian_indep_compute_probability_box<T, n, n-1>::value(min_minus_mean,
00129 max_minus_mean,
00130 diag_covar_);
00131 }
00132
00133
00134 template <class T, unsigned int n>
00135 vnl_vector_fixed<T,n> bsta_gaussian_indep<T,n>::gradient(const vnl_vector_fixed<T,n>& pt) const
00136 {
00137 T pd = prob_density(pt);
00138 vnl_vector_fixed<T,n> h((pt[0]-this->mean_[0])/diag_covar_[0], (pt[1] - this->mean_[1])/diag_covar_[1], (pt[2] - this->mean_[2])/diag_covar_[2]);
00139 return -pd * h;
00140 }
00141
00142
00143 #define BSTA_GAUSSIAN_INDEP_INSTANTIATE(T,n) \
00144 template class bsta_gaussian_indep<T,n >
00145
00146
00147 #endif // bsta_gaussian_indep_txx_