00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef UMATH_H
00021 #define UMATH_H
00022
00027 #include "rtabmap/utilite/UtiLiteExp.h"
00028
00029 #include <cmath>
00030 #include <list>
00031 #include <vector>
00032
00033 #if _MSC_VER
00034 #undef min
00035 #undef max
00036 #endif
00037
00041 template<class T>
00042 inline bool uIsNan(const T & value)
00043 {
00044 #ifdef __APPLE__
00045 return std::isnan(value);
00046 #elif _MSC_VER
00047 return _isnan(value) != 0;
00048 #else
00049 return isnan(value);
00050 #endif
00051 }
00052
00056 template<class T>
00057 inline bool uIsFinite(const T & value)
00058 {
00059 #if _MSC_VER
00060 return _finite(value) != 0;
00061 #else
00062 return std::isfinite(value);
00063 #endif
00064 }
00065
00073 template<class T>
00074 inline T uMax(const T * v, unsigned int size, unsigned int & index)
00075 {
00076 T max = 0;
00077 index = 0;
00078 if(!v || size == 0)
00079 {
00080 return max;
00081 }
00082 max = v[0];
00083 for(unsigned int i=1; i<size; ++i)
00084 {
00085 if(uIsNan(max) || (max < v[i] && !uIsNan(v[i])))
00086 {
00087 max = v[i];
00088 index = i;
00089 }
00090 }
00091
00092 return max;
00093 }
00094
00101 template<class T>
00102 inline T uMax(const std::vector<T> & v, unsigned int & index)
00103 {
00104 return uMax(v.data(), v->size(), index);
00105 }
00106
00113 template<class T>
00114 inline T uMax(const T * v, unsigned int size)
00115 {
00116 unsigned int index;
00117 return uMax(v, size, index);
00118 }
00119
00125 template<class T>
00126 inline T uMax(const std::vector<T> & v)
00127 {
00128 return uMax(v.data(), v.size());
00129 }
00130
00138 template<class T>
00139 inline T uMin(const T * v, unsigned int size, unsigned int & index)
00140 {
00141 T min = 0;
00142 index = 0;
00143 if(!v || size == 0)
00144 {
00145 return min;
00146 }
00147 min = v[0];
00148 for(unsigned int i=1; i<size; ++i)
00149 {
00150 if(uIsNan(min) || (min > v[i] && !uIsNan(v[i])))
00151 {
00152 min = v[i];
00153 index = i;
00154 }
00155 }
00156
00157 return min;
00158 }
00159
00166 template<class T>
00167 inline T uMin(const std::vector<T> & v, unsigned int & index)
00168 {
00169 return uMin(v.data(), v.size(), index);
00170 }
00171
00178 template<class T>
00179 inline T uMin(const T * v, unsigned int size)
00180 {
00181 unsigned int index;
00182 return uMin(v, size, index);
00183 }
00184
00190 template<class T>
00191 inline T uMin(const std::vector<T> & v)
00192 {
00193 return uMin(v.data(), v.size());
00194 }
00195
00205 template<class T>
00206 inline void uMinMax(const T * v, unsigned int size, T & min, T & max, unsigned int & indexMin, unsigned int & indexMax)
00207 {
00208 min = 0;
00209 max = 0;
00210 indexMin = 0;
00211 indexMax = 0;
00212 if(!v || size == 0)
00213 {
00214 return;
00215 }
00216 min = v[0];
00217 max = v[0];
00218
00219 for(unsigned int i=1; i<size; ++i)
00220 {
00221 if(uIsNan(min) || (min > v[i] && !uIsNan(v[i])))
00222 {
00223 min = v[i];
00224 indexMin = i;
00225 }
00226
00227 if(uIsNan(max) || (max < v[i] && !uIsNan(v[i])))
00228 {
00229 max = v[i];
00230 indexMax = i;
00231 }
00232 }
00233 }
00234
00243 template<class T>
00244 inline void uMinMax(const std::vector<T> & v, T & min, T & max, unsigned int & indexMin, unsigned int & indexMax)
00245 {
00246 uMinMax(v.data(), v.size(), min, max, indexMin, indexMax);
00247 }
00248
00256 template<class T>
00257 inline void uMinMax(const T * v, unsigned int size, T & min, T & max)
00258 {
00259 unsigned int indexMin;
00260 unsigned int indexMax;
00261 uMinMax(v, size, min, max, indexMin, indexMax);
00262 }
00263
00270 template<class T>
00271 inline void uMinMax(const std::vector<T> & v, T & min, T & max)
00272 {
00273 uMinMax(v.data(), v.size(), min, max);
00274 }
00275
00281 template<class T>
00282 inline int uSign(const T & v)
00283 {
00284 if(v < 0)
00285 {
00286 return -1;
00287 }
00288 else
00289 {
00290 return 1;
00291 }
00292 }
00293
00299 template<class T>
00300 inline T uSum(const std::list<T> & list)
00301 {
00302 T sum = 0;
00303 for(typename std::list<T>::const_iterator i=list.begin(); i!=list.end(); ++i)
00304 {
00305 sum += *i;
00306 }
00307 return sum;
00308 }
00309
00316 template<class T>
00317 inline T uSum(const T * v, unsigned int size)
00318 {
00319 T sum = 0;
00320 if(v && size)
00321 {
00322 for(unsigned int i=0; i<size; ++i)
00323 {
00324 sum += v[i];
00325 }
00326 }
00327 return sum;
00328 }
00329
00335 template<class T>
00336 inline T uSum(const std::vector<T> & v)
00337 {
00338 return uSum(v.data(), (int)v.size());
00339 }
00340
00348 template<class T>
00349 inline T uSumSquared(const T * v, unsigned int size, T subtract = T())
00350 {
00351 T sum = 0;
00352 if(v && size)
00353 {
00354 for(unsigned int i=0; i<size; ++i)
00355 {
00356 sum += (v[i]-subtract)*(v[i]-subtract);
00357 }
00358 }
00359 return sum;
00360 }
00361
00368 template<class T>
00369 inline T uSumSquared(const std::vector<T> & v, T subtract = T())
00370 {
00371 return uSumSquared(v.data(), v.size(), subtract);
00372 }
00373
00380 template<class T>
00381 inline T uMean(const T * v, unsigned int size)
00382 {
00383 T buf = 0;
00384 if(v && size)
00385 {
00386 for(unsigned int i=0; i<size; ++i)
00387 {
00388 buf += v[i];
00389 }
00390 buf /= size;
00391 }
00392 return buf;
00393 }
00394
00400 template<class T>
00401 inline T uMean(const std::list<T> & list)
00402 {
00403 T m = 0;
00404 if(list.size())
00405 {
00406 for(typename std::list<T>::const_iterator i=list.begin(); i!=list.end(); ++i)
00407 {
00408 m += *i;
00409 }
00410 m /= list.size();
00411 }
00412 return m;
00413 }
00414
00420 template<class T>
00421 inline T uMean(const std::vector<T> & v)
00422 {
00423 return uMean(v.data(), v.size());
00424 }
00425
00434 template<class T>
00435 inline T uMeanSquaredError(const T * x, unsigned int sizeX, const T * y, unsigned int sizeY)
00436 {
00437 T sum = 0;
00438 if(x && y && sizeX == sizeY)
00439 {
00440 for(unsigned int i=0; i<sizeX; ++i)
00441 {
00442 T diff = x[i]-y[i];
00443 sum += diff*diff;
00444 }
00445 return sum/(T)sizeX;
00446 }
00447 return (T)-1;
00448 }
00449
00456 template<class T>
00457 inline T uMeanSquaredError(const std::vector<T> & x, const std::vector<T> & y)
00458 {
00459 return uMeanSquaredError(x.data(), x.size(), y.data(), y.size());
00460 }
00461
00470 template<class T>
00471 inline T uVariance(const T * v, unsigned int size, T meanV)
00472 {
00473 T buf = 0;
00474 if(v && size>1)
00475 {
00476 float sum = 0;
00477 for(unsigned int i=0; i<size; ++i)
00478 {
00479 sum += (v[i]-meanV)*(v[i]-meanV);
00480 }
00481 buf = sum/(size-1);
00482 }
00483 return buf;
00484 }
00485
00493 template<class T>
00494 inline T uVariance(const std::list<T> & list, const T & m)
00495 {
00496 T buf = 0;
00497 if(list.size()>1)
00498 {
00499 float sum = 0;
00500 for(typename std::list<T>::const_iterator i=list.begin(); i!=list.end(); ++i)
00501 {
00502 sum += (*i-m)*(*i-m);
00503 }
00504 buf = sum/(list.size()-1);
00505 }
00506 return buf;
00507 }
00508
00515 template<class T>
00516 inline T uVariance(const T * v, unsigned int size)
00517 {
00518 T m = uMean(v, size);
00519 return uVariance(v, size, m);
00520 }
00521
00529 template<class T>
00530 inline T uVariance(const std::vector<T> & v, const T & m)
00531 {
00532 return uVariance(v.data(), v.size(), m);
00533 }
00534
00539 template<class T>
00540 inline T uNormSquared(const std::vector<T> & v)
00541 {
00542 float sum = 0.0f;
00543 for(unsigned int i=0; i<v.size(); ++i)
00544 {
00545 sum += v[i]*v[i];
00546 }
00547 return sum;
00548 }
00549
00554 template<class T>
00555 inline T uNorm(const std::vector<T> & v)
00556 {
00557 return std::sqrt(uNormSquared(v));
00558 }
00559
00564 template<class T>
00565 inline T uNormSquared(const T & x1, const T & x2)
00566 {
00567 return x1*x1 + x2*x2;
00568 }
00569
00574 template<class T>
00575 inline T uNorm(const T & x1, const T & x2)
00576 {
00577 return std::sqrt(uNormSquared(x1, x2));
00578 }
00579
00584 template<class T>
00585 inline T uNormSquared(const T & x1, const T & x2, const T & x3)
00586 {
00587 return x1*x1 + x2*x2 + x3*x3;
00588 }
00589
00594 template<class T>
00595 inline T uNorm(const T & x1, const T & x2, const T & x3)
00596 {
00597 return std::sqrt(uNormSquared(x1, x2, x3));
00598 }
00599
00604 template<class T>
00605 inline std::vector<T> uNormalize(const std::vector<T> & v)
00606 {
00607 float norm = uNorm(v);
00608 if(norm == 0)
00609 {
00610 return v;
00611 }
00612 else
00613 {
00614 std::vector<T> r(v.size());
00615 for(unsigned int i=0; i<v.size(); ++i)
00616 {
00617 r[i] = v[i]/norm;
00618 }
00619 return r;
00620 }
00621 }
00622
00626 template<class T>
00627 inline std::list<unsigned int> uLocalMaxima(const T * v, unsigned int size)
00628 {
00629 std::list<unsigned int> maxima;
00630 if(size)
00631 {
00632 for(unsigned int i=0; i<size; ++i)
00633 {
00634 if(i == 0)
00635 {
00636
00637 if((i+1 < size && v[i] > v[i+1]) ||
00638 i+1 >= size)
00639 {
00640 maxima.push_back(i);
00641 }
00642 }
00643 else if(i == size - 1)
00644 {
00645
00646 if((i >= 1 && v[i] > v[i-1]) ||
00647 i == 0)
00648 {
00649 maxima.push_back(i);
00650 }
00651 }
00652 else
00653 {
00654
00655 if(v[i] > v[i-1] && v[i] > v[i+1])
00656 {
00657 maxima.push_back(i);
00658 }
00659 }
00660 }
00661 }
00662 return maxima;
00663 }
00664
00668 template<class T>
00669 inline std::list<unsigned int> uLocalMaxima(const std::vector<T> & v)
00670 {
00671 return uLocalMaxima(v.data(), v.size());
00672 }
00673
00678 enum UXMatchMethod{UXCorrRaw, UXCorrBiased, UXCorrUnbiased, UXCorrCoeff, UXCovRaw, UXCovBiased, UXCovUnbiased, UXCovCoeff};
00679
00689 template<class T>
00690 inline std::vector<T> uXMatch(const T * vA, const T * vB, unsigned int sizeA, unsigned int sizeB, UXMatchMethod method)
00691 {
00692 if(!vA || !vB || sizeA == 0 || sizeB == 0)
00693 {
00694 return std::vector<T>();
00695 }
00696
00697 std::vector<T> result(sizeA + sizeB - 1);
00698
00699 T meanA = 0;
00700 T meanB = 0;
00701 if(method > UXCorrCoeff)
00702 {
00703 meanA = uMean(vA, sizeA);
00704 meanB = uMean(vB, sizeB);
00705 }
00706
00707 T den = 1;
00708 if(method == UXCorrCoeff || method == UXCovCoeff)
00709 {
00710 den = std::sqrt(uSumSquared(vA, sizeA, meanA) * uSumSquared(vB, sizeB, meanB));
00711 }
00712 else if(method == UXCorrBiased || method == UXCovBiased)
00713 {
00714 den = (T)std::max(sizeA, sizeB);
00715 }
00716
00717 if(sizeA == sizeB)
00718 {
00719 T resultA;
00720 T resultB;
00721
00722 int posA;
00723 int posB;
00724 unsigned int j;
00725
00726
00727 for(unsigned int i=0; i<sizeA; ++i)
00728 {
00729 if(method == UXCorrUnbiased || method == UXCovUnbiased)
00730 {
00731 den = 0;
00732 }
00733
00734 posA = sizeA - i - 1;
00735 posB = sizeB - i - 1;
00736 resultA = 0;
00737 resultB = 0;
00738 for(j=0; (j + posB) < sizeB && (j + posA) < sizeA; ++j)
00739 {
00740 resultA += (vA[j] - meanA) * (vB[j + posB] - meanB);
00741 resultB += (vA[j + posA] - meanA) * (vB[j] - meanB);
00742 if(method == UXCorrUnbiased || method == UXCovUnbiased)
00743 {
00744 ++den;
00745 }
00746 }
00747
00748 result[i] = resultA / den;
00749 result[result.size()-1 -i] = resultB / den;
00750 }
00751 }
00752 else
00753 {
00754 for(unsigned int i=0; i<result.size(); ++i)
00755 {
00756 if(method == UXCorrUnbiased || method == UXCovUnbiased)
00757 {
00758 den = 0;
00759 }
00760
00761 int posB = sizeB - i - 1;
00762 T r = 0;
00763 if(posB >= 0)
00764 {
00765 for(unsigned int j=0; (j + posB) < sizeB && j < sizeA; ++j)
00766 {
00767 r += (vA[j] - meanA) * (vB[j + posB] - meanB);
00768 if(method == UXCorrUnbiased || method == UXCovUnbiased)
00769 {
00770 ++den;
00771 }
00772 }
00773 }
00774 else
00775 {
00776 int posA = posB*-1;
00777 for(unsigned int i=0; (i+posA) < sizeA && i < sizeB; ++i)
00778 {
00779 r += (vA[i+posA] - meanA) * (vB[i] - meanB);
00780 if(method == UXCorrUnbiased || method == UXCovUnbiased)
00781 {
00782 ++den;
00783 }
00784 }
00785 }
00786
00787 result[i] = r / den;
00788 }
00789 }
00790
00791 return result;
00792 }
00793
00801 template<class T>
00802 inline std::vector<T> uXMatch(const std::vector<T> & vA, const std::vector<T> & vB, UXMatchMethod method)
00803 {
00804 return uXMatch(vA.data(), vB.data(), vA.size(), vB.size(), method);
00805 }
00806
00817 template<class T>
00818 inline T uXMatch(const T * vA, const T * vB, unsigned int sizeA, unsigned int sizeB, unsigned int index, UXMatchMethod method)
00819 {
00820 T result = 0;
00821 if(!vA || !vB || sizeA == 0 || sizeB == 0)
00822 {
00823 return result;
00824 }
00825
00826 T meanA = 0;
00827 T meanB = 0;
00828 if(method > UXCorrCoeff)
00829 {
00830 meanA = uMean(vA, sizeA);
00831 meanB = uMean(vB, sizeB);
00832 }
00833 unsigned int size = sizeA + sizeB - 1;
00834
00835 T den = 1;
00836 if(method == UXCorrCoeff || method == UXCovCoeff)
00837 {
00838 den = std::sqrt(uSumSquared(vA, sizeA, meanA) * uSumSquared(vB, sizeB, meanB));
00839 }
00840 else if(method == UXCorrBiased || method == UXCovBiased)
00841 {
00842 den = (T)std::max(sizeA, sizeB);
00843 }
00844 else if(method == UXCorrUnbiased || method == UXCovUnbiased)
00845 {
00846 den = 0;
00847 }
00848
00849 if(index < size)
00850 {
00851 int posB = sizeB - index - 1;
00852 unsigned int i;
00853 if(posB >= 0)
00854 {
00855 for(i=0; (i + posB) < sizeB && i < sizeA; ++i)
00856 {
00857 result += (vA[i] - meanA) * (vB[i + posB] - meanB);
00858 if(method == UXCorrUnbiased || method == UXCovUnbiased)
00859 {
00860 ++den;
00861 }
00862 }
00863 }
00864 else
00865 {
00866 int posA = posB*-1;
00867 for(i=0; (i+posA) < sizeA && i < sizeB; ++i)
00868 {
00869 result += (vA[i+posA] - meanA) * (vB[i] - meanB);
00870 if(method == UXCorrUnbiased || method == UXCovUnbiased)
00871 {
00872 ++den;
00873 }
00874 }
00875 }
00876 }
00877 return result / den;
00878 }
00879
00890 template<class T>
00891 inline T uXMatch(const std::vector<T> & vA, const std::vector<T> & vB, unsigned int index, UXMatchMethod method)
00892 {
00893 return uXMatch(vA.data(), vB.data(), vA.size(), vB.size(), index, method);
00894 }
00895
00901 inline std::vector<float> uHamming(unsigned int L)
00902 {
00903 std::vector<float> w(L);
00904 unsigned int N = L-1;
00905 float pi = 3.14159265f;
00906 for(unsigned int n=0; n<N; ++n)
00907 {
00908 w[n] = 0.54f-0.46f*std::cos(2.0f*pi*float(n)/float(N));
00909 }
00910 return w;
00911 }
00912
00913 template <typename T>
00914 bool uIsInBounds(const T& value, const T& low, const T& high)
00915 {
00916 return !(value < low) && !(value >= high);
00917 }
00918
00919 #endif // UMATH_H