... | ... |
@@ -70,9 +70,8 @@ protected: |
70 | 70 |
void acceptExchange(AtomicProposal *prop, float d1, unsigned r1, |
71 | 71 |
unsigned c1, unsigned r2, unsigned c2); |
72 | 72 |
|
73 |
- std::pair<float, bool> gibbsMass(AlphaParameters alpha, GapsRng *rng); |
|
74 |
- std::pair<float, bool> gibbsMass(AlphaParameters alpha, float m1, float m2, |
|
75 |
- GapsRng *rng); |
|
73 |
+ OptionalFloat gibbsMass(AlphaParameters alpha, GapsRng *rng); |
|
74 |
+ OptionalFloat gibbsMass(AlphaParameters alpha, float m1, float m2, GapsRng *rng); |
|
76 | 75 |
|
77 | 76 |
public: |
78 | 77 |
|
... | ... |
@@ -346,7 +345,7 @@ void GibbsSampler<T, MatA, MatB>::birth(AtomicProposal *prop) |
346 | 345 |
if (impl()->canUseGibbs(row, col)) |
347 | 346 |
{ |
348 | 347 |
AlphaParameters alpha = impl()->alphaParameters(row, col); |
349 |
- mass = gibbsMass(alpha, &(prop->rng)).first; |
|
348 |
+ mass = gibbsMass(alpha, &(prop->rng)).value; // 0 if it fails |
|
350 | 349 |
} |
351 | 350 |
else |
352 | 351 |
{ |
... | ... |
@@ -386,10 +385,10 @@ void GibbsSampler<T, MatA, MatB>::death(AtomicProposal *prop) |
386 | 385 |
AlphaParameters alpha = impl()->alphaParameters(row, col); |
387 | 386 |
if (impl()->canUseGibbs(row, col)) |
388 | 387 |
{ |
389 |
- std::pair<float, bool> gMass = gibbsMass(alpha, &(prop->rng)); |
|
390 |
- if (gMass.second) |
|
388 |
+ OptionalFloat gMass = gibbsMass(alpha, &(prop->rng)); |
|
389 |
+ if (gMass.hasValue) |
|
391 | 390 |
{ |
392 |
- rebirthMass = gMass.first; |
|
391 |
+ rebirthMass = gMass.value; |
|
393 | 392 |
} |
394 | 393 |
} |
395 | 394 |
|
... | ... |
@@ -454,16 +453,15 @@ void GibbsSampler<T, MatA, MatB>::exchange(AtomicProposal *prop) |
454 | 453 |
if (impl()->canUseGibbs(r1, c1, r2, c2)) |
455 | 454 |
{ |
456 | 455 |
AlphaParameters alpha = impl()->alphaParameters(r1, c1, r2, c2); |
457 |
- std::pair<float, bool> gMass = gibbsMass(alpha, m1, m2, &(prop->rng)); |
|
458 |
- if (gMass.second) |
|
456 |
+ OptionalFloat gMass = gibbsMass(alpha, m1, m2, &(prop->rng)); |
|
457 |
+ if (gMass.hasValue) |
|
459 | 458 |
{ |
460 |
- acceptExchange(prop, gMass.first, r1, c1, r2, c2); |
|
459 |
+ acceptExchange(prop, gMass.value, r1, c1, r2, c2); |
|
461 | 460 |
return; |
462 | 461 |
} |
463 | 462 |
} |
464 | 463 |
|
465 |
- float pUpper = gaps::p_gamma(m1 + m2, 2.f, 1.f / mLambda); |
|
466 |
- float newMass = prop->rng.inverseGammaSample(0.f, pUpper, 2.f, 1.f / mLambda); |
|
464 |
+ float newMass = prop->rng.truncGammaUpper(m1 + m2, 2.f, 1.f / mLambda); |
|
467 | 465 |
|
468 | 466 |
float delta = m1 > m2 ? newMass - m1 : m2 - newMass; // change larger mass |
469 | 467 |
float pOldMass = 2.f * newMass > m1 + m2 ? gaps::max(m1, m2) : gaps::min(m1, m2); |
... | ... |
@@ -537,7 +535,7 @@ float d1, unsigned r1, unsigned c1, unsigned r2, unsigned c2) |
537 | 535 |
} |
538 | 536 |
|
539 | 537 |
template <class T, class MatA, class MatB> |
540 |
-std::pair<float, bool> GibbsSampler<T, MatA, MatB>::gibbsMass(AlphaParameters alpha, |
|
538 |
+OptionalFloat GibbsSampler<T, MatA, MatB>::gibbsMass(AlphaParameters alpha, |
|
541 | 539 |
GapsRng *rng) |
542 | 540 |
{ |
543 | 541 |
alpha.s *= mAnnealingTemp; |
... | ... |
@@ -553,14 +551,17 @@ GapsRng *rng) |
553 | 551 |
{ |
554 | 552 |
float m = rng->inverseNormSample(pLower, 1.f, mean, sd); |
555 | 553 |
float gMass = gaps::min(m, mMaxGibbsMass / mLambda); |
556 |
- return std::pair<float, bool>(gMass, gMass >= gaps::epsilon); |
|
554 |
+ if (gMass >= gaps::epsilon) |
|
555 |
+ { |
|
556 |
+ return OptionalFloat(gMass); |
|
557 |
+ } |
|
557 | 558 |
} |
558 | 559 |
} |
559 |
- return std::pair<float, bool>(0.f, false); |
|
560 |
+ return OptionalFloat(); |
|
560 | 561 |
} |
561 | 562 |
|
562 | 563 |
template <class T, class MatA, class MatB> |
563 |
-std::pair<float, bool> GibbsSampler<T, MatA, MatB>::gibbsMass(AlphaParameters alpha, |
|
564 |
+OptionalFloat GibbsSampler<T, MatA, MatB>::gibbsMass(AlphaParameters alpha, |
|
564 | 565 |
float m1, float m2, GapsRng *rng) |
565 | 566 |
{ |
566 | 567 |
alpha.s *= mAnnealingTemp; |
... | ... |
@@ -576,11 +577,11 @@ float m1, float m2, GapsRng *rng) |
576 | 577 |
if (!(pLower > 0.95f || pUpper < 0.05f)) |
577 | 578 |
{ |
578 | 579 |
float delta = rng->inverseNormSample(pLower, pUpper, mean, sd); |
579 |
- float gibbsMass = gaps::min(gaps::max(-m1, delta), m2); // conserve mass |
|
580 |
- return std::pair<float, bool>(gibbsMass, true); |
|
580 |
+ float gMass = gaps::min(gaps::max(-m1, delta), m2); // conserve mass |
|
581 |
+ return OptionalFloat(gMass); |
|
581 | 582 |
} |
582 | 583 |
} |
583 |
- return std::pair<float, bool>(0.f, false); |
|
584 |
+ return OptionalFloat(); |
|
584 | 585 |
} |
585 | 586 |
|
586 | 587 |
#ifdef GAPS_DEBUG |
... | ... |
@@ -8,8 +8,8 @@ |
8 | 8 |
namespace gaps |
9 | 9 |
{ |
10 | 10 |
const float epsilon = 1.0e-10f; |
11 |
- const float pi = 3.14159265358979323846264f; |
|
12 |
- const float pi_double = 3.14159265358979323846264; |
|
11 |
+ const float pi = 3.1415926535897932384626433832795f; |
|
12 |
+ const float pi_double = 3.1415926535897932384626433832795; |
|
13 | 13 |
|
14 | 14 |
float min(float a, float b); |
15 | 15 |
unsigned min(unsigned a, unsigned b); |
... | ... |
@@ -237,14 +237,16 @@ float GapsRng::inverseNormSample(float a, float b, float mean, float sd) |
237 | 237 |
return gaps::q_norm(u, mean, sd); |
238 | 238 |
} |
239 | 239 |
|
240 |
-float GapsRng::inverseGammaSample(float a, float b, float mean, float sd) |
|
240 |
+float GapsRng::truncGammaUpper(float b, float shape, float scale) |
|
241 | 241 |
{ |
242 |
- float u = uniform(a, b); |
|
242 |
+ float upper = gaps::p_gamma(b, shape, scale); |
|
243 |
+ |
|
244 |
+ float u = uniform(0.f, upper); |
|
243 | 245 |
while (u == 0.f || u == 1.f) |
244 | 246 |
{ |
245 |
- u = uniform(a, b); |
|
247 |
+ u = uniform(0.f, upper); |
|
246 | 248 |
} |
247 |
- return gaps::q_gamma(u, mean, sd); |
|
249 |
+ return gaps::q_gamma(u, shape, scale); |
|
248 | 250 |
} |
249 | 251 |
|
250 | 252 |
Archive& operator<<(Archive &ar, GapsRng &gen) |
... | ... |
@@ -303,3 +305,9 @@ double gaps::lgamma(double x) |
303 | 305 |
{ |
304 | 306 |
return boost::math::lgamma(x); |
305 | 307 |
} |
308 |
+ |
|
309 |
+float gaps::d_norm_fast(float d, float mean, float sd) |
|
310 |
+{ |
|
311 |
+ return std::exp((d - mean) * (d - mean) / (-2.f * sd * sd)) |
|
312 |
+ / std::sqrt(2.f * gaps::pi * sd * sd); |
|
313 |
+} |
... | ... |
@@ -9,8 +9,8 @@ |
9 | 9 |
|
10 | 10 |
struct OptionalFloat |
11 | 11 |
{ |
12 |
- bool hasValue; |
|
13 | 12 |
float value; |
13 |
+ bool hasValue; |
|
14 | 14 |
|
15 | 15 |
OptionalFloat() : hasValue(false), value(0.f) {} |
16 | 16 |
OptionalFloat(float f) : hasValue(true), value(f) {} |
... | ... |
@@ -26,6 +26,13 @@ namespace gaps |
26 | 26 |
float d_norm(float d, float mean, float sd); |
27 | 27 |
float q_norm(float q, float mean, float sd); |
28 | 28 |
float p_norm(float p, float mean, float sd); |
29 |
+ |
|
30 |
+ float d_gamma_fast(float d, float shape, float scale); |
|
31 |
+ float p_gamma_fast(float p, float shape, float scale); |
|
32 |
+ float q_gamma_fast(float q, float shape, float scale); |
|
33 |
+ float d_norm_fast(float d, float mean, float sd); |
|
34 |
+ float p_norm_fast(float p, float mean, float sd); |
|
35 |
+ float q_norm_fast(float q, float mean, float sd); |
|
29 | 36 |
} |
30 | 37 |
|
31 | 38 |
// used for seeding individual rngs |
... | ... |
@@ -66,7 +73,7 @@ public: |
66 | 73 |
float exponential(float lambda); |
67 | 74 |
|
68 | 75 |
float inverseNormSample(float a, float b, float mean, float sd); |
69 |
- float inverseGammaSample(float a, float b, float mean, float sd); |
|
76 |
+ float truncGammaUpper(float b, float shape, float scale); |
|
70 | 77 |
|
71 | 78 |
static void setSeed(uint64_t seed); |
72 | 79 |
static void save(Archive &ar); |