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
00034
00035
00036
00037
00038 #ifndef MATHFUNCTIONS_H_DEFINED
00039 #define MATHFUNCTIONS_H_DEFINED
00040
00041 #include "Util/Assert.H"
00042 #include "Image/Image.H"
00043 #include "Image/Point2D.H"
00044 #include "Util/FastMathFunctions.H"
00045 #include "Util/Promotions.H"
00046 #include "rutz/compat_cmath.h"
00047
00048 #include <algorithm>
00049 #include <cmath>
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #define D_PI 3.1415926535897932384626433832795029
00066
00067 #define D_E 2.7182818284590452353602874713526625
00068
00069 #define D_LOG_SQRT_2_PI 0.9189385332046727417803297364056176
00070
00071 #define D_SQRT_2_PI 2.5066282746310002416123552393401041
00072
00073 #define D_SQRT_PI 1.7724538509055160272981674833411451
00074
00075 #define D_SQRT_2 1.4142135623730950488016887242096981
00076
00077 #define D_LOG_2_PI 1.8378770664093454835606594728112353
00078
00079 #define D_LOG_PI 1.1447298858494001741434273513530587
00080
00081 #define D_LOG_2 0.6931471805599453094172321214581766
00082
00083 #define D_LOG_SQRT_2 0.3465735902799726547086160607290883
00084
00085 #define D_2_PI 6.2831853071795862319959269370883703
00086
00087 #define D_EULER_GAMMA 0.5772156649015328606065120900824024
00088
00089 #define D_DEGREE 0.0174532925199432957692369076848861
00090
00091 #define D_GOLDEN_RATIO 1.6180339887498948482045868343656381
00092
00093 #define D_CATALAN 0.9159655941772190150546035149323841
00094
00095 #define D_GLAISHER 1.2824271291006226368753425688697917
00096
00097 #define D_KHINCHIN 2.6854520010653064453097148354817956
00098
00099 #define D_SOLDNER 1.4513692348833810502839684858920274
00100
00101 #define D_APERY 1.2020569031595942853997381615114499
00102
00103 #define D_GAUSS_KUZMAN 0.3036630028987326585974481219015562
00104
00105 #define D_FRANSEN 2.8077702420285193652215011865577729
00106
00107 #define D_SERPINSKY 2.5849817595792532170658935873831711
00108
00109 #define D_MILL 1.3063778838630806904686144926026057
00110
00111 #define D_OMEGA 0.5671432904097838729999686622103555
00112
00113 #define D_GOLOMB_DICKMAN 0.6243299885435508709929363831008372
00114
00115
00116
00117
00118
00119
00120
00121
00122 #define L_PI 3.14159265358979323846264338327950288419716939937510582097494459230781L // ... 640628620899862803482534
00123
00124 #define L_E 2.71828182845904523536028747135266249775724709369995957496696762772407L // ... 663035354759457138
00125
00126 #define L_LOG_SQRT_2_PI 0.91893853320467274178032973640561763986139747363778341281715154048276L
00127
00128 #define L_SQRT_2_PI 2.50662827463100050241576528481104525300698674060993831662992357634229L
00129
00130 #define L_SQRT_PI 1.77245385090551602729816748334114518279754945612238712821380778985291L
00131
00132 #define L_SQRT_2 1.41421356237309514547462185873882845044136047363281250000000000000000L
00133
00134 #define L_LOG_2_PI 1.83787706640934548356065947281123527972279494727556682563430308096553L
00135
00136 #define L_LOG_PI 1.14472988584940017414342735135305871164729481291531157151362307147214L
00137
00138 #define L_LOG_2 0.69314718055994528622676398299518041312694549560546875000000000000000L
00139
00140 #define L_2_PI 6.28318530717958647692528676655900576839433879875021164194988918461560L
00141
00142 #define L_DEGREE 0.01745329251994329576923690768488612713442871888541725456097191440171L // ... 009114603449443682
00143
00144 #define L_EULER_GAMMA 0.57721566490153286060651209008240243104215933593992359880576723488486L
00145
00146 #define L_GOLDEN_RATIO 1.61803398874989484820458683436563811772030917980576286213544862270526L // ... 046281890244970721
00147
00148 #define L_CATALAN 0.91596559417721901505460351493238411077414937428167213426649811962176L // ... 301977625476947936
00149
00150 #define L_GLAISHER 1.28242712910062263687534256886979172776768892732500119206374002174040L // ... 630885882646112974
00151
00152 #define L_KHINCHIN 2.68545200106530644530971483548179569382038229399446295305115234555721L // ... 885953715200280114
00153
00154
00155
00156
00157
00158
00159
00160 template <class T>
00161 inline int signOf(const T& x);
00162
00163
00164 template <class T>
00165 inline T squareOf(const T& x);
00166
00167
00168
00169
00170 template <class T, class T2>
00171 inline T clampValue(const T& val, const T2& bound1, const T2& bound2);
00172
00173
00174
00175
00176
00177
00178
00179
00180 bool isFinite(const byte& arg);
00181
00182
00183 bool isFinite(const int16& arg);
00184
00185
00186 bool isFinite(const int32& arg);
00187
00188
00189 bool isFinite(const float& arg);
00190
00191
00192 bool isFinite(const double& arg);
00193
00194
00195
00196
00197
00198
00199
00200
00201 void initRandomNumbers();
00202
00203
00204 void initRandomNumbersZero();
00205
00206
00207
00208
00209 double randomDouble();
00210
00211
00212
00213 double randomDoubleFromNormal(const double s);
00214
00215
00216
00217
00218 int randomUpToIncluding(const int n);
00219
00220
00221
00222
00223 int randomUpToNotIncluding(const int n);
00224
00225
00226 template <class T> inline
00227 void randShuffle(T* array, const uint size);
00228
00229
00230
00231
00232
00233
00234
00235
00236 double ran2(int& idum);
00237
00238
00239
00240
00241
00242 int getIdum(const bool useRandom = true);
00243
00244
00245 double gasdev(int& idum);
00246
00247
00248 double expdev(int& idum);
00249
00250
00251
00252
00253
00254
00255
00256
00257 double poisson(const unsigned int k, const double mu);
00258
00259
00260 double lngamma(double x);
00261
00262
00263 double psi(const double x);
00264
00265
00266
00267
00268
00269
00270
00271
00272 template <class T> inline T maxmerge(T A, const T B)
00273 {
00274 if (A < B) A = B;
00275 return A;
00276 }
00277
00278
00279 template <class T> inline T minmerge(T A, const T B)
00280 {
00281 if (A > B) A = B;
00282 return A;
00283 }
00284
00285
00286
00287 template <class T> inline T sec(T A)
00288 {
00289 return clamped_convert<T>(1.0/cos(A));
00290 }
00291
00292
00293
00294 template <class T> inline T cosec(T A)
00295 {
00296 return clamped_convert<T>(1.0/sin(A));
00297 }
00298
00299
00300
00301 template <class T> inline T cotan(T A)
00302 {
00303 return clamped_convert<T>(1.0/tan(A));
00304 }
00305
00306
00307
00308 template <class T> inline T asec(T A)
00309 {
00310 ASSERT(A >= 1.0);
00311 return clamped_convert<T>(acos(1.0/A));
00312 }
00313
00314
00315
00316 template <class T> inline T acosec(T A)
00317 {
00318 ASSERT(A >= 1.0);
00319 return clamped_convert<T>(asin(1.0/A));
00320 }
00321
00322
00323
00324 template <class T> inline T acotan(T A)
00325 {
00326 return clamped_convert<T>(atan(1.0/A));
00327 }
00328
00329
00330
00331 template <class T> inline T sech(T A)
00332 {
00333 return clamped_convert<T>(1.0/cosh(A));
00334 }
00335
00336
00337
00338 template <class T> inline T cosech(T A)
00339 {
00340 return clamped_convert<T>(1.0/sinh(A));
00341 }
00342
00343
00344
00345 template <class T> inline T cotanh(T A)
00346 {
00347 return clamped_convert<T>(1.0/tanh(A));
00348 }
00349
00350
00351
00352 template <class T> inline T asech(T A)
00353 {
00354 return clamped_convert<T>(acosh(1.0/A));
00355 }
00356
00357
00358
00359 template <class T> inline T acosech(T A)
00360 {
00361 return clamped_convert<T>(asinh(1.0/A));
00362 }
00363
00364
00365
00366 template <class T> inline T acotanh(T A)
00367 {
00368 return clamped_convert<T>(atanh(1.0/A));
00369 }
00370
00371
00372
00373 template <class T> inline T sign(T A)
00374 {
00375 if (A >= 0) A = 1;
00376 else A = -1;
00377 return A;
00378 }
00379
00380
00381
00382 template <class T> inline T logN(T A, const T n)
00383 {
00384 A = clamped_convert<T>(
00385 log(static_cast<double>(A))/
00386 log(static_cast<double>(n)));
00387 return A;
00388 }
00389
00390
00391
00392 template <class T> inline T logsig(T A,const T a, const T b)
00393 {
00394 A = clamped_convert<T>(1.0/(1+exp(static_cast<double>(- (b * (A - a))))));
00395 return A;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 template <class T> inline T logsig2(T x, const T a, const T b)
00406 {
00407 x = clamped_convert<T>(1.0/(1+exp(static_cast<double>(-x*a + b))));
00408 return x;
00409 }
00410
00411
00412
00413 template <class T> inline T tansig(T A)
00414 {
00415 A = clamped_convert<T>(2/1+exp(-2*static_cast<double>(A))-1);
00416 return A;
00417 }
00418
00419
00420
00421 template <class T> inline T angDiff(const T A,const T B, const double diffWRAP=M_PI)
00422 {
00423 double diff = fabs(static_cast<double>(A) - static_cast<double>(B));
00424 return std::min(diff, fabs(diff-diffWRAP));
00425 }
00426
00427
00428 template <class T> inline double angle(const Point2D<T> p0, const Point2D<T> p1, const Point2D<T> p2)
00429 {
00430
00431 double dx1 = p1.i - p0.i;
00432 double dy1 = p1.j - p0.j;
00433 double dx2 = p2.i - p0.i;
00434 double dy2 = p2.j - p0.j;
00435
00436 return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
00437 }
00438
00439
00440
00441
00442
00443 template <class T> inline T saturate(T A, const T n)
00444 {
00445 if(A >= n) A = n;
00446 else A = A;
00447 return A;
00448 }
00449
00450
00451
00452 template <class T> inline T gauss(T A, const T Mu, const T Std)
00453 {
00454 return clamped_convert<T>(
00455 (1/(fastSqrt(D_2_PI*pow(static_cast<double>(Std),2))))
00456 *exp(-1*(pow((static_cast<double>(A) -
00457 static_cast<double>(Mu)),2)
00458 /(2*pow(static_cast<double>(Std),2)))));
00459 }
00460
00461
00462
00463 template <class T> inline T gauss(T diff, const T Std)
00464 {
00465 return clamped_convert<T>(
00466 (1/(fastSqrt(D_2_PI*pow(static_cast<double>(Std),2))))
00467 *exp(-1*(pow((static_cast<double>(diff)),2)
00468 /(2*pow(static_cast<double>(Std),2)))));
00469 }
00470
00471
00472
00473 template <class T> inline T gamma(T X, const T A, const T B)
00474 {
00475 return clamped_convert<T>((
00476 pow(static_cast<double>(X),static_cast<double>(A) -1) *
00477 pow(static_cast<double>(B),static_cast<double>(A)) *
00478 exp(static_cast<double>(-1.0*B*X)))/
00479 lgamma(static_cast<double>(A)));
00480 }
00481
00482
00483
00484 template <class T> inline T max(T A)
00485 {
00486 return A;
00487 }
00488
00489
00490
00491 template <class T> inline T min(T A)
00492 {
00493 return A;
00494 }
00495
00496
00497
00498 template <class T> inline bool isBounded(T A, const T upper, const T lower)
00499 {
00500 return ((A >= lower) && (A <= upper));
00501 }
00502
00503
00504
00505 template <class T> inline T sum(T A)
00506 {
00507 return A;
00508 }
00509
00510
00511
00512 template <class T> inline T mean(T A)
00513 {
00514 return A;
00515 }
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 template <class T> inline T onlineMean(T mu, T A, int n)
00528 {
00529 const T delta = A - mu;
00530 return mu + (delta/n);
00531 }
00532
00533 template <class T> inline T onlineStdev(T mu, T stdev, T A, int n)
00534 {
00535 T ret = stdev;
00536 if (n > 2)
00537 {
00538 const T delta = A - mu;
00539 ret = (stdev * (n-2)) + delta*delta;
00540 ret /= T(n-1);
00541 }
00542
00543 return ret;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 template <class T> inline int signOf(const T& x)
00555 { return (x < 0) ? -1 : 1; }
00556
00557 template <class T> inline T squareOf(const T& x)
00558 { return (x * x); }
00559
00560 template <class T, class T2>
00561 inline T clampValue(const T& val, const T2& bound1, const T2& bound2)
00562 {
00563 if (bound1 < bound2)
00564 {
00565 if (val < bound1) return bound1;
00566 if (val > bound2) return bound2;
00567 return val;
00568 }
00569 else
00570 {
00571 if (val < bound2) return bound2;
00572 if (val > bound1) return bound1;
00573 }
00574 return val;
00575 }
00576
00577 template <class T> inline void randShuffle(T* array, const uint size)
00578 {
00579 for (uint i = 0; i < size; ++i)
00580 {
00581 const uint idx = i + randomUpToNotIncluding(size-i);
00582 std::swap(array[i], array[idx]);
00583 }
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 struct cheb_series_struct {
00612 double * c;
00613 int order;
00614 double a;
00615 double b;
00616 int order_sp;
00617 };
00618 typedef struct cheb_series_struct cheb_series;
00619
00620
00621
00622 static double psics_data[23] = {
00623 -.038057080835217922,
00624 .491415393029387130,
00625 -.056815747821244730,
00626 .008357821225914313,
00627 -.001333232857994342,
00628 .000220313287069308,
00629 -.000037040238178456,
00630 .000006283793654854,
00631 -.000001071263908506,
00632 .000000183128394654,
00633 -.000000031353509361,
00634 .000000005372808776,
00635 -.000000000921168141,
00636 .000000000157981265,
00637 -.000000000027098646,
00638 .000000000004648722,
00639 -.000000000000797527,
00640 .000000000000136827,
00641 -.000000000000023475,
00642 .000000000000004027,
00643 -.000000000000000691,
00644 .000000000000000118,
00645 -.000000000000000020
00646 };
00647 const static cheb_series psi_cs = { psics_data, 22, -1, 1, 17 };
00648
00649
00650 static double apsics_data[16] = {
00651 -.0204749044678185,
00652 -.0101801271534859,
00653 .0000559718725387,
00654 -.0000012917176570,
00655 .0000000572858606,
00656 -.0000000038213539,
00657 .0000000003397434,
00658 -.0000000000374838,
00659 .0000000000048990,
00660 -.0000000000007344,
00661 .0000000000001233,
00662 -.0000000000000228,
00663 .0000000000000045,
00664 -.0000000000000009,
00665 .0000000000000002,
00666 -.0000000000000000
00667 };
00668 const static cheb_series apsi_cs = { apsics_data, 15, -1, 1, 9 };
00669
00670
00671
00672
00673
00674
00675 inline double cheb_eval(const cheb_series* cs, const double x)
00676 {
00677 double d = 0.0, dd = 0.0;
00678
00679 const double y = (2.0*x - cs->a - cs->b) * (1.0/(cs->b - cs->a));
00680
00681 const double y2 = 2.0 * y;
00682
00683 for (uint j = cs->order; j >= 1; j--)
00684 {
00685 const double temp = d;
00686 d = y2*d - dd + cs->c[j];
00687 dd = temp;
00688 }
00689
00690 return y*d - dd + 0.5 * cs->c[0];
00691 }
00692
00693
00694
00695
00696
00697
00698
00699 inline double cheb_eval_psi(const double x)
00700 {
00701 double d = 0.0, dd = 0.0;
00702
00703 const double y2 = 2.0 * x;
00704
00705 for (uint j = 22; j >= 1; j--)
00706 {
00707 const double temp = d;
00708 d = y2*d - dd + psics_data[j];
00709 dd = temp;
00710 }
00711
00712 return x*d - dd + 0.5 * -.038057080835217922;
00713 }
00714
00715 inline double cheb_eval_apsi(const double x)
00716 {
00717 double d = 0.0, dd = 0.0;
00718
00719 const double y2 = 2.0 * x;
00720
00721 for (uint j = 15; j >= 1; j--)
00722 {
00723 const double temp = d;
00724 d = y2*d - dd + apsics_data[j];
00725 dd = temp;
00726 }
00727
00728 return x*d - dd + 0.5 * -.0204749044678185;
00729 }
00730
00731
00732
00733
00734
00735 inline double psi(const double x)
00736 {
00737 if (x >= 2.0)
00738 {
00739
00740
00741
00742
00743
00744
00745 const double t = 8.0 / (x*x) - 1.0;
00746 const double cheb = cheb_eval(&apsi_cs, t);
00747 return fastLog(x) - 0.5 / x + cheb;
00748 }
00749 else if (x < 1.0)
00750 {
00751 if( x <= 0.0)
00752 LFATAL("Digamma (Psi) Only defined for x > 0.0");
00753
00754 const double t1 = 1.0 / x;
00755 const double cheb = cheb_eval(&psi_cs, 2.0*x-1.0);
00756 return cheb - t1;
00757 }
00758 else
00759 {
00760 const double v = x - 1.0;
00761 return cheb_eval(&psi_cs, 2.0*v-1.0);
00762
00763 }
00764 }
00765
00766
00767
00768 inline double fast_psi(const double x)
00769 {
00770 if (x >= 2.0)
00771 {
00772 const double t = 8.0 / (x*x) - 1.0;
00773 const double cheb = cheb_eval_apsi(t);
00774 return fastLog(x) - 0.5 / x + cheb;
00775 }
00776 else if (x < 1.0)
00777 {
00778 const double t1 = 1.0 / x;
00779 const double cheb = cheb_eval_psi(2.0*x-1.0);
00780 return cheb - t1;
00781 }
00782 else
00783 {
00784 const double v = x - 1.0;
00785 return cheb_eval_psi(2.0*v-1.0);
00786 }
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796 template <class T> inline T wow(const T& k)
00797 {
00798
00799
00800
00801
00802
00803 if (k < 0.0) return 0.0;
00804
00805 return k * (1.0F/D_LOG_2);
00806 }
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 template <class T> inline T KLjointGammaGamma(const T ai,const T aj,
00824 const T bi,const T bj,
00825 const T Ai,const T Aj,
00826 const T Bi,const T Bj,
00827 const bool doWow = false,
00828 const T gammaBiasi = 1.0F,
00829 const T gammaBiasj = 1.0F)
00830 {
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 const T k = gammaBiasi * KLgamma(ai,bi,Ai,Bi) + gammaBiasj * KLgamma(aj,bj,Aj,Bj);
00867
00868 if(doWow) return wow(k);
00869 else return k;
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887 template <class T> inline T KLjointGammaGauss(const T a,const T u,
00888 const T b,const T s,
00889 const T A,const T U,
00890 const T B,const T S,
00891 const bool doWow = false,
00892 const T gammaBias = 1.0F,
00893 const T gaussBias = 1.0F)
00894 {
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 const T k = gammaBias * KLgamma(a,b,A,B) + gaussBias * KLgauss(u,s,U,S);
00925
00926 if(doWow) return wow(k);
00927 else return k;
00928 }
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939 template <class T> inline T KLgamma(const T a,const T b,
00940 const T A,const T B,
00941 const bool doWow = false)
00942 {
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 const T k = - a + a*B/b + A*fastLog(b/B) + lgamma(A) - lgamma(a)
00968 + (a - A)*fast_psi(a);
00969
00970 if(doWow) return wow(k);
00971 else return k;
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 template <class T> inline T KLgammaConst(const T a, const T A,
00989 const T C1, const T C2,
00990 const bool doWow = false)
00991 {
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030 const T k = a*C1 + A*C2 + lgamma(A) - lgamma(a) + (a - A)*fast_psi(a);
01031
01032 if(doWow) return wow(k);
01033 else return k;
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 template <class T> inline T KLgamma(const T a,const T A,
01048 const bool doWow = false)
01049 {
01050
01051
01052
01053
01054
01055 const T k = lgamma(A) - lgamma(a) + (a - A)*fast_psi(a);
01056
01057 if(doWow) return wow(k);
01058 else return k;
01059 }
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070 template <class T> inline T KLgauss(const T u,const T s,
01071 const T U,const T S,
01072 const bool doWow = false)
01073 {
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 const T iS = 1.0 / 2*S*S;
01093 const T x = s*s * iS;
01094 const T mm = (u - U)*(u - U);
01095 const T k = -1.0 * (x - 0.5 - log(s/S) + mm * iS);
01096
01097 if(doWow)
01098 return wow(k);
01099 else
01100 return k;
01101 }
01102
01103
01104
01105
01106 struct GaussianDef
01107 {
01108 double weight;
01109 double mu;
01110 double sigma;
01111
01112 GaussianDef(double w, double m, double s) :
01113 weight(w), mu(m), sigma(s)
01114 {}
01115
01116 };
01117
01118
01119
01120
01121
01122
01123
01124 inline double L2GMM(const std::vector<GaussianDef>& f,
01125 const std::vector<GaussianDef>& g)
01126 {
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140 double distff = 0;
01141 for(uint i=0; i<f.size(); i++)
01142 for(uint j=0; j<f.size(); j++)
01143 distff += f[i].weight*f[j].weight * gauss(0.0, f[i].mu-f[j].mu, f[i].sigma+f[j].sigma);
01144
01145 double distgg = 0;
01146 for(uint i=0; i<g.size(); i++)
01147 for(uint j=0; j<g.size(); j++)
01148 distgg += g[i].weight*g[j].weight * gauss(0.0, g[i].mu-g[j].mu, g[i].sigma+g[j].sigma);
01149
01150 double distfg = 0;
01151 for(uint i=0; i<f.size(); i++)
01152 for(uint j=0; j<g.size(); j++)
01153 distfg += f[i].weight*g[j].weight * gauss(0.0, f[i].mu-g[j].mu, f[i].sigma+g[j].sigma);
01154
01155
01156 return distff + distgg - 2*distfg;
01157 }
01158
01159
01160 double AUC(const float* model, const float* rand,
01161 size_t sm, size_t sr,
01162 const double step = 0.1);
01163
01164
01165
01166 template <class T> inline Point2D<T> ellipsoid(const T a, const T b, const T e, const T theta)
01167 {
01168
01169 T x = clamped_convert<T>(a * sign(cos(theta)) * pow(fabs(static_cast<double>(cos(theta))), e));
01170 T y = clamped_convert<T>(b * sign(sin(theta)) * pow(fabs(static_cast<double>(sin(theta))), e));
01171
01172 return Point2D<T>(x,y);
01173
01174 }
01175
01176
01177 Point2D<float> getEllipseFromCov(const Image<double>& cov);
01178
01179
01180
01181 double inline getChi2Inv(int k)
01182 {
01183 switch (k)
01184 {
01185 case 2: return 5.991464547107980e+00;
01186 case 3: return 7.814727903251160e+00;
01187 case 6: return 1.259158724374398e+01;
01188 default : LFATAL("Unknown value for k=%i", k);
01189 }
01190
01191 return 0;
01192 }
01193
01194 #endif
01195
01196
01197
01198