00001 #include <stdlib.h>
00002
00003
00004
00005
00006
00007 #include <math.h>
00008 #include <gmapping/utils/stat.h>
00009
00010 namespace GMapping {
00011
00012 #if 0
00013
00014 int sampleUniformInt(int max)
00015 {
00016 return (int)(max*(rand()/(RAND_MAX+1.0)));
00017 }
00018
00019 double sampleUniformDouble(double min, double max)
00020 {
00021 return min + (rand() / (double)RAND_MAX) * (max - min);
00022 }
00023
00024
00025 #endif
00026
00027
00028
00029
00030
00031 double pf_ran_gaussian(double sigma)
00032 {
00033 double x1, x2, w;
00034 double r;
00035
00036 do
00037 {
00038 do { r = drand48(); } while (r == 0.0);
00039 x1 = 2.0 * r - 1.0;
00040 do { r = drand48(); } while (r == 0.0);
00041 x2 = 2.0 * drand48() - 1.0;
00042 w = x1*x1 + x2*x2;
00043 } while(w > 1.0 || w==0.0);
00044
00045 return(sigma * x2 * sqrt(-2.0*log(w)/w));
00046 }
00047
00048 double sampleGaussian(double sigma, unsigned int S) {
00049
00050
00051
00052
00053
00054
00055
00056 if (S!=0)
00057 {
00058
00059 srand(S);
00060 }
00061 if (sigma==0)
00062 return 0;
00063
00064 return pf_ran_gaussian (sigma);
00065 }
00066 #if 0
00067
00068 double evalGaussian(double sigmaSquare, double delta){
00069 if (sigmaSquare<=0)
00070 sigmaSquare=1e-4;
00071 return exp(-.5*delta*delta/sigmaSquare)/sqrt(2*M_PI*sigmaSquare);
00072 }
00073
00074 #endif
00075 double evalLogGaussian(double sigmaSquare, double delta){
00076 if (sigmaSquare<=0)
00077 sigmaSquare=1e-4;
00078 return -.5*delta*delta/sigmaSquare-.5*log(2*M_PI*sigmaSquare);
00079 }
00080 #if 0
00081
00082
00083 Covariance3 Covariance3::zero={0.,0.,0.,0.,0.,0.};
00084
00085 Covariance3 Covariance3::operator + (const Covariance3 & cov) const{
00086 Covariance3 r(*this);
00087 r.xx+=cov.xx;
00088 r.yy+=cov.yy;
00089 r.tt+=cov.tt;
00090 r.xy+=cov.xy;
00091 r.yt+=cov.yt;
00092 r.xt+=cov.xt;
00093 return r;
00094 }
00095
00096 EigenCovariance3::EigenCovariance3(){}
00097
00098 EigenCovariance3::EigenCovariance3(const Covariance3& cov){
00099 static gsl_eigen_symmv_workspace * m_eigenspace=NULL;
00100 static gsl_matrix * m_cmat=NULL;
00101 static gsl_matrix * m_evec=NULL;
00102 static gsl_vector * m_eval=NULL;
00103 static gsl_vector * m_noise=NULL;
00104 static gsl_vector * m_pnoise=NULL;
00105
00106 if (m_eigenspace==NULL){
00107 m_eigenspace=gsl_eigen_symmv_alloc(3);
00108 m_cmat=gsl_matrix_alloc(3,3);
00109 m_evec=gsl_matrix_alloc(3,3);
00110 m_eval=gsl_vector_alloc(3);
00111 m_noise=gsl_vector_alloc(3);
00112 m_pnoise=gsl_vector_alloc(3);
00113 }
00114
00115 gsl_matrix_set(m_cmat,0,0,cov.xx); gsl_matrix_set(m_cmat,0,1,cov.xy); gsl_matrix_set(m_cmat,0,2,cov.xt);
00116 gsl_matrix_set(m_cmat,1,0,cov.xy); gsl_matrix_set(m_cmat,1,1,cov.yy); gsl_matrix_set(m_cmat,1,2,cov.yt);
00117 gsl_matrix_set(m_cmat,2,0,cov.xt); gsl_matrix_set(m_cmat,2,1,cov.yt); gsl_matrix_set(m_cmat,2,2,cov.tt);
00118 gsl_eigen_symmv (m_cmat, m_eval, m_evec, m_eigenspace);
00119 for (int i=0; i<3; i++){
00120 eval[i]=gsl_vector_get(m_eval,i);
00121 for (int j=0; j<3; j++)
00122 evec[i][j]=gsl_matrix_get(m_evec,i,j);
00123 }
00124 }
00125
00126 EigenCovariance3 EigenCovariance3::rotate(double angle) const{
00127 static gsl_matrix * m_rmat=NULL;
00128 static gsl_matrix * m_vmat=NULL;
00129 static gsl_matrix * m_result=NULL;
00130 if (m_rmat==NULL){
00131 m_rmat=gsl_matrix_alloc(3,3);
00132 m_vmat=gsl_matrix_alloc(3,3);
00133 m_result=gsl_matrix_alloc(3,3);
00134 }
00135
00136 double c=cos(angle);
00137 double s=sin(angle);
00138 gsl_matrix_set(m_rmat,0,0, c ); gsl_matrix_set(m_rmat,0,1, -s); gsl_matrix_set(m_rmat,0,2, 0.);
00139 gsl_matrix_set(m_rmat,1,0, s ); gsl_matrix_set(m_rmat,1,1, c); gsl_matrix_set(m_rmat,1,2, 0.);
00140 gsl_matrix_set(m_rmat,2,0, 0.); gsl_matrix_set(m_rmat,2,1, 0.); gsl_matrix_set(m_rmat,2,2, 1.);
00141
00142 for (unsigned int i=0; i<3; i++)
00143 for (unsigned int j=0; j<3; j++)
00144 gsl_matrix_set(m_vmat,i,j,evec[i][j]);
00145 gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1., m_rmat, m_vmat, 0., m_result);
00146 EigenCovariance3 ecov(*this);
00147 for (int i=0; i<3; i++){
00148 for (int j=0; j<3; j++)
00149 ecov.evec[i][j]=gsl_matrix_get(m_result,i,j);
00150 }
00151 return ecov;
00152 }
00153
00154 OrientedPoint EigenCovariance3::sample() const{
00155 static gsl_matrix * m_evec=NULL;
00156 static gsl_vector * m_noise=NULL;
00157 static gsl_vector * m_pnoise=NULL;
00158 if (m_evec==NULL){
00159 m_evec=gsl_matrix_alloc(3,3);
00160 m_noise=gsl_vector_alloc(3);
00161 m_pnoise=gsl_vector_alloc(3);
00162 }
00163 for (int i=0; i<3; i++){
00164 for (int j=0; j<3; j++)
00165 gsl_matrix_set(m_evec,i,j, evec[i][j]);
00166 }
00167 for (int i=0; i<3; i++){
00168 double v=sampleGaussian(sqrt(eval[i]));
00169 if(isnan(v))
00170 v=0;
00171 gsl_vector_set(m_pnoise,i, v);
00172 }
00173 gsl_blas_dgemv (CblasNoTrans, 1., m_evec, m_pnoise, 0, m_noise);
00174 OrientedPoint ret(gsl_vector_get(m_noise,0),gsl_vector_get(m_noise,1),gsl_vector_get(m_noise,2));
00175 ret.theta=atan2(sin(ret.theta), cos(ret.theta));
00176 return ret;
00177 }
00178
00179 #endif
00180
00181 double Gaussian3::eval(const OrientedPoint& p) const{
00182 OrientedPoint q=p-mean;
00183 q.theta=atan2(sin(p.theta-mean.theta),cos(p.theta-mean.theta));
00184 double v1,v2,v3;
00185 v1 = covariance.evec[0][0]*q.x+covariance.evec[1][0]*q.y+covariance.evec[2][0]*q.theta;
00186 v2 = covariance.evec[0][1]*q.x+covariance.evec[1][1]*q.y+covariance.evec[2][1]*q.theta;
00187 v3 = covariance.evec[0][2]*q.x+covariance.evec[1][2]*q.y+covariance.evec[2][2]*q.theta;
00188 return evalLogGaussian(covariance.eval[0], v1)+evalLogGaussian(covariance.eval[1], v2)+evalLogGaussian(covariance.eval[2], v3);
00189 }
00190
00191 #if 0
00192 void Gaussian3::computeFromSamples(const std::vector<OrientedPoint> & poses, const std::vector<double>& weights ){
00193 OrientedPoint mean=OrientedPoint(0,0,0);
00194 double wcum=0;
00195 double s=0, c=0;
00196 std::vector<double>::const_iterator w=weights.begin();
00197 for (std::vector<OrientedPoint>::const_iterator p=poses.begin(); p!=poses.end(); p++){
00198 s+=*w*sin(p->theta);
00199 c+=*w*cos(p->theta);
00200 mean.x+=*w*p->x;
00201 mean.y+=*w*p->y;
00202 wcum+=*w;
00203 w++;
00204 }
00205 mean.x/=wcum;
00206 mean.y/=wcum;
00207 s/=wcum;
00208 c/=wcum;
00209 mean.theta=atan2(s,c);
00210
00211 Covariance3 cov=Covariance3::zero;
00212 w=weights.begin();
00213 for (std::vector<OrientedPoint>::const_iterator p=poses.begin(); p!=poses.end(); p++){
00214 OrientedPoint delta=(*p)-mean;
00215 delta.theta=atan2(sin(delta.theta),cos(delta.theta));
00216 cov.xx+=*w*delta.x*delta.x;
00217 cov.yy+=*w*delta.y*delta.y;
00218 cov.tt+=*w*delta.theta*delta.theta;
00219 cov.xy+=*w*delta.x*delta.y;
00220 cov.yt+=*w*delta.y*delta.theta;
00221 cov.xt+=*w*delta.x*delta.theta;
00222 w++;
00223 }
00224 cov.xx/=wcum;
00225 cov.yy/=wcum;
00226 cov.tt/=wcum;
00227 cov.xy/=wcum;
00228 cov.yt/=wcum;
00229 cov.xt/=wcum;
00230 EigenCovariance3 ecov(cov);
00231 this->mean=mean;
00232 this->covariance=ecov;
00233 this->cov=cov;
00234 }
00235
00236 void Gaussian3::computeFromSamples(const std::vector<OrientedPoint> & poses){
00237 OrientedPoint mean=OrientedPoint(0,0,0);
00238 double wcum=1;
00239 double s=0, c=0;
00240 for (std::vector<OrientedPoint>::const_iterator p=poses.begin(); p!=poses.end(); p++){
00241 s+=sin(p->theta);
00242 c+=cos(p->theta);
00243 mean.x+=p->x;
00244 mean.y+=p->y;
00245 wcum+=1.;
00246 }
00247 mean.x/=wcum;
00248 mean.y/=wcum;
00249 s/=wcum;
00250 c/=wcum;
00251 mean.theta=atan2(s,c);
00252
00253 Covariance3 cov=Covariance3::zero;
00254 for (std::vector<OrientedPoint>::const_iterator p=poses.begin(); p!=poses.end(); p++){
00255 OrientedPoint delta=(*p)-mean;
00256 delta.theta=atan2(sin(delta.theta),cos(delta.theta));
00257 cov.xx+=delta.x*delta.x;
00258 cov.yy+=delta.y*delta.y;
00259 cov.tt+=delta.theta*delta.theta;
00260 cov.xy+=delta.x*delta.y;
00261 cov.yt+=delta.y*delta.theta;
00262 cov.xt+=delta.x*delta.theta;
00263 }
00264 cov.xx/=wcum;
00265 cov.yy/=wcum;
00266 cov.tt/=wcum;
00267 cov.xy/=wcum;
00268 cov.yt/=wcum;
00269 cov.xt/=wcum;
00270 EigenCovariance3 ecov(cov);
00271 this->mean=mean;
00272 this->covariance=ecov;
00273 this->cov=cov;
00274 }
00275 #endif
00276
00277 }
00278