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 #ifndef mrpt_math_container_ops_H
00029 #define mrpt_math_container_ops_H
00030
00031 #include <mrpt/math/math_frwds.h>
00032
00033 #include <mrpt/math/lightweight_geom_data.h>
00034
00035 #include <functional>
00036 #include <algorithm>
00037 #include <cmath>
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include <algorithm>
00057 #include <numeric>
00058 #include <functional>
00059
00060 #include <mrpt/math/CHistogram.h>
00061
00062
00063 namespace mrpt
00064 {
00065 namespace math
00066 {
00067
00068
00069
00070
00071 template<class CONTAINER>
00072 vector_double histogram(
00073 const CONTAINER &v,
00074 double limit_min,
00075 double limit_max,
00076 size_t number_bins,
00077 bool do_normalization = false,
00078 vector_double *out_bin_centers = NULL)
00079 {
00080 mrpt::math::CHistogram H( limit_min, limit_max, number_bins );
00081 vector_double ret(number_bins);
00082 vector_double dummy_ret_bins;
00083 H.add(v);
00084 if (do_normalization)
00085 H.getHistogramNormalized( out_bin_centers ? *out_bin_centers : dummy_ret_bins, ret );
00086 else H.getHistogram( out_bin_centers ? *out_bin_centers : dummy_ret_bins, ret );
00087 return ret;
00088 }
00089
00090
00091
00092
00093
00094 template <class CONTAINER1,class CONTAINER2>
00095 inline void cumsum(const CONTAINER1 &in_data, CONTAINER2 &out_cumsum)
00096 {
00097 out_cumsum.resizeLike(in_data);
00098 typename CONTAINER1::value_type last=0;
00099 const size_t N = in_data.size();
00100 for (size_t i=0;i<N;i++)
00101 last = out_cumsum[i] = last + in_data[i];
00102 }
00103
00104
00105
00106 template<class CONTAINER>
00107 inline CONTAINER cumsum(const CONTAINER &in_data)
00108 {
00109 CONTAINER ret;
00110 cumsum(in_data,ret);
00111 return ret;
00112 }
00113
00114 template <class CONTAINER> inline typename CONTAINER::value_type norm_inf(const CONTAINER &v) { return v.norm_inf(); }
00115 template <class CONTAINER> inline typename CONTAINER::value_type norm(const CONTAINER &v) { return v.norm(); }
00116 template <class CONTAINER> inline typename CONTAINER::value_type maximum(const CONTAINER &v) { return v.maximum(); }
00117 template <class CONTAINER> inline typename CONTAINER::value_type minimum(const CONTAINER &v) { return v.minimum(); }
00118
00119 template <typename T> inline T maximum(const std::vector<T> &v)
00120 {
00121 ASSERT_(!v.empty())
00122 T m = v[0];
00123 for (size_t i=0;i<v.size();i++) mrpt::utils::keep_max(m,v[i]);
00124 return m;
00125 }
00126 template <typename T> inline T minimum(const std::vector<T> &v)
00127 {
00128 ASSERT_(!v.empty())
00129 T m = v[0];
00130 for (size_t i=0;i<v.size();i++) mrpt::utils::keep_min(m,v[i]);
00131 return m;
00132 }
00133
00134
00135
00136
00137
00138
00139 template <class CONTAINER> CONTAINER & containerFromPoseOrPoint(CONTAINER &C, const TPoint2D &p) {
00140 C.resize(2,1);
00141 for (size_t i=0;i<2;i++) C.coeffRef(i,0)=p[i];
00142 return C;
00143 }
00144 template <class CONTAINER> CONTAINER & containerFromPoseOrPoint(CONTAINER &C, const TPoint3D &p) {
00145 C.resize(3,1);
00146 for (size_t i=0;i<3;i++) C.coeffRef(i,0)=p[i];
00147 return C;
00148 }
00149 template <class CONTAINER> CONTAINER & containerFromPoseOrPoint(CONTAINER &C, const TPose2D &p) {
00150 C.resize(3,1);
00151 for (size_t i=0;i<3;i++) C.coeffRef(i,0)=p[i];
00152 return C;
00153 }
00154 template <class CONTAINER> CONTAINER & containerFromPoseOrPoint(CONTAINER &C, const TPose3D &p) {
00155 C.resize(6,1);
00156 for (size_t i=0;i<6;i++) C.coeffRef(i,0)=p[i];
00157 return C;
00158 }
00159 template <class CONTAINER> CONTAINER & containerFromPoseOrPoint(CONTAINER &C, const TPose3DQuat &p) {
00160 C.resize(7,1);
00161 for (size_t i=0;i<7;i++) C.coeffRef(i,0)=p[i];
00162 return C;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 template <class CONTAINER>
00175 typename CONTAINER::value_type squareNorm_accum(const typename CONTAINER::value_type total, const CONTAINER &v);
00176 template <class CONTAINER> typename CONTAINER::value_type squareNorm_accum(const typename CONTAINER::value_type total, const CONTAINER &v) {
00177 return total+v.squaredNorm();
00178 }
00179
00180
00181
00182 template<size_t N,class T,class U>
00183 inline T squareNorm(const U &v) {
00184 T res=0;
00185 for (size_t i=0;i<N;i++) res+=square(v[i]);
00186 return res;
00187 }
00188
00189
00190 template <class CONTAINER1,class CONTAINER2>
00191 inline typename CONTAINER1::value_type
00192 dotProduct(const CONTAINER1 &v1,const CONTAINER1 &v2)
00193 {
00194 return v1.dot(v2);
00195 }
00196
00197
00198 template<size_t N,class T,class U,class V>
00199 inline T dotProduct(const U &v1,const V &v2) {
00200 T res=0;
00201 for (size_t i=0;i<N;i++) res+=v1[i]*v2[i];
00202 return res;
00203 }
00204
00205
00206
00207
00208 template <class CONTAINER> inline typename CONTAINER::value_type sum(const CONTAINER &v) { return v.sum(); }
00209
00210
00211 template <typename T> inline T sum(const std::vector<T> &v) { return std::accumulate(v.begin(),v.end(),T(0)); }
00212
00213
00214
00215 template <class CONTAINER,typename RET> inline RET sumRetType(const CONTAINER &v) { return v.sumRetType<RET>(); }
00216
00217
00218
00219 template <class CONTAINER>
00220 inline double mean(const CONTAINER &v)
00221 {
00222 if (v.empty())
00223 return 0;
00224 else return sum(v)/static_cast<double>(v.size());
00225 }
00226
00227
00228 template <typename T>
00229 inline void minimum_maximum(const std::vector<T> &V, T&curMin,T&curMax)
00230 {
00231 ASSERT_(V.size()!=0)
00232 const size_t N=V.size();
00233 curMin=curMax=V[0];
00234 for (size_t i=1;i<N;i++)
00235 {
00236 mrpt::utils::keep_min(curMin,V[i]);
00237 mrpt::utils::keep_max(curMax,V[i]);
00238 }
00239 }
00240
00241
00242 template <class Derived>
00243 inline void minimum_maximum(
00244 const Eigen::MatrixBase<Derived> &V,
00245 typename Eigen::MatrixBase<Derived>::value_type &curMin,
00246 typename Eigen::MatrixBase<Derived>::value_type &curMax)
00247 {
00248 V.minimum_maximum(curMin,curMax);
00249 }
00250
00251
00252
00253 template <class CONTAINER1,class CONTAINER2>
00254 size_t countCommonElements(const CONTAINER1 &a,const CONTAINER2 &b)
00255 {
00256 size_t ret=0;
00257 for (typename CONTAINER1::const_iterator it1 = a.begin();it1!=a.end();it1++)
00258 for (typename CONTAINER2::const_iterator it2 = b.begin();it2!=b.end();it2++)
00259 if ( (*it1) == (*it2) )
00260 ret++;
00261 return ret;
00262 }
00263
00264
00265 template <class CONTAINER>
00266 void adjustRange(CONTAINER &m, const typename CONTAINER::value_type minVal,const typename CONTAINER::value_type maxVal)
00267 {
00268 if (size_t(m.size())==0) return;
00269 typename CONTAINER::value_type curMin,curMax;
00270 minimum_maximum(m,curMin,curMax);
00271 const typename CONTAINER::value_type curRan = curMax-curMin;
00272 m -= (curMin+minVal);
00273 if (curRan!=0) m *= (maxVal-minVal)/curRan;
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 template<class VECTORLIKE>
00285 void meanAndStd(
00286 const VECTORLIKE &v,
00287 double &out_mean,
00288 double &out_std,
00289 bool unbiased = true)
00290 {
00291 if (v.size()<2)
00292 {
00293 out_std = 0;
00294 out_mean = (v.size()==1) ? *v.begin() : 0;
00295 }
00296 else
00297 {
00298
00299 const size_t N = v.size();
00300 out_mean = mrpt::math::sum(v) / static_cast<double>(N);
00301
00302 double vector_std=0;
00303 for (size_t i=0;i<N;i++) vector_std += mrpt::utils::square( v[i]-out_mean);
00304 out_std = std::sqrt(vector_std / static_cast<double>(N - (unbiased ? 1:0)) );
00305 }
00306 }
00307
00308
00309
00310
00311
00312
00313
00314 template<class VECTORLIKE>
00315 inline double stddev(const VECTORLIKE &v, bool unbiased = true)
00316 {
00317 double m,s;
00318 meanAndStd(v,m,s,unbiased);
00319 return s;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328 template<class VECTOR_OF_VECTOR, class VECTORLIKE, class MATRIXLIKE>
00329 void meanAndCovVec(
00330 const VECTOR_OF_VECTOR &v,
00331 VECTORLIKE &out_mean,
00332 MATRIXLIKE &out_cov
00333 )
00334 {
00335 const size_t N = v.size();
00336 ASSERTMSG_(N>0,"The input vector contains no elements");
00337 const double N_inv = 1.0/N;
00338
00339 const size_t M = v[0].size();
00340 ASSERTMSG_(M>0,"The input vector contains rows of length 0");
00341
00342
00343 out_mean.assign(M,0);
00344 for (size_t i=0;i<N;i++)
00345 for (size_t j=0;j<M;j++)
00346 out_mean[j]+=v[i][j];
00347 out_mean*=N_inv;
00348
00349
00350
00351
00352 out_cov.zeros(M,M);
00353 for (size_t i=0;i<N;i++)
00354 {
00355 for (size_t j=0;j<M;j++)
00356 out_cov.get_unsafe(j,j)+=square(v[i][j]-out_mean[j]);
00357
00358 for (size_t j=0;j<M;j++)
00359 for (size_t k=j+1;k<M;k++)
00360 out_cov.get_unsafe(j,k)+=(v[i][j]-out_mean[j])*(v[i][k]-out_mean[k]);
00361 }
00362 for (size_t j=0;j<M;j++)
00363 for (size_t k=j+1;k<M;k++)
00364 out_cov.get_unsafe(k,j) = out_cov.get_unsafe(j,k);
00365 out_cov*=N_inv;
00366 }
00367
00368
00369
00370
00371
00372
00373 template<class VECTOR_OF_VECTOR>
00374 inline Eigen::MatrixXd covVector( const VECTOR_OF_VECTOR &v )
00375 {
00376 vector_double m;
00377 Eigen::MatrixXd C;
00378 meanAndCovVec(v,m,C);
00379 return C;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389 template <class CONT1,class CONT2>
00390 double ncc_vector( const CONT1 &patch1, const CONT2 &patch2 )
00391 {
00392 ASSERT_( patch1.size()==patch2.size() )
00393
00394 double numerator = 0, sum_a = 0, sum_b = 0, result, a_mean, b_mean;
00395 a_mean = patch1.mean();
00396 b_mean = patch2.mean();
00397
00398 const size_t N = patch1.size();
00399 for(size_t i=0;i<N;++i)
00400 {
00401 numerator += (patch1[i]-a_mean)*(patch2[i]-b_mean);
00402 sum_a += mrpt::utils::square(patch1[i]-a_mean);
00403 sum_b += mrpt::utils::square(patch2[i]-b_mean);
00404 }
00405 ASSERTMSG_(sum_a*sum_b!=0,"Divide by zero when normalizing.")
00406 result=numerator/std::sqrt(sum_a*sum_b);
00407 return result;
00408 }
00409
00410
00411
00412 }
00413 }
00414
00415
00416
00417 #endif