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 #include "Surprise/SurpriseModel.H"
00039
00040 #include "Util/Assert.H"
00041 #include "Util/log.H"
00042
00043
00044
00045
00046
00047
00048
00049 SurpriseModel::SurpriseModel(const double updatefac, const double sampleval,
00050 const double samplevar) :
00051 itsUpdateFac(updatefac), itsInitialVal(sampleval), itsInitialVar(samplevar)
00052 { }
00053
00054
00055 SurpriseModel::~SurpriseModel()
00056 { }
00057
00058
00059 inline void SurpriseModel::init(const double updfac,
00060 const double sampleval,
00061 const double samplevar)
00062 { itsInitialVal = sampleval; itsInitialVar = samplevar; itsUpdateFac = updfac;}
00063
00064
00065 inline void SurpriseModel::resetUpdFac(const double updfac)
00066 { itsUpdateFac = updfac; }
00067
00068
00069 inline double SurpriseModel::surprise(const SurpriseModel& other)
00070 { LFATAL("Unimplemented! use derived classes instead"); return 0.0; }
00071
00072
00073 inline void SurpriseModel::preComputeHyperParams(const SurpriseModel& sample)
00074 { LFATAL("Unimplemented! use derived classes instead"); }
00075
00076
00077 inline void SurpriseModel::combineFrom(const Image<SurpriseModel>& models,
00078 const Image<float>& weights)
00079 { LFATAL("Unimplemented! use derived classes instead"); }
00080
00081
00082 inline void SurpriseModel::combineFrom(const Image<SurpriseModel>& models,
00083 const Image<float>& weights,
00084 const Point2D<int>& pos,
00085 const int width,
00086 const int height,
00087 const int offset)
00088 { LFATAL("Unimplemented! use derived classes instead"); }
00089
00090
00091 inline void SurpriseModel::setBias(const double slfac,
00092 const double ssfac,
00093 const SU_KL_BIAS klbias)
00094 { LFATAL("Unimplemented! use derived classes instead"); }
00095
00096
00097 #define COMBINE_FROM(models,weights) \
00098 ASSERT(models.isSameSize(weights)); \
00099 COMBINE_INIT \
00100 Image<COMBINE_TYPE>::const_iterator m = models.begin(), \
00101 stop = models.end(); \
00102 Image<float>::const_iterator w = weights.begin(); \
00103 double wsum = 0.0; \
00104 while(m != stop) \
00105 { \
00106 const double weight = double(*w++); \
00107 COMBINE_UPDATE \
00108 wsum += weight; \
00109 ++m; \
00110 } \
00111 COMBINE_FINISH
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 #define COMBINE_FROM_WMIN(models,weights,pos,width,height,offset) \
00143 COMBINE_INIT \
00144 Image<COMBINE_TYPE>::const_iterator m = models.begin(); \
00145 Image<float>::const_iterator w = weights.begin(); \
00146 w += offset - pos.i; \
00147 double wsum = 0.0F; \
00148 for (int j = 0; j < height; j ++) \
00149 { \
00150 for (int i = 0; i < width; i ++) \
00151 { \
00152 const double weight = *w++; \
00153 COMBINE_UPDATE \
00154 wsum += weight; \
00155 ++m; \
00156 } \
00157 w += width + 1; \
00158 } \
00159 COMBINE_FINISH
00160
00161
00162
00163
00164
00165
00166
00167 SurpriseModelSG::SurpriseModelSG(const double updatefac,
00168 const double sampleval,
00169 const double samplevar) :
00170 SurpriseModel(updatefac, sampleval, samplevar),
00171 itsN(1),
00172 itsMean(sampleval),
00173 itsVar(samplevar)
00174 { }
00175
00176
00177 SurpriseModelSG::~SurpriseModelSG()
00178 { }
00179
00180
00181 inline void SurpriseModelSG::reset()
00182 { load(itsInitialVal, itsInitialVar); }
00183
00184
00185 inline void SurpriseModelSG::init(const double updfac,
00186 const double sampleval,
00187 const double samplevar)
00188 {
00189 SurpriseModel::init(updfac, sampleval, samplevar);
00190 reset();
00191 }
00192
00193
00194 inline void SurpriseModelSG::load(const double sampleval,
00195 const double samplevar)
00196 { itsMean = sampleval; itsVar = samplevar; }
00197
00198
00199 inline double SurpriseModelSG::surprise(const SurpriseModelSG& sample)
00200 {
00201 const double mean1 = itsMean, var1 = itsVar / itsUpdateFac;
00202 const double mean2 = sample.itsMean, var2 = sample.itsVar;
00203
00204 const double ivar1 = var1 < 1.0e-10 ? 1.0e10 : 1.0 / var1;
00205 const double ivar2 = var2 < 1.0e-10 ? itsN * 1.0e10 : itsN / var2;
00206
00207
00208
00209
00210 const double newMean = (mean1 * ivar1 + mean2 * ivar2) / (ivar1 + ivar2);
00211 const double newVar = 1.0 / (ivar1 + ivar2);
00212
00213
00214
00215
00216 const double x = newVar / var1, mm = newMean - mean1;
00217 const double s = 0.5 * (x - 1.0 - log(x) + mm * mm /var1);
00218
00219
00220 itsMean = newMean; itsVar = newVar;
00221
00222
00223 return s / M_LN2;
00224 }
00225
00226
00227 inline void SurpriseModelSG::preComputeHyperParams(const SurpriseModelSG& sample)
00228 { LFATAL("Unimplemented in this model!"); }
00229
00230
00231
00232 #define COMBINE_INIT itsMean = 0.0; itsVar = 0.0;
00233 #define COMBINE_TYPE SurpriseModelSG
00234 #define COMBINE_UPDATE \
00235 const double mmean = m->itsMean; \
00236 itsMean += weight * mmean; \
00237 itsVar += weight * (m->itsVar + mmean * mmean);
00238 #define COMBINE_FINISH \
00239 itsMean /= wsum; itsVar /= wsum; \
00240 itsVar -= itsMean * itsMean;
00241
00242
00243 inline void SurpriseModelSG::combineFrom(const Image<SurpriseModelSG>& models,
00244 const Image<float>& weights)
00245 {
00246
00247
00248 COMBINE_FROM(models,weights)
00249 }
00250
00251
00252 inline void SurpriseModelSG::combineFrom(const Image<SurpriseModelSG>& models,
00253 const Image<float>& weights,
00254 const Point2D<int>& pos,
00255 const int width,
00256 const int height,
00257 const int offset)
00258 {
00259
00260
00261 COMBINE_FROM_WMIN(models,weights,pos,width,height,offset)
00262 }
00263
00264
00265
00266 #undef COMBINE_INIT
00267 #undef COMBINE_TYPE
00268 #undef COMBINE_UPDATE
00269 #undef COMBINE_FINISH
00270
00271
00272 inline double SurpriseModelSG::getMean() const
00273 { return itsMean; }
00274
00275
00276 inline double SurpriseModelSG::getVar() const
00277 { return itsVar; }
00278
00279
00280 inline double SurpriseModelSG::getUpdateFac() const
00281 { return itsUpdateFac; }
00282
00283
00284
00285
00286
00287
00288
00289 SurpriseModelSP::SurpriseModelSP(const double updatefac,
00290 const double sampleval,
00291 const double samplevar) :
00292 SurpriseModel(updatefac, sampleval, samplevar),
00293 itsN(1),
00294 itsAlpha(itsN * sampleval / (1.0 - updatefac)),
00295 itsBeta(itsN / (1.0 - updatefac))
00296 { }
00297
00298
00299 SurpriseModelSP::~SurpriseModelSP()
00300 { }
00301
00302
00303 inline void SurpriseModelSP::reset()
00304 { load(itsInitialVal, itsInitialVar); }
00305
00306
00307 inline void SurpriseModelSP::init(const double updfac,
00308 const double sampleval,
00309 const double samplevar)
00310 {
00311 SurpriseModel::init(updfac, sampleval, samplevar);
00312 load(sampleval, samplevar);
00313 }
00314
00315
00316 inline void SurpriseModelSP::load(const double sampleval,
00317 const double samplevar)
00318 {
00319 itsAlpha = itsN * sampleval / (1.0 - itsUpdateFac);
00320 itsBeta = itsN / (1.0 - itsUpdateFac);
00321 }
00322
00323
00324 inline double SurpriseModelSP::surprise(const SurpriseModelSP& sample)
00325 {
00326
00327 itsAlpha *= itsUpdateFac; itsBeta *= itsUpdateFac;
00328
00329
00330
00331 if (itsAlpha <= 0.0) itsAlpha = 0.0000001;
00332
00333
00334
00335 const double newAlpha = itsAlpha + itsN * sample.itsAlpha / sample.itsBeta;
00336 const double newBeta = itsBeta + itsN;
00337
00338
00339 const double s = KLgamma<double>(newAlpha,newBeta,itsAlpha,itsBeta,true);
00340
00341
00342 itsAlpha = newAlpha; itsBeta = newBeta;
00343
00344 return s;
00345 }
00346
00347
00348 inline void SurpriseModelSP::preComputeHyperParams(const SurpriseModelSP& sample)
00349 { LFATAL("Unimplemented in this model!"); }
00350
00351
00352 #define COMBINE_INIT itsAlpha = 0.0; itsBeta = 0.0;
00353 #define COMBINE_TYPE SurpriseModelSP
00354
00355
00356
00357 #define COMBINE_UPDATE \
00358 itsAlpha += weight * m->itsAlpha; \
00359 itsBeta += weight * m->itsBeta;
00360 #define COMBINE_FINISH \
00361 wsum = 1/wsum; \
00362 itsBeta *= wsum; \
00363 itsAlpha *= itsBeta * wsum;
00364
00365
00366 inline void SurpriseModelSP::combineFrom(const Image<SurpriseModelSP>& models,
00367 const Image<float>& weights)
00368 {
00369
00370
00371
00372 COMBINE_FROM(models,weights)
00373 }
00374
00375
00376 inline void SurpriseModelSP::combineFrom(const Image<SurpriseModelSP>& models,
00377 const Image<float>& weights,
00378 const Point2D<int>& pos,
00379 const int width,
00380 const int height,
00381 const int offset)
00382 {
00383
00384
00385
00386 COMBINE_FROM_WMIN(models,weights,pos,width,height,offset)
00387 }
00388
00389
00390
00391 #undef COMBINE_INIT
00392 #undef COMBINE_TYPE
00393 #undef COMBINE_UPDATE
00394 #undef COMBINE_FINISH
00395
00396
00397 inline double SurpriseModelSP::getMean() const
00398 { return itsAlpha / itsBeta; }
00399
00400
00401 inline double SurpriseModelSP::getVar() const
00402 { return itsAlpha / (itsBeta * itsBeta); }
00403
00404
00405 inline double SurpriseModelSP::getUpdateFac() const
00406 { return itsUpdateFac; }
00407
00408
00409 inline double SurpriseModelSP::getAlpha() const
00410 { return itsAlpha; }
00411
00412
00413 inline double SurpriseModelSP::getBeta() const
00414 { return itsBeta; }
00415
00416
00417 void SurpriseModelSP::preSetAlpha()
00418 {
00419 itsAlpha = itsAlpha/itsBeta;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428 SurpriseModelSP1::SurpriseModelSP1(const double updatefac,
00429 const double sampleval,
00430 const double samplevar) :
00431 SurpriseModel(updatefac, sampleval, samplevar),
00432 itsN(1),
00433 itsAlpha(itsN * sampleval / (1.0 - updatefac)),
00434 itsBeta(itsN / (1.0 - updatefac))
00435 { }
00436
00437
00438 SurpriseModelSP1::~SurpriseModelSP1()
00439 { }
00440
00441
00442 inline void SurpriseModelSP1::reset()
00443 { load(itsInitialVal, itsInitialVar); }
00444
00445
00446 inline void SurpriseModelSP1::init(const double updfac,
00447 const double sampleval,
00448 const double samplevar)
00449 {
00450 SurpriseModel::init(updfac, sampleval, samplevar);
00451 load(sampleval, samplevar);
00452 }
00453
00454
00455 inline void SurpriseModelSP1::load(const double sampleval,
00456 const double samplevar)
00457 {
00458 itsAlpha = itsN * sampleval / (1.0 - itsUpdateFac);
00459 itsBeta = itsN / (1.0 - itsUpdateFac);
00460 }
00461
00462
00463 inline double SurpriseModelSP1::surprise(const SurpriseModelSP1& sample)
00464 {
00465
00466
00467 if (itsAlpha <= 0.0) itsAlpha = 0.0000001;
00468
00469
00470
00471 const double newAlpha = itsAlpha * itsUpdateFac +
00472 itsN * sample.itsAlpha / sample.itsBeta;
00473 const double newBeta = itsBeta * itsUpdateFac +
00474 itsN;
00475
00476
00477 const double s = KLgamma<double>(newAlpha,newBeta,itsAlpha,itsBeta,true);
00478
00479
00480 itsAlpha = newAlpha; itsBeta = newBeta;
00481
00482 return s;
00483 }
00484
00485
00486 inline void SurpriseModelSP1::preComputeHyperParams(const SurpriseModelSP1& sample)
00487 { LFATAL("Unimplemented in this model!"); }
00488
00489
00490 #define COMBINE_INIT itsAlpha = 0.0; itsBeta = 0.0;
00491 #define COMBINE_TYPE SurpriseModelSP1
00492
00493
00494
00495 #define COMBINE_UPDATE \
00496 itsAlpha += weight * m->itsAlpha; \
00497 itsBeta += weight * m->itsBeta;
00498 #define COMBINE_FINISH \
00499 wsum = 1/wsum; \
00500 itsBeta *= wsum; \
00501 itsAlpha *= itsBeta * wsum;
00502
00503
00504 inline void SurpriseModelSP1::combineFrom(const Image<SurpriseModelSP1>& models,
00505 const Image<float>& weights)
00506 {
00507
00508
00509
00510 COMBINE_FROM(models,weights)
00511 }
00512
00513
00514 inline void SurpriseModelSP1::combineFrom(const Image<SurpriseModelSP1>& models,
00515 const Image<float>& weights,
00516 const Point2D<int>& pos,
00517 const int width,
00518 const int height,
00519 const int offset)
00520 {
00521
00522
00523
00524 COMBINE_FROM_WMIN(models,weights,pos,width,height,offset)
00525 }
00526
00527
00528
00529 #undef COMBINE_INIT
00530 #undef COMBINE_TYPE
00531 #undef COMBINE_UPDATE
00532 #undef COMBINE_FINISH
00533
00534
00535 inline double SurpriseModelSP1::getMean() const
00536 { return itsAlpha / itsBeta; }
00537
00538
00539 inline double SurpriseModelSP1::getVar() const
00540 { return itsAlpha / (itsBeta * itsBeta); }
00541
00542
00543 inline double SurpriseModelSP1::getUpdateFac() const
00544 { return itsUpdateFac; }
00545
00546
00547 inline double SurpriseModelSP1::getAlpha() const
00548 { return itsAlpha; }
00549
00550
00551 inline double SurpriseModelSP1::getBeta() const
00552 { return itsBeta; }
00553
00554
00555 void SurpriseModelSP1::preSetAlpha()
00556 {
00557 itsAlpha = itsAlpha/itsBeta;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566 SurpriseModelSPC::SurpriseModelSPC(const double updatefac,
00567 const double sampleval,
00568 const double samplevar) :
00569 SurpriseModel(updatefac, sampleval, samplevar),
00570 itsN(1),
00571 itsAlpha(itsN * sampleval / (1.0 - updatefac)),
00572 itsBeta(M_PI)
00573 { }
00574
00575
00576 SurpriseModelSPC::~SurpriseModelSPC()
00577 { }
00578
00579
00580 inline void SurpriseModelSPC::reset()
00581 { load(itsInitialVal, itsInitialVar); }
00582
00583
00584 inline void SurpriseModelSPC::init(const double updfac,
00585 const double sampleval,
00586 const double samplevar)
00587 {
00588 SurpriseModel::init(updfac, sampleval, samplevar);
00589 load(sampleval, samplevar);
00590 }
00591
00592
00593 inline void SurpriseModelSPC::load(const double sampleval,
00594 const double samplevar)
00595 {
00596 itsAlpha = itsN * sampleval / (1.0 - itsUpdateFac);
00597 itsBeta = M_PI;
00598 }
00599
00600
00601 inline double SurpriseModelSPC::surprise(const SurpriseModelSPC& sample)
00602 {
00603
00604 itsAlpha *= itsUpdateFac;
00605
00606
00607
00608 if (itsAlpha <= 0.0) itsAlpha = 0.0000001;
00609
00610
00611
00612 const double newAlpha = itsAlpha + itsN * sample.itsAlpha / sample.itsBeta;
00613
00614
00615 static const double itsC1 = D_SQRT_2/2.0F - 1.0F;
00616 static const double itsC2 = D_LOG_SQRT_2;
00617
00618 const double s = KLgammaConst<double>(newAlpha,itsAlpha,itsC1,itsC2,true);
00619
00620
00621 itsAlpha = newAlpha;
00622
00623 return s;
00624 }
00625
00626
00627 inline void SurpriseModelSPC::preComputeHyperParams(const SurpriseModelSPC& sample)
00628 { LFATAL("Unimplemented in this model!"); }
00629
00630
00631 #define COMBINE_INIT itsAlpha = 0.0; itsBeta = 0.0;
00632 #define COMBINE_TYPE SurpriseModelSPC
00633
00634
00635
00636 #define COMBINE_UPDATE \
00637 itsAlpha += weight * m->itsAlpha; \
00638 itsBeta += weight * m->itsBeta;
00639 #define COMBINE_FINISH \
00640 wsum = 1/wsum; \
00641 itsBeta *= wsum; \
00642 itsAlpha *= itsBeta * wsum;
00643
00644
00645 inline void SurpriseModelSPC::combineFrom(const Image<SurpriseModelSPC>& models,
00646 const Image<float>& weights)
00647 {
00648
00649
00650
00651 COMBINE_FROM(models,weights)
00652 }
00653
00654
00655 inline void SurpriseModelSPC::combineFrom(const Image<SurpriseModelSPC>& models,
00656 const Image<float>& weights,
00657 const Point2D<int>& pos,
00658 const int width,
00659 const int height,
00660 const int offset)
00661 {
00662
00663
00664
00665 COMBINE_FROM_WMIN(models,weights,pos,width,height,offset)
00666 }
00667
00668
00669
00670 #undef COMBINE_INIT
00671 #undef COMBINE_TYPE
00672 #undef COMBINE_UPDATE
00673 #undef COMBINE_FINISH
00674
00675
00676 inline double SurpriseModelSPC::getMean() const
00677 { return itsAlpha / itsBeta; }
00678
00679
00680 inline double SurpriseModelSPC::getVar() const
00681 { return itsAlpha / (itsBeta * itsBeta); }
00682
00683
00684 inline double SurpriseModelSPC::getUpdateFac() const
00685 { return itsUpdateFac; }
00686
00687
00688 inline double SurpriseModelSPC::getAlpha() const
00689 { return itsAlpha; }
00690
00691
00692 inline double SurpriseModelSPC::getBeta() const
00693 { return itsBeta; }
00694
00695
00696 void SurpriseModelSPC::preSetAlpha()
00697 {
00698 itsAlpha = itsAlpha/itsBeta;
00699 }
00700
00701
00702
00703
00704
00705
00706 SurpriseModelSPF::SurpriseModelSPF(const double updatefac,
00707 const double sampleval,
00708 const double samplevar) :
00709 SurpriseModel(updatefac, sampleval, samplevar),
00710 itsN(1),
00711 itsAlpha(itsN * sampleval / (1.0 - updatefac)),
00712 itsBeta(itsN / (1.0 - updatefac))
00713 { }
00714
00715
00716 SurpriseModelSPF::~SurpriseModelSPF()
00717 { }
00718
00719
00720 inline void SurpriseModelSPF::reset()
00721 { load(itsInitialVal, itsInitialVar); }
00722
00723
00724 inline void SurpriseModelSPF::init(const double updfac,
00725 const double sampleval,
00726 const double samplevar)
00727 {
00728 SurpriseModel::init(updfac, sampleval, samplevar);
00729 load(sampleval, samplevar);
00730 }
00731
00732
00733 inline void SurpriseModelSPF::load(const double sampleval,
00734 const double samplevar)
00735 {
00736 itsAlpha = itsN * sampleval / (1.0 - itsUpdateFac);
00737 itsBeta = itsN / (1.0 - itsUpdateFac);
00738 }
00739
00740
00741 inline double SurpriseModelSPF::surprise(const SurpriseModelSPF& sample)
00742 {
00743
00744 itsAlpha *= itsUpdateFac; itsBeta *= itsUpdateFac;
00745
00746
00747
00748 if (itsAlpha <= 0.0) itsAlpha = 0.0000001;
00749
00750
00751
00752 const double newAlpha = itsAlpha + itsN * sample.itsAlpha / sample.itsBeta;
00753 const double newBeta = itsN * sample.itsAlpha / itsAlpha;
00754
00755
00756 const double s = KLgamma<double>(newAlpha,newBeta,itsAlpha,itsBeta,true);
00757
00758
00759 itsAlpha = newAlpha; itsBeta = newBeta;
00760
00761 return s;
00762 }
00763
00764
00765 inline void SurpriseModelSPF::preComputeHyperParams(const SurpriseModelSPF& sample)
00766 { LFATAL("Unimplemented in this model!"); }
00767
00768
00769 #define COMBINE_INIT itsAlpha = 0.0; itsBeta = 0.0;
00770 #define COMBINE_TYPE SurpriseModelSPF
00771
00772
00773
00774 #define COMBINE_UPDATE \
00775 itsAlpha += weight * m->itsAlpha; \
00776 itsBeta += weight * m->itsBeta;
00777 #define COMBINE_FINISH \
00778 wsum = 1/wsum; \
00779 itsBeta *= wsum; \
00780 itsAlpha *= itsBeta * wsum;
00781
00782
00783 inline void SurpriseModelSPF::combineFrom(const Image<SurpriseModelSPF>& models,
00784 const Image<float>& weights)
00785 {
00786
00787
00788
00789 COMBINE_FROM(models,weights)
00790 }
00791
00792
00793 inline void SurpriseModelSPF::combineFrom(const Image<SurpriseModelSPF>& models,
00794 const Image<float>& weights,
00795 const Point2D<int>& pos,
00796 const int width,
00797 const int height,
00798 const int offset)
00799 {
00800
00801
00802
00803 COMBINE_FROM_WMIN(models,weights,pos,width,height,offset)
00804 }
00805
00806
00807
00808 #undef COMBINE_INIT
00809 #undef COMBINE_TYPE
00810 #undef COMBINE_UPDATE
00811 #undef COMBINE_FINISH
00812
00813
00814 inline double SurpriseModelSPF::getMean() const
00815 { return itsAlpha / itsBeta; }
00816
00817
00818 inline double SurpriseModelSPF::getVar() const
00819 { return itsAlpha / (itsBeta * itsBeta); }
00820
00821
00822 inline double SurpriseModelSPF::getUpdateFac() const
00823 { return itsUpdateFac; }
00824
00825
00826 inline double SurpriseModelSPF::getAlpha() const
00827 { return itsAlpha; }
00828
00829
00830 inline double SurpriseModelSPF::getBeta() const
00831 { return itsBeta; }
00832
00833
00834 void SurpriseModelSPF::preSetAlpha()
00835 {
00836 itsAlpha = itsAlpha/itsBeta;
00837 }
00838
00839
00840
00841
00842
00843
00844
00845 SurpriseModelCS::SurpriseModelCS(const double updatefac,
00846 const double sampleval,
00847 const double samplevar) :
00848 SurpriseModel(updatefac, sampleval, samplevar),
00849 itsN(1),
00850 itsAlpha(itsN * sampleval / (1.0 - updatefac)),
00851 itsBeta(0.5)
00852 { }
00853
00854
00855 SurpriseModelCS::~SurpriseModelCS()
00856 { }
00857
00858
00859 inline void SurpriseModelCS::reset()
00860 { load(itsInitialVal, itsInitialVar); }
00861
00862
00863 inline void SurpriseModelCS::init(const double updfac,
00864 const double sampleval,
00865 const double samplevar)
00866 {
00867 SurpriseModel::init(updfac, sampleval, samplevar);
00868 load(sampleval, samplevar);
00869 }
00870
00871
00872 inline void SurpriseModelCS::load(const double sampleval,
00873 const double samplevar)
00874 {
00875 itsAlpha = itsN * sampleval / (1.0 - itsUpdateFac);
00876 itsBeta = 0.5;
00877 }
00878
00879
00880 inline double SurpriseModelCS::surprise(const SurpriseModelCS& sample)
00881 {
00882
00883 itsAlpha *= itsUpdateFac;
00884
00885
00886
00887 if (itsAlpha <= 0.0) itsAlpha = 0.0000001;
00888
00889
00890
00891 const double newAlpha = itsAlpha + itsN * sample.itsAlpha / sample.itsBeta;
00892
00893
00894 const double s = KLgamma<double>(newAlpha,itsAlpha,true);
00895
00896
00897 itsAlpha = newAlpha;
00898
00899 return s;
00900 }
00901
00902
00903 inline void SurpriseModelCS::preComputeHyperParams(const SurpriseModelCS& sample)
00904 { LFATAL("Unimplemented in this model!"); }
00905
00906
00907 #define COMBINE_INIT itsAlpha = 0.0; itsBeta = 0.0;
00908 #define COMBINE_TYPE SurpriseModelCS
00909
00910
00911
00912 #define COMBINE_UPDATE \
00913 itsAlpha += weight * m->itsAlpha/m->itsBeta;
00914 #define COMBINE_FINISH \
00915 wsum = 1/wsum; \
00916 itsAlpha *= itsBeta * wsum;
00917
00918
00919 inline void SurpriseModelCS::combineFrom(const Image<SurpriseModelCS>& models,
00920 const Image<float>& weights)
00921 {
00922
00923
00924
00925 COMBINE_FROM(models,weights)
00926 }
00927
00928
00929 inline void SurpriseModelCS::combineFrom(const Image<SurpriseModelCS>& models,
00930 const Image<float>& weights,
00931 const Point2D<int>& pos,
00932 const int width,
00933 const int height,
00934 const int offset)
00935 {
00936
00937
00938
00939 COMBINE_FROM_WMIN(models,weights,pos,width,height,offset)
00940 }
00941
00942
00943
00944 #undef COMBINE_INIT
00945 #undef COMBINE_TYPE
00946 #undef COMBINE_UPDATE
00947 #undef COMBINE_FINISH
00948
00949
00950 inline double SurpriseModelCS::getMean() const
00951 { return itsAlpha / itsBeta; }
00952
00953
00954 inline double SurpriseModelCS::getVar() const
00955 { return itsAlpha / (itsBeta * itsBeta); }
00956
00957
00958 inline double SurpriseModelCS::getUpdateFac() const
00959 { return itsUpdateFac; }
00960
00961
00962 inline double SurpriseModelCS::getAlpha() const
00963 { return itsAlpha; }
00964
00965
00966 inline double SurpriseModelCS::getBeta() const
00967 { return itsBeta; }
00968
00969
00970 void SurpriseModelCS::preSetAlpha()
00971 {
00972 itsAlpha = itsAlpha/itsBeta;
00973 }
00974
00975
00976
00977
00978
00979
00980
00981 SurpriseModelGG::SurpriseModelGG(const double updatefac,
00982 const double sampleval,
00983 const double samplevar) :
00984 SurpriseModel(updatefac, sampleval, samplevar),
00985 itsCombineFromRun(false),
00986 itsN(1),
00987 itsJointKLBiasType(SU_KL_STATIC),
00988 itsAlpha(itsN * sampleval / (1.0 - updatefac)),
00989 itsBeta(itsN / (1.0 - updatefac)),
00990 itsSLfac(1.0f),
00991 itsSSfac(1.0f)
00992
00993 { }
00994
00995
00996 SurpriseModelGG::~SurpriseModelGG()
00997 { }
00998
00999
01000 inline void SurpriseModelGG::reset()
01001 { load(itsInitialVal, itsInitialVar); }
01002
01003
01004 inline void SurpriseModelGG::init(const double updfac,
01005 const double sampleval,
01006 const double samplevar)
01007 {
01008 SurpriseModel::init(updfac, sampleval, samplevar);
01009 load(sampleval, samplevar);
01010 }
01011
01012
01013 inline void SurpriseModelGG::load(const double sampleval,
01014 const double samplevar)
01015 {
01016 itsAlpha = itsN * sampleval / (1.0 - itsUpdateFac);
01017 itsBeta = itsN / (1.0 - itsUpdateFac);
01018 }
01019
01020
01021 inline double SurpriseModelGG::surprise(const SurpriseModelGG& sample)
01022 {
01023 ASSERT(itsCombineFromRun);
01024
01025 itsAlpha *= itsUpdateFac; itsBeta *= itsUpdateFac;
01026
01027
01028
01029 if (itsAlpha <= 0.0) itsAlpha = 0.0000001;
01030
01031
01032
01033
01034
01035 const double newAlpha = itsAlpha + itsN * sample.itsAlpha / sample.itsBeta;
01036 const double newBeta = itsBeta + itsN;
01037
01038
01039
01040
01041 const double newExp = sample.itsAlpha / sample.itsBeta;
01042 const double newMean = (itsSum + newExp)/(itsWeightSum + 1);
01043
01044
01045 const double newSS = (newExp*newExp + itsSS)/(itsWeightSum + 1);
01046 const double newVar = newSS - newMean * newMean;
01047
01048
01049 itsSig = sqrt(itsVar);
01050 const double newSig = sqrt(newVar);
01051
01052 double s = 0.0000001;
01053
01054
01055 if(itsSig > 0.0 && newSig > 0.0)
01056 {
01057
01058
01059
01060 if(itsJointKLBiasType == SU_KL_NONE)
01061 s = KLjointGammaGauss<double>(newAlpha, newMean,
01062 newBeta, newSig,
01063 itsAlpha, itsMean,
01064 itsBeta, itsSig,
01065 true);
01066 else if(itsJointKLBiasType == SU_KL_STATIC)
01067 s = KLjointGammaGauss<double>(newAlpha, newMean,
01068 newBeta, newSig,
01069 itsAlpha, itsMean,
01070 itsBeta, itsSig,
01071 true,
01072 itsSLfac,
01073 itsSSfac);
01074 else
01075 LERROR("Invalid bias type %d given for KL bias",itsJointKLBiasType);
01076 }
01077
01078
01079
01080
01081
01082
01083
01084 itsAlpha = newAlpha; itsBeta = newBeta;
01085
01086
01087 itsCombineFromRun = false;
01088
01089 return s;
01090 }
01091
01092
01093 inline void SurpriseModelGG::preComputeHyperParams(const SurpriseModelGG& sample)
01094 { LFATAL("Unimplemented in this model!"); }
01095
01096
01097 #define COMBINE_INIT itsMean = 0.0; itsVar = 0.0;
01098 #define COMBINE_TYPE SurpriseModelGG
01099
01100
01101
01102
01103 #define COMBINE_UPDATE \
01104 const double expVal = m->itsAlpha / m->itsBeta; \
01105 itsMean += weight * expVal; \
01106 itsVar += weight * expVal * expVal;
01107 #define COMBINE_FINISH \
01108 itsSum = itsMean; \
01109 itsSS = itsVar; \
01110 itsWeightSum = wsum; \
01111 itsMean /= wsum; itsVar /= wsum; \
01112 itsVar -= itsMean * itsMean; \
01113 itsCombineFromRun = true;
01114
01115
01116 inline void SurpriseModelGG::combineFrom(const Image<SurpriseModelGG>& models,
01117 const Image<float>& weights)
01118 {
01119
01120
01121
01122 COMBINE_FROM(models,weights)
01123 }
01124
01125
01126 inline void SurpriseModelGG::combineFrom(const Image<SurpriseModelGG>& models,
01127 const Image<float>& weights,
01128 const Point2D<int>& pos,
01129 const int width,
01130 const int height,
01131 const int offset)
01132 {
01133
01134
01135
01136 COMBINE_FROM_WMIN(models,weights,pos,width,height,offset)
01137 }
01138
01139
01140
01141 #undef COMBINE_INIT
01142 #undef COMBINE_TYPE
01143 #undef COMBINE_UPDATE
01144 #undef COMBINE_FINISH
01145
01146
01147 inline double SurpriseModelGG::getMean() const
01148 { return itsAlpha / itsBeta; }
01149
01150
01151 inline double SurpriseModelGG::getVar() const
01152 { return itsAlpha / (itsBeta * itsBeta); }
01153
01154
01155 inline double SurpriseModelGG::getUpdateFac() const
01156 { return itsUpdateFac; }
01157
01158
01159 inline double SurpriseModelGG::getAlpha() const
01160 { return itsAlpha; }
01161
01162
01163 inline double SurpriseModelGG::getBeta() const
01164 { return itsBeta; }
01165
01166
01167 void SurpriseModelGG::setBias(const double slfac,
01168 const double ssfac,
01169 const SU_KL_BIAS klbias)
01170 {
01171 itsSLfac = slfac;
01172 itsSSfac = ssfac;
01173 itsJointKLBiasType = klbias;
01174 }
01175
01176
01177
01178
01179 SurpriseModelPM::SurpriseModelPM(const double updatefac,
01180 const double sampleval,
01181 const double samplevar) :
01182 SurpriseModel(updatefac, sampleval, samplevar),
01183 itsN(1),
01184 itsSample(itsN * sampleval / (1.0 - updatefac)),
01185 itsBeta0(1)
01186
01187 {
01188 itsAlpha0 = itsSample;
01189 itsAlpha1 = itsSample;
01190 itsAlpha2 = itsSample;
01191 itsBeta1 = itsBeta0;
01192 itsBeta2 = itsBeta0;
01193 itsInitBeta = itsBeta0;
01194 itsExpectAlpha1 = 1;
01195 itsExpectAlpha2 = 1;
01196 itsXBar1 = 0;
01197 itsXBar2 = 0;
01198 }
01199
01200
01201 SurpriseModelPM::~SurpriseModelPM()
01202 { }
01203
01204
01205 inline void SurpriseModelPM::reset()
01206 { load(itsInitialVal, itsInitialVar); }
01207
01208
01209 inline void SurpriseModelPM::init(const double updfac,
01210 const double sampleval,
01211 const double samplevar)
01212 {
01213 SurpriseModel::init(updfac, sampleval, samplevar);
01214 load(sampleval, samplevar);
01215 }
01216
01217
01218 inline void SurpriseModelPM::load(const double sampleval,
01219 const double samplevar)
01220 {
01221 itsSample = sampleval;
01222 }
01223
01224
01225 inline double SurpriseModelPM::surprise(const SurpriseModelPM& sample)
01226 {
01227
01228
01229 if (itsAlpha1 <= 0.0) itsAlpha1 = 0.0000001;
01230 if (itsAlpha2 <= 0.0) itsAlpha2 = 0.0000001;
01231
01232
01233 return KLgamma<double>(itsAlpha2,itsBeta2,itsAlpha1,itsBeta1,true);
01234 }
01235
01236
01237 inline void SurpriseModelPM::preComputeHyperParams(const SurpriseModelPM& sample)
01238 {
01239
01240
01241
01242
01243 itsAlpha0 = itsAlpha1;
01244 itsAlpha1 = itsAlpha2;
01245
01246 const double alphaUpdate0 = itsAlpha0 * itsUpdateFac;
01247 const double alphaUpdate1 = itsAlpha1 * itsUpdateFac;
01248
01249 const double data = sample.itsSample / itsBeta2;
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 itsAlpha2 = alphaUpdate1 + data;
01261
01262
01263 itsLgamma1 = itsLgamma2;
01264 itsLgamma2 = lgamma(itsAlpha2);
01265
01266 itsBeta1 = itsBeta2;
01267
01268 itsExpectAlpha1 = alphaUpdate0 + itsXBar1;
01269 itsExpectAlpha2 = alphaUpdate1 + itsXBar2;
01270
01271 itsXBar2 = (sample.itsSample + itsXBar1*itsUpdateFac) /
01272 (1 + itsUpdateFac);
01273 itsXBar1 = itsXBar2;
01274 }
01275
01276
01277 inline void SurpriseModelPM::combineFrom(const Image<SurpriseModelPM>& models,
01278 const Image<float>& weights)
01279 {
01280 LFATAL("This method not supported for this type of object");
01281 }
01282
01283
01284 inline void SurpriseModelPM::combineFrom(const Image<SurpriseModelPM>& models,
01285 const Image<float>& weights,
01286 const Point2D<int>& pos,
01287 const int width,
01288 const int height,
01289 const int offset)
01290 {
01291 ASSERT(weights.getWidth() == 2 * width + 1);
01292 ASSERT(weights.getHeight() == 2 * height + 1);
01293 ASSERT(models.coordsOk(pos));
01294
01295
01296
01297
01298 double wsum = 0.0F;
01299 double cov = 0.0F;
01300 Image<SurpriseModelPM>::const_iterator m = models.begin();
01301 Image<float>::const_iterator w = weights.begin();
01302
01303
01304 w += offset - pos.i;
01305 if((itsExpectAlpha2 != 0) && (itsExpectAlpha1 != 0))
01306 {
01307 for (ushort j = 0; j < height; j++)
01308 {
01309 for (ushort i = 0; i < width; i++)
01310 {
01311 const double weight = *w++;
01312 if (weight)
01313 {
01314
01315
01316
01317 const double aRatio2 = m->itsExpectAlpha2 / itsExpectAlpha2;
01318 const double aRatio1 = m->itsExpectAlpha1 / itsExpectAlpha1;
01319 const double ratDiff = aRatio2 - aRatio1;
01320 cov += (weight * ratDiff) * itsAlpha1;
01321 wsum += weight;
01322 }
01323 ++m;
01324 }
01325
01326 w += width + 1;
01327 }
01328 }
01329 else
01330 {
01331 cov = itsAlpha2; wsum = 1;
01332 }
01333 const double combinedAlpha2 = cov / wsum;
01334 const double ratio = combinedAlpha2 / itsAlpha2;
01335
01336
01337
01338
01339
01340 if((itsAlpha2 != 0) && (ratio != 0))
01341 {
01342
01343
01344 itsBeta2 = itsInitBeta * ((ratio * itsBeta1 * itsUpdateFac) + 1);
01345
01346
01347
01348
01349
01350 }
01351 else
01352 itsBeta2 = itsBeta1 * itsUpdateFac + 1;
01353
01354 }
01355
01356
01357 inline double SurpriseModelPM::getMean() const
01358 { return itsAlpha2 / itsBeta2; }
01359
01360
01361 inline double SurpriseModelPM::getVar() const
01362 { return itsAlpha2 / (itsBeta2 * itsBeta2); }
01363
01364
01365 inline double SurpriseModelPM::getUpdateFac() const
01366 { return itsUpdateFac; }
01367
01368
01369
01370
01371 SurpriseModelOD::SurpriseModelOD(const double updatefac,
01372 const double sampleval,
01373 const double samplevar) :
01374 SurpriseModel(updatefac, sampleval, samplevar),
01375 itsN(1),
01376 itsLambda(sampleval)
01377 { }
01378
01379
01380 SurpriseModelOD::~SurpriseModelOD()
01381 { }
01382
01383
01384 inline void SurpriseModelOD::reset()
01385 { load(itsInitialVal, itsInitialVar); }
01386
01387
01388 inline void SurpriseModelOD::init(const double updfac,
01389 const double sampleval,
01390 const double samplevar)
01391 {
01392 SurpriseModel::init(updfac, sampleval, samplevar);
01393 load(sampleval, samplevar);
01394 }
01395
01396
01397 inline void SurpriseModelOD::load(const double sampleval,
01398 const double samplevar)
01399 {
01400 itsLambda = sampleval;
01401 }
01402
01403
01404 inline double SurpriseModelOD::surprise(const SurpriseModelOD& sample)
01405 {
01406
01407 double ret = poisson(int(sample.itsLambda+0.4999), itsLambda);
01408
01409
01410 itsLambda = itsLambda + itsUpdateFac * (sample.itsLambda - itsLambda);
01411
01412
01413 ret = 1.0 / (ret + 1.0e-5) - 1.0;
01414 if (ret < 0.0) ret = 0.0;
01415
01416 return ret * 0.00001;
01417 }
01418
01419
01420 inline void SurpriseModelOD::preComputeHyperParams(const SurpriseModelOD& sample)
01421 { LFATAL("Unimplemented in this model!"); }
01422
01423
01424 inline void SurpriseModelOD::combineFrom(const Image<SurpriseModelOD>&
01425 models, const Image<float>& weights)
01426 {
01427 ASSERT(models.isSameSize(weights));
01428
01429
01430 itsLambda = 0.0;
01431 Image<SurpriseModelOD>::const_iterator m = models.begin(),
01432 stop = models.end();
01433 double wsum = 0.0;
01434 Image<float>::const_iterator w = weights.begin();
01435 while(m != stop)
01436 {
01437 const double weight = double(*w++);
01438 itsLambda += weight * m->itsLambda;
01439 wsum += weight;
01440 ++m;
01441 }
01442 }
01443
01444
01445 inline void SurpriseModelOD::combineFrom(const Image<SurpriseModelOD>&
01446 models, const Image<float>& weights,
01447 const Point2D<int>& pos,
01448 const int width,
01449 const int height,
01450 const int offset)
01451 {
01452 ASSERT(weights.getWidth() == 2 * width + 1);
01453 ASSERT(weights.getHeight() == 2 * height + 1);
01454 ASSERT(models.coordsOk(pos));
01455
01456
01457 itsLambda = 0.0;
01458 Image<SurpriseModelOD>::const_iterator m = models.begin();
01459 Image<float>::const_iterator w = weights.begin();
01460 double wsum = 0.0;
01461
01462
01463 w += offset - pos.i;
01464 for (int j = 0; j < height; j ++)
01465 {
01466 for (int i = 0; i < width; i ++)
01467 {
01468 const double weight = double(*w++);
01469 if (weight)
01470 {
01471 itsLambda += weight * m->itsLambda;
01472 wsum += weight;
01473 }
01474 ++m;
01475 }
01476
01477 w += width + 1;
01478 }
01479 }
01480
01481
01482 inline double SurpriseModelOD::getMean() const
01483 { return itsLambda; }
01484
01485
01486 inline double SurpriseModelOD::getVar() const
01487 { return itsLambda; }
01488
01489
01490 inline double SurpriseModelOD::getUpdateFac() const
01491 { return itsUpdateFac; }
01492
01493
01494
01495
01496
01497