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_H
00029 #define MRPT_MATH_H
00030
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/math/CMatrixTemplateNumeric.h>
00033 #include <mrpt/math/CMatrixFixedNumeric.h>
00034 #include <mrpt/math/CVectorTemplate.h>
00035 #include <mrpt/math/vector_ops.h>
00036 #include <mrpt/math/CHistogram.h>
00037
00038 #include <numeric>
00039 #include <cmath>
00040
00041
00042
00043
00044 namespace mrpt
00045 {
00046
00047
00048 namespace math
00049 {
00050 using namespace mrpt::utils;
00051
00052
00053
00054
00055
00056 bool MRPTDLLIMPEXP loadVector( utils::CFileStream &f, std::vector<int> &d);
00057
00058
00059
00060
00061
00062 bool MRPTDLLIMPEXP loadVector( utils::CFileStream &f, std::vector<double> &d);
00063
00064
00065
00066 bool MRPTDLLIMPEXP isNan(float v);
00067
00068
00069
00070 bool MRPTDLLIMPEXP isNan(double v);
00071
00072
00073
00074 bool MRPTDLLIMPEXP isFinite(float v);
00075
00076
00077
00078 bool MRPTDLLIMPEXP isFinite(double v);
00079
00080
00081
00082 template <class T>
00083 size_t countNonZero(const std::vector<T> &a)
00084 {
00085 typename std::vector<T>::const_iterator it_a;
00086 size_t count=0;
00087 for (it_a=a.begin(); it_a!=a.end(); it_a++) if (*it_a) count++;
00088 return count;
00089 }
00090
00091
00092
00093 template<class T>
00094 T maximum(const std::vector<T> &v, unsigned int *maxIndex = NULL)
00095 {
00096 typename std::vector<T>::const_iterator maxIt = std::max_element(v.begin(),v.end());
00097 if (maxIndex) *maxIndex = static_cast<unsigned int>( std::distance(v.begin(),maxIt) );
00098 return *maxIt;
00099 }
00100
00101
00102
00103 template<class T>
00104 T norm_inf(const std::vector<T> &v, unsigned int *maxIndex = NULL)
00105 {
00106 double M=0;
00107 int i,M_idx=-1;
00108 typename std::vector<T>::const_iterator it;
00109 for (i=0, it=v.begin(); it!=v.end();it++,i++)
00110 {
00111 double it_abs = fabs( static_cast<double>(*it));
00112 if (it_abs>M || M_idx==-1)
00113 {
00114 M = it_abs;
00115 M_idx = i;
00116 }
00117 }
00118 if (maxIndex) *maxIndex = M_idx;
00119 return static_cast<T>(M);
00120 }
00121
00122
00123
00124
00125 template<class T>
00126 T norm(const std::vector<T> &v)
00127 {
00128 T total=0;
00129 typename std::vector<T>::const_iterator it;
00130 for (it=v.begin(); it!=v.end();it++)
00131 total += square(*it);
00132 return ::sqrt(total);
00133 }
00134
00135
00136
00137
00138 template <class T>
00139 T minimum(const std::vector<T> &v, unsigned int *minIndex = NULL)
00140 {
00141 typename std::vector<T>::const_iterator minIt = std::min_element(v.begin(),v.end());
00142 if (minIndex) *minIndex = static_cast<unsigned int>( std::distance(v.begin(),minIt) );
00143 return *minIt;
00144 }
00145
00146
00147
00148
00149 template<class T>
00150 void minimum_maximum(const std::vector<T> &v, T& out_min, T& out_max, unsigned int *minIndex = NULL,unsigned int *maxIndex = NULL)
00151 {
00152 size_t N = v.size();
00153 if (N)
00154 {
00155 out_max = out_min = v[0];
00156 unsigned int min_idx=0,max_idx=0;
00157 for (size_t i=0;i<N;i++)
00158 {
00159 if (v[i]<out_min)
00160 {
00161 out_min=v[i];
00162 min_idx = i;
00163 }
00164 if (v[i]>out_max)
00165 {
00166 out_max=v[i];
00167 max_idx = i;
00168 }
00169 }
00170 if (minIndex) *minIndex = min_idx;
00171 if (maxIndex) *maxIndex = max_idx;
00172 }
00173 }
00174
00175
00176
00177
00178 template<class T>
00179 double mean(const std::vector<T> &v)
00180 {
00181 if (v.empty())
00182 return 0;
00183 else return static_cast<double>( std::accumulate(v.begin(),v.end(), static_cast<T>(0) ) ) / v.size();
00184 }
00185
00186
00187
00188
00189 template<class T>
00190 T sum(const std::vector<T> &v)
00191 {
00192 return std::accumulate(v.begin(),v.end(), static_cast<T>(0) );
00193 }
00194
00195
00196
00197 template<typename T,typename K>
00198 void linspace(T first,T last, size_t count, std::vector<K> &out_vector)
00199 {
00200 if (count<2)
00201 {
00202 out_vector.assign(1,last);
00203 return;
00204 }
00205 else
00206 {
00207 out_vector.resize(count);
00208 const T incr = (last-first)/T(count-1);
00209 T c = first;
00210 for (size_t i=0;i<count;i++,c+=incr)
00211 out_vector[i] = K(c);
00212 }
00213 }
00214
00215
00216
00217 template<class T>
00218 inline std::vector<T> linspace(T first,T last, size_t count)
00219 {
00220 std::vector<T> ret;
00221 mrpt::math::linspace(first,last,count,ret);
00222 return ret;
00223 }
00224
00225
00226 template<class T,T STEP>
00227 inline std::vector<T> sequence(T first,size_t length)
00228 {
00229 std::vector<T> ret(length);
00230 if (!length) return ret;
00231 size_t i=0;
00232 while (length--) { ret[i++]=first; first+=STEP; }
00233 return ret;
00234 }
00235
00236
00237 template<class T>
00238 std::vector<T> ones(size_t count)
00239 {
00240 return std::vector<T>(count,1);
00241 }
00242
00243
00244 template<class T>
00245 std::vector<T> zeros(size_t count)
00246 {
00247 return std::vector<T>(count,0);
00248 }
00249
00250
00251
00252
00253 template<class T>
00254 void normalize(const std::vector<T> &v, std::vector<T> &out_v)
00255 {
00256 T total=0;
00257 typename std::vector<T>::const_iterator it;
00258 for (it=v.begin(); it!=v.end();it++)
00259 total += square(*it);
00260 total = ::sqrt(total);
00261 if (total)
00262 {
00263 out_v.resize(v.size());
00264 typename std::vector<T>::iterator q;
00265 for (it=v.begin(),q=out_v.begin(); q!=out_v.end();it++,q++)
00266 *q = *it / total;
00267 }
00268 else out_v.assign(v.size(),0);
00269 }
00270
00271
00272
00273
00274 template<class T>
00275 std::vector<T> cumsum(const std::vector<T> &v)
00276 {
00277 T last = 0;
00278 std::vector<T> ret(v.size());
00279 typename std::vector<T>::const_iterator it;
00280 typename std::vector<T>::iterator it2;
00281 for (it = v.begin(),it2=ret.begin();it!=v.end();it++,it2++)
00282 last = (*it2) = last + (*it);
00283 return ret;
00284 }
00285
00286
00287
00288
00289 template<class T>
00290 void cumsum(const std::vector<T> &v, std::vector<T> &out_cumsum)
00291 {
00292 T last = 0;
00293 out_cumsum.resize(v.size());
00294 typename std::vector<T>::const_iterator it;
00295 typename std::vector<T>::iterator it2;
00296 for (it = v.begin(),it2=out_cumsum.begin();it!=v.end();it++,it2++)
00297 last = (*it2) = last + (*it);
00298 }
00299
00300
00301
00302
00303
00304
00305 template<class T>
00306 double stddev(const std::vector<T> &v, bool unbiased = true)
00307 {
00308 if (v.size()<2)
00309 return 0;
00310 else
00311 {
00312
00313 typename std::vector<T>::const_iterator it;
00314 double vector_std=0,vector_mean = 0;
00315 for (it = v.begin();it!=v.end();it++) vector_mean += (*it);
00316 vector_mean /= static_cast<double>(v.size());
00317
00318 for (it = v.begin();it!=v.end();it++) vector_std += square((*it)-vector_mean);
00319 vector_std = sqrt(vector_std / static_cast<double>(v.size() - (unbiased ? 1:0)) );
00320
00321 return vector_std;
00322 }
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332 template<class T>
00333 void meanAndCov(
00334 const std::vector<std::vector<T> > &v,
00335 vector_double &out_mean,
00336 CMatrixDouble &out_cov
00337 )
00338 {
00339 const size_t N = v.size();
00340 ASSERTMSG_(N>0,"The input vector contains no elements");
00341 const double N_inv = 1.0/N;
00342
00343 const size_t M = v[0].size();
00344 ASSERTMSG_(M>0,"The input vector contains rows of length 0");
00345
00346
00347 out_mean.assign(M,0);
00348 for (size_t i=0;i<N;i++)
00349 for (size_t j=0;j<M;j++)
00350 out_mean[j]+=v[i][j];
00351 out_mean*=N_inv;
00352
00353
00354
00355
00356 out_cov.zeros(M,M);
00357 for (size_t i=0;i<N;i++)
00358 {
00359 for (size_t j=0;j<M;j++)
00360 out_cov.get_unsafe(j,j)+=square(v[i][j]-out_mean[j]);
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(j,k)+=(v[i][j]-out_mean[j])*(v[i][k]-out_mean[k]);
00365 }
00366 for (size_t j=0;j<M;j++)
00367 for (size_t k=j+1;k<M;k++)
00368 out_cov.get_unsafe(k,j) = out_cov.get_unsafe(j,k);
00369 out_cov*=N_inv;
00370 }
00371
00372
00373
00374
00375
00376
00377
00378 template<class MAT_IN, class MAT_OUT>
00379 void meanAndCov(
00380 const MAT_IN &v,
00381 vector_double &out_mean,
00382 MAT_OUT &out_cov
00383 )
00384 {
00385 const size_t N = v.getRowCount();
00386 ASSERTMSG_(N>0,"The input matrix contains no elements");
00387 const double N_inv = 1.0/N;
00388
00389 const size_t M = v.getColCount();
00390 ASSERTMSG_(M>0,"The input matrix contains rows of length 0");
00391
00392
00393 out_mean.assign(M,0);
00394 for (size_t i=0;i<N;i++)
00395 for (size_t j=0;j<M;j++)
00396 out_mean[j]+=v.get_unsafe(i,j);
00397 out_mean*=N_inv;
00398
00399
00400
00401
00402 out_cov.zeros(M,M);
00403 for (size_t i=0;i<N;i++)
00404 {
00405 for (size_t j=0;j<M;j++)
00406 out_cov.get_unsafe(j,j)+=square(v.get_unsafe(i,j)-out_mean[j]);
00407
00408 for (size_t j=0;j<M;j++)
00409 for (size_t k=j+1;k<M;k++)
00410 out_cov.get_unsafe(j,k)+=(v.get_unsafe(i,j)-out_mean[j])*(v.get_unsafe(i,k)-out_mean[k]);
00411 }
00412 for (size_t j=0;j<M;j++)
00413 for (size_t k=j+1;k<M;k++)
00414 out_cov.get_unsafe(k,j) = out_cov.get_unsafe(j,k);
00415 out_cov*=N_inv;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424 template<class T>
00425 CMatrixDouble cov( const std::vector<std::vector<T> > &v )
00426 {
00427 vector_double m;
00428 CMatrixDouble C;
00429 meanAndCov(v,m,C);
00430 return C;
00431 }
00432
00433
00434
00435
00436
00437
00438 template<class T>
00439 CMatrixDouble cov( const CMatrixTemplate<T> &v )
00440 {
00441 vector_double m;
00442 CMatrixDouble C;
00443 meanAndCov(v,m,C);
00444 return C;
00445 }
00446
00447
00448
00449
00450
00451
00452 template<class T, size_t N, size_t M>
00453 CMatrixFixedNumeric<T,M,M> cov( const CMatrixFixedNumeric<T,N,M> &v )
00454 {
00455 vector_double m;
00456 CMatrixFixedNumeric<T,M,M> C;
00457 meanAndCov(v,m,C);
00458 return C;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468 template<class T>
00469 void meanAndStd(
00470 const std::vector<T> &v,
00471 double &out_mean,
00472 double &out_std,
00473 bool unbiased = true)
00474 {
00475 if (v.size()<2)
00476 {
00477 out_std = 0;
00478 if (v.size()==1)
00479 out_mean = v[0];
00480 }
00481 else
00482 {
00483
00484 typename std::vector<T>::const_iterator it;
00485 out_std=0,out_mean = 0;
00486 for (it = v.begin();it!=v.end();it++) out_mean += (*it);
00487 out_mean /= static_cast<double>(v.size());
00488
00489
00490 for (it = v.begin();it!=v.end();it++) out_std += square(static_cast<double>(*it)-out_mean);
00491 out_std = sqrt(out_std / static_cast<double>((v.size() - (unbiased ? 1:0)) ));
00492 }
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502 template<class T>
00503 void weightedHistogram(
00504 const std::vector<T> &values,
00505 const std::vector<T> &weights,
00506 float binWidth,
00507 std::vector<float> &out_binCenters,
00508 std::vector<float> &out_binValues )
00509 {
00510 MRPT_START;
00511
00512 ASSERT_( values.size() == weights.size() );
00513 ASSERT_( binWidth > 0 );
00514 T minBin = minimum( values );
00515 unsigned int nBins = static_cast<unsigned>(ceil((maximum( values )-minBin) / binWidth));
00516
00517
00518 out_binCenters.resize(nBins);
00519 out_binValues.clear(); out_binValues.resize(nBins,0);
00520 float halfBin = 0.5f*binWidth;;
00521 vector_float binBorders(nBins+1,minBin-halfBin);
00522 for (unsigned int i=0;i<nBins;i++)
00523 {
00524 binBorders[i+1] = binBorders[i]+binWidth;
00525 out_binCenters[i] = binBorders[i]+halfBin;
00526 }
00527
00528
00529 float totalSum = 0;
00530 for (typename std::vector<T>::const_iterator itVal = values.begin(), itW = weights.begin(); itVal!=values.end(); ++itVal, ++itW )
00531 {
00532 int idx = round(((*itVal)-minBin)/binWidth);
00533 if (idx>=nBins) idx=nBins-1;
00534 ASSERT_(idx>=0);
00535 out_binValues[idx] += *itW;
00536 totalSum+= *itW;
00537 }
00538
00539 if (totalSum)
00540 out_binValues = out_binValues / totalSum;
00541
00542
00543 MRPT_END;
00544 }
00545
00546
00547
00548
00549 uint64_t MRPTDLLIMPEXP factorial64(unsigned int n);
00550
00551
00552
00553 double MRPTDLLIMPEXP factorial(unsigned int n);
00554
00555
00556
00557
00558
00559
00560 template <class T>
00561 void wrapTo2PiInPlace(T &a)
00562 {
00563 bool was_neg = a<0;
00564 a = fmod(a, static_cast<T>(M_2PI) );
00565 if (was_neg) a+=static_cast<T>(M_2PI);
00566 }
00567
00568
00569
00570
00571
00572 template <class T>
00573 T wrapTo2Pi(T a)
00574 {
00575 wrapTo2PiInPlace(a);
00576 return a;
00577 }
00578
00579
00580
00581
00582
00583 template <class T>
00584 T wrapToPi(T a)
00585 {
00586 return wrapTo2Pi( a + static_cast<T>(M_PI) )-static_cast<T>(M_PI);
00587 }
00588
00589
00590
00591
00592
00593 template <class T>
00594 void wrapToPiInPlace(T &a)
00595 {
00596 a = wrapToPi(a);
00597 }
00598
00599
00600
00601 template <class T>
00602 T round2up(T val)
00603 {
00604 T n = 1;
00605 while (n < val)
00606 {
00607 n <<= 1;
00608 if (n<=1)
00609 THROW_EXCEPTION("Overflow!");
00610 }
00611 return n;
00612 }
00613
00614
00615
00616
00617 template <class T>
00618 T round_10power(T val, int power10)
00619 {
00620 long double F = ::pow((long double)10.0,-(long double)power10);
00621 long int t = round_long( val * F );
00622 return T(t/F);
00623 }
00624
00625
00626
00627
00628
00629
00630
00631 template<class T>
00632 void chol(const CMatrixTemplateNumeric<T> &in,CMatrixTemplateNumeric<T> &out)
00633 {
00634 if (in.getColCount() != in.getRowCount()) THROW_EXCEPTION("Cholesky factorization error, in matrix not square");
00635 size_t i,j,k;
00636 T sum;
00637 out.setSize(in.getRowCount(),in.getColCount());
00638 for (i=0;i<in.getRowCount();i++)
00639 {
00640 for (j=i;j<in.getColCount();j++)
00641 {
00642 sum=in(i,j);
00643 for (k=i-1;(k>=0)&(k<in.getColCount());k--)
00644 {
00645 sum -= out(k,i)*out(k,j);
00646 }
00647 if (i==j)
00648 {
00649 if (sum<0)
00650 {
00651 THROW_EXCEPTION("Cholesky factorization error, in matrix not defined-positive");
00652 }
00653 out(i,j)=sqrt(sum);
00654 }
00655 else
00656 {
00657 out(i,j)=sum/out(i,i);
00658 out(j,i)=0;
00659 }
00660 }
00661 }
00662 }
00663
00664
00665
00666
00667 template<class T>
00668 double correlate_matrix(const CMatrixTemplateNumeric<T> &a1, const CMatrixTemplateNumeric<T> &a2)
00669 {
00670 if ((a1.getColCount()!=a2.getColCount())|(a1.getRowCount()!=a2.getRowCount()))
00671 THROW_EXCEPTION("Correlation Error!, images with no same size");
00672
00673 int i,j;
00674 T x1,x2;
00675 T syy=0, sxy=0, sxx=0, m1=0, m2=0 ,n=a1.getRowCount()*a2.getColCount();
00676
00677
00678 for (i=0;i<a1.getRowCount();i++)
00679 {
00680 for (j=0;j<a1.getColCount();j++)
00681 {
00682 m1 += a1(i,j);
00683 m2 += a2(i,j);
00684 }
00685 }
00686 m1 /= n;
00687 m2 /= n;
00688
00689 for (i=0;i<a1.getRowCount();i++)
00690 {
00691 for (j=0;j<a1.getColCount();j++)
00692 {
00693 x1 = a1(i,j) - m1;
00694 x2 = a2(i,j) - m2;
00695 sxx += x1*x1;
00696 syy += x2*x2;
00697 sxy += x1*x2;
00698 }
00699 }
00700
00701 return sxy / sqrt(sxx * syy);
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 template<class T>
00718 void MRPTDLLIMPEXP qr_decomposition(
00719 CMatrixTemplateNumeric<T> &A,
00720 CMatrixTemplateNumeric<T> &R,
00721 CMatrixTemplateNumeric<T> &Q,
00722 CVectorTemplate<T> &c,
00723 int &sing);
00724
00725
00726
00727
00728
00729 template<class T>
00730 void MRPTDLLIMPEXP UpdateCholesky(
00731 CMatrixTemplateNumeric<T> &chol,
00732 CVectorTemplate<T> &r1Modification);
00733
00734
00735
00736
00737
00738
00739
00740 void MRPTDLLIMPEXP computeEigenValues2x2(
00741 const CMatrixFloat &in_matrix,
00742 float &min_eigenvalue,
00743 float &max_eigenvalue );
00744
00745
00746
00747
00748 template<class T>
00749 std::vector<T> Exp(const std::vector<T> &v)
00750 {
00751 std::vector<T> ret(v.size());
00752 typename std::vector<T>::const_iterator it;
00753 typename std::vector<T>::iterator it2;
00754 for (it = v.begin(),it2=ret.begin();it!=v.end();it++,it2++) *it2 = ::exp(*it);
00755 return ret;
00756 }
00757
00758
00759
00760
00761 template<class T>
00762 std::vector<T> Log(const std::vector<T> &v)
00763 {
00764 std::vector<T> ret(v.size());
00765 typename std::vector<T>::const_iterator it;
00766 typename std::vector<T>::iterator it2;
00767 for (it = v.begin(),it2=ret.begin();it!=v.end();it++,it2++) *it2 = ::log(*it);
00768 return ret;
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778 double MRPTDLLIMPEXP averageLogLikelihood( const vector_double &logLikelihoods );
00779
00780
00781
00782 double MRPTDLLIMPEXP averageWrap2Pi(const vector_double &angles );
00783
00784
00785
00786
00787
00788
00789
00790
00791 double MRPTDLLIMPEXP averageLogLikelihood(
00792 const vector_double &logWeights,
00793 const vector_double &logLikelihoods );
00794
00795
00796
00797
00798
00799
00800
00801
00802 std::string MRPTDLLIMPEXP MATLAB_plotCovariance2D(
00803 const CMatrixFloat &cov22,
00804 const CVectorFloat &mean,
00805 const float &stdCount,
00806 const std::string &style = std::string("b"),
00807 const size_t &nEllipsePoints = 30 );
00808
00809
00810
00811
00812
00813
00814
00815
00816 std::string MRPTDLLIMPEXP MATLAB_plotCovariance2D(
00817 const CMatrixDouble &cov22,
00818 const CVectorDouble &mean,
00819 const float &stdCount,
00820 const std::string &style = std::string("b"),
00821 const size_t &nEllipsePoints = 30 );
00822
00823
00824
00825
00826 void MRPTDLLIMPEXP homogeneousMatrixInverse(
00827 const CMatrixDouble &M,
00828 CMatrixDouble &out_inverse_M);
00829
00830
00831
00832 void MRPTDLLIMPEXP homogeneousMatrixInverse(
00833 const CMatrixDouble44 &M,
00834 CMatrixDouble44 &out_inverse_M);
00835
00836
00837
00838
00839 template<class T>
00840 size_t countCommonElements(
00841 const std::vector<T> &a,
00842 const std::vector<T> &b)
00843 {
00844 size_t ret=0;
00845 typename std::vector<T>::const_iterator it1;
00846 typename std::vector<T>::const_iterator it2;
00847 for (it1 = a.begin();it1!=a.end();it1++)
00848 for (it2 = b.begin();it2!=b.end();it2++)
00849 if ( (*it1) == (*it2) )
00850 ret++;
00851
00852 return ret;
00853 }
00854
00855
00856
00857
00858
00859
00860 template <typename T, class USERPARAM >
00861 void estimateJacobian(
00862 const std::vector<T> &x,
00863 void (*functor)(const std::vector<T> &x,const USERPARAM &y, std::vector<T> &out),
00864 const std::vector<T> &increments,
00865 const USERPARAM &userParam,
00866 CMatrixTemplateNumeric<T> &out_Jacobian )
00867 {
00868 MRPT_START;
00869 ASSERT_(x.size()>0 && increments.size() == x.size());
00870
00871 size_t m = 0;
00872 const size_t n = x.size();
00873
00874 for (size_t j=0;j<n;j++) { ASSERT_( increments[j]>0 ) }
00875
00876 std::vector<T> f_minus, f_plus;
00877 std::vector<T> x_mod(x);
00878
00879
00880 for (size_t j=0;j<n;j++)
00881 {
00882
00883 x_mod[j]+=increments[j];
00884 functor(x_mod,userParam, f_plus);
00885
00886 x_mod[j]=x[j]-increments[j];
00887 functor(x_mod,userParam, f_minus);
00888
00889 x_mod[j]=x[j];
00890 const T Ax_2_inv = T(0.5)/increments[j];
00891
00892
00893 if (j==0)
00894 {
00895 m = f_plus.size();
00896 out_Jacobian.setSize(m,n);
00897 }
00898
00899 for (size_t i=0;i<m;i++)
00900 {
00901 out_Jacobian(i,j) = Ax_2_inv* (f_plus[i]-f_minus[i]);
00902 }
00903
00904 }
00905
00906 MRPT_END;
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916 template <class T>
00917 T interpolate(
00918 const T &x,
00919 const std::vector<T> &ys,
00920 const T &x0,
00921 const T &x1 )
00922 {
00923 MRPT_START
00924 ASSERT_(x1>x0); ASSERT_(!ys.empty());
00925 const size_t N = ys.size();
00926 if (x<=x0) return ys[0];
00927 if (x>=x1) return ys[N-1];
00928 const T Ax = (x1-x0)/T(N);
00929 const size_t i = int( (x-x0)/Ax );
00930 if (i>=N-1) return ys[N-1];
00931 const T Ay = ys[i+1]-ys[i];
00932 return ys[i] + (x-(x0+i*Ax))*Ay/Ax;
00933 MRPT_END
00934 }
00935
00936
00937
00938
00939
00940 double MRPTDLLIMPEXP interpolate2points(const double x, const double x0, const double y0, const double x1, const double y1, bool wrap2pi = false);
00941
00942
00943
00944
00945
00946 double MRPTDLLIMPEXP spline(const double t, const std::vector<double> &x, const std::vector<double> &y, bool wrap2pi = false);
00947
00948
00949
00950
00951
00952
00953 double MRPTDLLIMPEXP leastSquareLinearFit(const double t, const std::vector<double> &x, const std::vector<double> &y, bool wrap2pi = false);
00954
00955
00956
00957
00958 void MRPTDLLIMPEXP leastSquareLinearFit(const std::vector<double> &ts, std::vector<double> &outs, const std::vector<double> &x, const std::vector<double> &y, bool wrap2pi = false);
00959
00960
00961
00962
00963
00964 template<class T>
00965 vector_double histogram(const std::vector<T> &v, double limit_min, double limit_max, size_t number_bins, bool do_normalization = false )
00966 {
00967 mrpt::math::CHistogram H( limit_min, limit_max, number_bins );
00968 vector_double ret(number_bins);
00969 size_t i;
00970 for (i=0;i<v.size();i++) H.add(static_cast<double>( v[i] ));
00971 for (i=0;i<number_bins;i++) ret[i] = do_normalization ? H.getBinRatio(i) : H.getBinCount(i);
00972 return ret;
00973 }
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983 template <typename T, typename At, size_t N>
00984 std::vector<T>& loadVector( std::vector<T> &v, At (&theArray)[N] )
00985 {
00986 MRPT_COMPILE_TIME_ASSERT(N!=0)
00987 v.resize(N);
00988 for (size_t i=0; i < N; i++)
00989 v[i] = static_cast<T>(theArray[i]);
00990 return v;
00991 }
00992
00993
00994 template <class T>
00995 std::vector<T> Abs(const std::vector<T> &a)
00996 {
00997 typename std::vector<T> res(a.size());
00998 for (size_t i=0;i<a.size();i++)
00999 res[i] = static_cast<T>( fabs( static_cast<double>( a[i] ) ) );
01000 return res;
01001 }
01002
01003
01004
01005
01006 void unwrap2PiSequence(vector_double &x);
01007
01008
01009
01010
01011
01012
01013
01014 template<class T>
01015 T MRPTDLLIMPEXP mahalanobisDistance2(
01016 const std::vector<T> &X,
01017 const std::vector<T> &MU,
01018 const CMatrixTemplateNumeric<T> &COV_inv );
01019
01020
01021
01022
01023 template<class T>
01024 T mahalanobisDistance(
01025 const std::vector<T> &X,
01026 const std::vector<T> &MU,
01027 const CMatrixTemplateNumeric<T> &COV_inv )
01028 {
01029 return std::sqrt( mahalanobisDistance2(X,MU,COV_inv) );
01030 }
01031
01032
01033
01034
01035
01036 template<class T>
01037 T MRPTDLLIMPEXP mahalanobisDistance2(
01038 const std::vector<T> &mean_diffs,
01039 const CMatrixTemplateNumeric<T> &COV1,
01040 const CMatrixTemplateNumeric<T> &COV2,
01041 const CMatrixTemplateNumeric<T> *CROSS_COV12=NULL
01042 );
01043
01044
01045
01046
01047
01048 template <typename T>
01049 T productIntegralTwoGaussians(
01050 const std::vector<T> &mean_diffs,
01051 const CMatrixTemplateNumeric<T> &COV1,
01052 const CMatrixTemplateNumeric<T> &COV2
01053 )
01054 {
01055 const size_t vector_dim = mean_diffs.size();
01056 ASSERT_(vector_dim>=1)
01057
01058 CMatrixTemplateNumeric<T> C = COV1;
01059 C+= COV2;
01060 const T cov_det = C.det();
01061 CMatrixTemplateNumeric<T> C_inv;
01062 C.inv_fast(C_inv);
01063
01064 return std::pow( M_2PI, -0.5*vector_dim ) * (1.0/std::sqrt( cov_det ))
01065 * exp( -0.5 * mrpt::math::multiply_HCHt_scalar(mean_diffs,C_inv) );
01066 }
01067
01068
01069
01070
01071 template <typename T, size_t DIM>
01072 T productIntegralTwoGaussians(
01073 const std::vector<T> &mean_diffs,
01074 const CMatrixFixedNumeric<T,DIM,DIM> &COV1,
01075 const CMatrixFixedNumeric<T,DIM,DIM> &COV2
01076 )
01077 {
01078 ASSERT_(mean_diffs.size()==DIM);
01079
01080 CMatrixFixedNumeric<T,DIM,DIM> C = COV1;
01081 C+= COV2;
01082 const T cov_det = C.det();
01083 CMatrixFixedNumeric<T,DIM,DIM> C_inv(false,false);
01084 C.inv_fast(C_inv);
01085
01086 return std::pow( M_2PI, -0.5*DIM ) * (1.0/std::sqrt( cov_det ))
01087 * exp( -0.5 * mrpt::math::multiply_HCHt_scalar(mean_diffs,C_inv) );
01088 }
01089
01090
01091
01092
01093 template <typename T>
01094 void productIntegralAndMahalanobisTwoGaussians(
01095 const std::vector<T> &mean_diffs,
01096 const CMatrixTemplateNumeric<T> &COV1,
01097 const CMatrixTemplateNumeric<T> &COV2,
01098 T &maha_out,
01099 T &intprod_out,
01100 const CMatrixTemplateNumeric<T> *CROSS_COV12=NULL
01101 )
01102 {
01103 const size_t vector_dim = mean_diffs.size();
01104 ASSERT_(vector_dim>=1)
01105
01106 CMatrixTemplateNumeric<T> C = COV1;
01107 C+= COV2;
01108 if (CROSS_COV12)
01109 C.substract_An(*CROSS_COV12,2);
01110 const T cov_det = C.det();
01111 CMatrixTemplateNumeric<T> C_inv;
01112 C.inv_fast(C_inv);
01113
01114 maha_out = mrpt::math::multiply_HCHt_scalar(mean_diffs,C_inv);
01115 intprod_out = std::pow( M_2PI, -0.5*vector_dim ) * (1.0/std::sqrt( cov_det ))*exp(-0.5*maha_out);
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125 template<typename T,size_t N,typename U>
01126 void covariancesAndMean(const std::vector<T> &elements,CMatrixTemplateNumeric<U> &covariances,U (&means)[N]) {
01127 size_t nElms=elements.size();
01128 for (size_t i=0;i<N;i++) {
01129 means[i]=0;
01130 for (size_t j=0;j<nElms;j++) means[i]+=elements[j][i];
01131 means[i]/=nElms;
01132 }
01133 covariances.resize(N,N);
01134 for (size_t i=0;i<N;i++) for (size_t j=0;j<=i;j++) {
01135 U elem=0;
01136 for (size_t k=0;k<nElms;k++) elem+=(elements[k][i]-means[i])*(elements[k][j]-means[j]);
01137 elem/=nElms;
01138 covariances.get_unsafe(i,j) = elem;
01139 if (i!=j) covariances.get_unsafe(j,i)=elem;
01140 }
01141 }
01142
01143
01144
01145
01146
01147 template<typename T,size_t N,typename U>
01148 void covariancesAndMean(const std::vector<T> &elements,CMatrixFixedNumeric<U,N,N> &covariances,U (&means)[N]) {
01149 size_t nElms=elements.size();
01150 for (size_t i=0;i<N;i++) {
01151 means[i]=0;
01152 for (size_t j=0;j<nElms;j++) means[i]+=elements[j][i];
01153 means[i]/=nElms;
01154 }
01155 for (size_t i=0;i<N;i++) for (size_t j=0;j<=i;j++) {
01156 U elem=0;
01157 for (size_t k=0;k<nElms;k++) elem+=(elements[k][i]-means[i])*(elements[k][j]-means[j]);
01158 elem/=nElms;
01159 covariances.get_unsafe(i,j) = elem;
01160 if (i!=j) covariances.get_unsafe(j,i)=elem;
01161 }
01162 }
01163
01164
01165
01166
01167
01168 template<typename T,size_t N,typename U>
01169 void covariancesAndMean(const std::vector<T> &elements,CMatrixFixedNumeric<U,N,N> &covariances,std::vector<U> &means ) {
01170 means.resize(N);
01171 size_t nElms=elements.size();
01172 for (size_t i=0;i<N;i++) {
01173 means[i]=0;
01174 for (size_t j=0;j<nElms;j++) means[i]+=elements[j][i];
01175 means[i]/=nElms;
01176 }
01177 for (size_t i=0;i<N;i++) for (size_t j=0;j<=i;j++) {
01178 U elem=0;
01179 for (size_t k=0;k<nElms;k++) elem+=(elements[k][i]-means[i])*(elements[k][j]-means[j]);
01180 elem/=nElms;
01181 covariances.get_unsafe(i,j) = elem;
01182 if (i!=j) covariances.get_unsafe(j,i)=elem;
01183 }
01184 }
01185
01186
01187 template<size_t N,class T,class U,class V>
01188 inline T dotProduct(const U &v1,const V &v2) {
01189 T res=0;
01190 for (size_t i=0;i<N;i++) res+=v1[i]*v2[i];
01191 return res;
01192 }
01193
01194
01195 template<size_t N,class T,class U>
01196 inline T squareNorm(const U &v) {
01197 T res=0;
01198 for (size_t i=0;i<N;i++) res+=v[i]*v[i];
01199 return res;
01200 }
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 template <size_t N, typename T>
01212 std::vector<T> make_vector(const T val1, ...)
01213 {
01214 MRPT_COMPILE_TIME_ASSERT( N>0 )
01215 std::vector<T> ret;
01216 ret.reserve(N);
01217
01218 ret.push_back(val1);
01219
01220 va_list args;
01221 va_start(args,val1);
01222 for (size_t i=0;i<N-1;i++)
01223 ret.push_back( va_arg(args,T) );
01224
01225 va_end(args);
01226 return ret;
01227 }
01228
01229 }
01230
01231 }
01232
01233 #endif