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
00029
00030
00031
00032
00033 #ifndef _LTI_MATH_H_
00034 #define _LTI_MATH_H_
00035
00036 #include "ltiObject.h"
00037 #include "ltiTypes.h"
00038 #include "ltiSinCos.h"
00039 #include <cmath>
00040 #include <limits>
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #undef _LTI_MATH_H_STYLE
00053 #if (defined _LTI_MSC_6) || (defined _LTI_GNUC_2 )
00054 #define _LTI_MATH_H_STYLE 1
00055 #endif
00056
00057
00058
00059
00060 #if defined(_LTI_GNUC_3) && !defined(_LTI_ICC)
00061 using std::isnan;
00062 using std::isinf;
00063 using std::isfinite;
00064 #endif
00065
00066 #ifndef _LTI_MATH_H_STYLE
00067 #include <algorithm>
00068 #endif
00069
00070 # ifdef min
00071 # undef min
00072 # endif
00073
00074 # ifdef max
00075 # undef max
00076 # endif
00077
00078 namespace lti {
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 template <class T>
00098 inline bool closeTo(const T& a, const T& b,
00099 const T epsilon=std::numeric_limits<T>::epsilon()) {
00100 const T diff=a-b;
00101 return ((diff<=epsilon) && (diff>=-epsilon));
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 template <class T>
00122 inline bool closeToZero(const T& a,
00123 const T epsilon=std::numeric_limits<T>::epsilon()) {
00124 return ((a<=epsilon) && (a>=-epsilon));
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 template<class T>
00134 inline T round(T x) {
00135 if( x >= static_cast<T>(0) ) {
00136 return static_cast<T>(static_cast<long>(x + 0.5));
00137 }
00138
00139 return static_cast<T>(static_cast<long>(x - 0.5));
00140 }
00141
00142
00143
00144
00145
00146
00147 template<class T>
00148 inline int iround(T x) {
00149 if( x >= 0 ) {
00150 return static_cast<int>(x + 0.5);
00151 }
00152
00153 return static_cast<int>(x - 0.5);
00154 }
00155
00156
00157
00158
00159
00160
00161 template<class T>
00162 inline long lround(T x) {
00163 if( x >= 0 ) {
00164 return static_cast<long>(x + 0.5);
00165 }
00166
00167 return static_cast<long>(x - 0.5);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 template<class T,class F>
00191 inline void condRoundCastTo(const F from,T& to) {
00192 to=static_cast<T>(from);
00193 }
00194
00195
00196 template<>
00197 inline void condRoundCastTo<int,float>(const float x,int& dest) {
00198 dest=iround(x);
00199 }
00200
00201 template<>
00202 inline void condRoundCastTo<int,double>(const double x,int& dest) {
00203 dest=iround(x);
00204 }
00205
00206 template<>
00207 inline void condRoundCastTo<ubyte,float>(const float x,ubyte& dest) {
00208 dest=static_cast<ubyte>(iround(x));
00209 }
00210
00211 template<>
00212 inline void condRoundCastTo<ubyte,double>(const double x,ubyte& dest) {
00213 dest=static_cast<ubyte>(iround(x));
00214 }
00215
00216 template<>
00217 inline void condRoundCastTo<short,float>(const float x,short& dest) {
00218 dest=static_cast<short>(iround(x));
00219 }
00220
00221 template<>
00222 inline void condRoundCastTo<short,double>(const double x,short& dest) {
00223 dest=static_cast<short>(iround(x));
00224 }
00225
00226 template<>
00227 inline void condRoundCastTo<unsigned int,float>(const float x,
00228 unsigned int& dest) {
00229 dest=static_cast<unsigned int>(iround(x));
00230 }
00231
00232 template<>
00233 inline void condRoundCastTo<unsigned int,double>(const double x,
00234 unsigned int& dest) {
00235 dest=static_cast<unsigned int>(iround(x));
00236 }
00237
00238 template<>
00239 inline void condRoundCastTo<byte,float>(const float x,byte& dest) {
00240 dest=static_cast<byte>(iround(x));
00241 }
00242
00243 template<>
00244 inline void condRoundCastTo<byte,double>(const double x,byte& dest) {
00245 dest=static_cast<byte>(iround(x));
00246 }
00247
00248 template<>
00249 inline void condRoundCastTo<unsigned short,float>(const float x,
00250 unsigned short& dest) {
00251 dest=static_cast<unsigned short>(iround(x));
00252 }
00253
00254 template<>
00255 inline void condRoundCastTo<unsigned short,double>(const double x,
00256 unsigned short& dest) {
00257 dest=static_cast<unsigned short>(iround(x));
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 template<class T>
00274 inline void exchange(T& a,T& b) {
00275 T tmp(a);
00276 a=b;
00277 b=tmp;
00278 }
00279
00280
00281
00282
00283
00284
00285 template<class T>
00286 inline T min(const T x, const T y) {
00287 return ((x<y) ? x : y);
00288 };
00289
00290
00291
00292
00293
00294
00295 template<class T>
00296 inline T max(const T x, const T y) {
00297 return ((x<y) ? y : x);
00298 };
00299
00300
00301
00302
00303
00304
00305 template<class T>
00306 inline T min(const T x, const T y, const T z) {
00307 return (min(x,min(y,z)));
00308 };
00309
00310
00311
00312
00313
00314
00315 template<class T>
00316 inline T max(const T x, const T y, const T z) {
00317 return (max(x,max(y,z)));
00318 };
00319
00320
00321
00322
00323 template<class T>
00324 inline void minmax(const T x, const T y, T& theMin, T& theMax) {
00325 if (x<y) {
00326 theMin=x;
00327 theMax=y;
00328 } else {
00329 theMin=y;
00330 theMax=x;
00331 }
00332 }
00333
00334
00335
00336
00337
00338 template<class T>
00339 inline void minmax(T& theMin, T& theMax) {
00340 if (theMax < theMin) {
00341 exchange(theMin,theMax);
00342 }
00343 }
00344
00345
00346
00347
00348
00349
00350 const double Pi = 3.1415926535897932;
00351
00352
00353
00354
00355
00356
00357 const double NaN = log(-1.0);
00358
00359
00360
00361
00362
00363
00364 const double Inf = tan(Pi/2.0);
00365
00366
00367
00368
00369
00370
00371 template<class T> T lnGamma(const T& x);
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 double factorial(const int x);
00382
00383
00384
00385
00386
00387
00388 double lnFactorial(const int x);
00389
00390
00391
00392
00393
00394
00395
00396
00397 double binomial(const int n,const int k);
00398
00399
00400
00401
00402 inline double degToRad(const double& deg) {
00403 static const double factor = Pi/180.0;
00404 return deg*factor;
00405 }
00406
00407
00408
00409
00410 inline float degToRad(const float& deg) {
00411 static const float factor = static_cast<float>(Pi/180.0);
00412 return deg*factor;
00413 }
00414
00415
00416
00417
00418 inline double degToRad(const int& deg) {
00419 static const double factor = Pi/180.0;
00420 return deg*factor;
00421 }
00422
00423
00424
00425
00426
00427 inline double radToDeg(const double& rad) {
00428 static const double factor = 180.0/Pi;
00429 return rad*factor;
00430 }
00431
00432
00433
00434
00435 inline float radToDeg(const float& rad) {
00436 static const float factor = static_cast<float>(180.0/Pi);
00437 return rad*factor;
00438 }
00439
00440
00441
00442
00443
00444
00445 inline byte abs(byte x) {
00446 return ((x>=0) ? x : -x);
00447 }
00448
00449
00450
00451
00452
00453
00454 inline int abs(int x) {
00455 return ((x>=0) ? x : -x);
00456 }
00457
00458
00459
00460
00461
00462
00463 inline float abs(float x) {
00464 #ifdef _LTI_MATH_H_STYLE
00465 return ((x>=0) ? x : -x);
00466 #else
00467 return std::abs(x);
00468 #endif
00469 }
00470
00471
00472
00473
00474
00475
00476 inline double abs(const double& x) {
00477 #ifdef _LTI_MATH_H_STYLE
00478 return ((x>=0) ? x : -x);
00479 #else
00480 return std::abs(x);
00481 #endif
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 template<class T>
00493 inline T absdiff(const T& x,const T& y) {
00494 return ((x>y) ? (x-y) : (y-x));
00495 }
00496
00497
00498
00499
00500 inline double reciprocal(const double& x) {
00501 return 1.0/x;
00502 }
00503
00504
00505
00506
00507 inline float reciprocal(const float& x) {
00508 return 1.0f/x;
00509 }
00510
00511
00512
00513
00514
00515
00516 inline double oneMinus(const double& x) {
00517 return 1.0-x;
00518 }
00519
00520
00521
00522
00523
00524
00525 inline float oneMinus(const float& x) {
00526 return 1.0f-x;
00527 }
00528
00529
00530
00531
00532 inline int oneMinus(const int& x) {
00533 return 1-x;
00534 }
00535
00536
00537
00538
00539
00540
00541 template<class T>
00542 inline T rectify(const T& x) {
00543 return ((x>=0) ? x : 0);
00544 }
00545
00546
00547
00548
00549
00550
00551 template<class T>
00552 inline T sqr(const T& x) {
00553 return (x*x);
00554 }
00555
00556
00557
00558
00559
00560
00561 inline int sqrt(int x) {
00562 return static_cast<int>(::sqrt(static_cast<double>(x)));
00563 }
00564
00565
00566
00567
00568
00569
00570 inline unsigned int sqrt(unsigned int x) {
00571 return static_cast<unsigned int>(::sqrt(static_cast<double>(x)));
00572 }
00573
00574
00575
00576
00577
00578
00579 inline float sqrt(float x) {
00580 #ifdef _LTI_MATH_H_STYLE
00581
00582
00583 return static_cast<float>(::sqrt(x));
00584 #else
00585
00586 return static_cast<float>(std::sqrt(x));
00587 #endif
00588 }
00589
00590
00591
00592
00593
00594
00595 inline double sqrt(const double& x) {
00596 #ifdef _LTI_MATH_H_STYLE
00597
00598
00599 return static_cast<double>(::sqrt(x));
00600 #else
00601
00602 return static_cast<double>(std::sqrt(x));
00603 #endif
00604 }
00605
00606
00607
00608
00609
00610 template<class T>
00611 inline T sqrtrect(const T x) {
00612 if (x<=static_cast<T>(0)) {
00613 return static_cast<T>(0);
00614 }
00615 return sqrt(x);
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 template <class T>
00629 inline void sincos(T angle, T& sval, T& cval) {
00630 sincos_impl(static_cast<double>(angle),
00631 static_cast<double&>(sval),
00632 static_cast<double&>(cval));
00633 }
00634
00635
00636 inline void sincos(float angle, float& sval, float& cval) {
00637 sincosf_impl(angle,sval,cval);
00638 }
00639
00640
00641
00642 #ifdef _LTI_MATH_H_STYLE
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 template<class T>
00656 inline void swap(T& a,T& b) {
00657 T tmp(a);
00658 a=b;
00659 b=tmp;
00660 }
00661
00662
00663
00664
00665
00666
00667 inline float sin(float x) {
00668 return static_cast<float>(::sin(x));
00669 }
00670
00671
00672
00673
00674
00675
00676 inline double sin(const double& x) {
00677 return ::sin(x);
00678 }
00679
00680
00681
00682
00683
00684
00685 inline float cos(float x) {
00686 return static_cast<float>(::cos(x));
00687 }
00688
00689
00690
00691
00692
00693
00694 inline double cos(const double& x) {
00695 return ::cos(x);
00696 }
00697
00698
00699
00700
00701
00702
00703 inline float tan(float x) {
00704 return static_cast<float>(::tan(x));
00705 }
00706
00707
00708
00709
00710
00711
00712 inline double tan(const double& x) {
00713 return ::tan(x);
00714 }
00715
00716
00717
00718
00719
00720
00721 inline float asin(float x) {
00722 return static_cast<float>(::asin(x));
00723 }
00724
00725
00726
00727
00728
00729
00730 inline double asin(const double& x) {
00731 return ::asin(x);
00732 }
00733
00734
00735
00736
00737
00738
00739 inline float acos(float x) {
00740 return static_cast<float>(::acos(x));
00741 }
00742
00743
00744
00745
00746
00747
00748 inline double acos(const double& x) {
00749 return ::acos(x);
00750 }
00751
00752
00753
00754
00755
00756
00757
00758 inline float atan(float x) {
00759 return static_cast<float>(::atan(x));
00760 }
00761
00762
00763
00764
00765
00766
00767 inline double atan(const double& x) {
00768 return ::atan(x);
00769 }
00770
00771
00772
00773
00774
00775
00776 inline float atan2(float y,float x) {
00777 return static_cast<float>(::atan2(y,x));
00778 }
00779
00780
00781
00782
00783
00784
00785 inline double atan2(const double& y,const double& x) {
00786 return ::atan2(y,x);
00787 }
00788
00789
00790
00791
00792
00793
00794 inline double sinh(const double& x) {
00795 return ::sinh(x);
00796 }
00797
00798
00799
00800
00801
00802
00803 inline double sinh(float x) {
00804 return static_cast<float>(::sinh(x));
00805 }
00806
00807
00808
00809
00810
00811
00812 inline float cosh(float x) {
00813 return static_cast<float>(::cosh(x));
00814 }
00815
00816
00817
00818
00819
00820
00821 inline double cosh(const double& x) {
00822 return ::cosh(x);
00823 }
00824
00825
00826
00827
00828
00829
00830 inline float tanh(float x) {
00831 return static_cast<float>(::tanh(x));
00832 }
00833
00834
00835
00836
00837
00838
00839 inline double tanh(const double& x) {
00840 return ::tanh(x);
00841 }
00842
00843
00844
00845
00846
00847
00848 inline float log(float x) {
00849 return static_cast<float>(::log(x));
00850 }
00851
00852
00853
00854
00855
00856
00857 inline double log(const double& x) {
00858 return ::log(x);
00859 }
00860
00861
00862
00863
00864
00865
00866 inline double log(int x) {
00867 return ::log(static_cast<double>(x));
00868 }
00869
00870
00871
00872
00873
00874
00875 inline float log10(float x) {
00876 return static_cast<float>(::log10(x));
00877 }
00878
00879
00880
00881
00882
00883
00884 inline double log10(const double& x) {
00885 return ::log10(x);
00886 }
00887
00888
00889
00890
00891
00892
00893 inline double log10(int x) {
00894 return ::log10(static_cast<double>(x));
00895 }
00896
00897
00898
00899
00900
00901
00902 inline float exp(float x) {
00903 return static_cast<float>(::exp(x));
00904 }
00905
00906
00907
00908
00909
00910
00911 inline double exp(const double& x) {
00912 return ::exp(x);
00913 }
00914
00915
00916
00917
00918
00919
00920 inline double exp(int x) {
00921 return ::exp(static_cast<double>(x));
00922 }
00923
00924
00925
00926
00927
00928
00929 inline double pow(const double& x, const double& y) {
00930 return ::pow(x,y);
00931 }
00932
00933
00934
00935
00936
00937
00938 inline float pow(float x,float y) {
00939 return static_cast<float>(::pow(x,y));
00940 }
00941
00942
00943
00944
00945
00946
00947 inline double pow(const double& x, int y) {
00948 return ::pow(x,y);
00949 }
00950
00951
00952
00953
00954
00955
00956 inline float pow(float x,int y) {
00957 return static_cast<float>(::pow(x,y));
00958 }
00959
00960 #else
00961
00962 using std::swap;
00963 using std::sin;
00964 using std::cos;
00965 using std::tan;
00966 using std::asin;
00967 using std::acos;
00968 using std::atan;
00969 using std::atan2;
00970 using std::sinh;
00971 using std::cosh;
00972 using std::tanh;
00973 using std::log;
00974 using std::log10;
00975 using std::exp;
00976 using std::pow;
00977 #endif
00978
00979
00980
00981
00982
00983
00984 inline float sigmoid(const float x) {
00985 return static_cast<float>(1.0/(1.0+exp(-x)));
00986 }
00987
00988
00989
00990
00991
00992
00993 inline double sigmoid(const double& x){
00994 return 1.0/(1.0+exp(-x));
00995 }
00996
00997
00998
00999
01000
01001
01002 inline double sigmoid(const int x){
01003 return 1.0/(1.0+exp(-static_cast<double>(x)));
01004 }
01005
01006
01007
01008
01009
01010
01011 template<class T>
01012 inline T signum(T x) {
01013 return ((x>=T()) ? T(1) : T(-1));
01014 }
01015
01016
01017
01018
01019
01020
01021 template<class T>
01022 inline T signum0(T x) {
01023 return ((x>0) ? T(1) : ((x<0) ? T(-1) : T(0)));
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 template<class T>
01035 inline bool even(const T x) {
01036 return ((x & static_cast<T>(1)) == 0);
01037 }
01038
01039 template<>
01040 inline bool even(const double x) {
01041 const int64 i = static_cast<int64>(x);
01042 return ((static_cast<double>(i) == x) && even(i));
01043 }
01044
01045 template<>
01046 inline bool even(const float x) {
01047 const int i = static_cast<int>(x);
01048 return ((static_cast<float>(i) == x) && even(i));
01049 }
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060 template<class T>
01061 inline bool odd(const T x) {
01062 return ((x & static_cast<T>(1)) != 0);
01063 }
01064
01065 template<>
01066 inline bool odd(const double x) {
01067 const int64 i = static_cast<int64>(x);
01068 return ((static_cast<double>(i) == x) && odd(i));
01069 }
01070
01071 template<>
01072 inline bool odd(const float x) {
01073 const int i = static_cast<int>(x);
01074 return ((static_cast<float>(i) == x) && odd(i));
01075 }
01076
01077
01078
01079
01080
01081
01082 template<class T>
01083 T betai(const T& a, const T& b, const T& x);
01084
01085
01086
01087
01088
01089 double betacf(const double& a, const double& b, const double& x);
01090
01091 }
01092
01093
01094 #include "ltiMath_template.h"
01095
01096 #endif