... | ... |
@@ -1,6 +1,8 @@ |
1 | 1 |
#ifndef __COGAPS_ARCHIVE_H__ |
2 | 2 |
#define __COGAPS_ARCHIVE_H__ |
3 | 3 |
|
4 |
+#include "GapsAssert.h" |
|
5 |
+ |
|
4 | 6 |
#include <fstream> |
5 | 7 |
#include <stdint.h> |
6 | 8 |
|
... | ... |
@@ -9,8 +11,8 @@ |
9 | 11 |
#define ARCHIVE_WRITE (std::ios::out | std::ios::trunc) |
10 | 12 |
|
11 | 13 |
// magic number written to beginning of archive files |
12 |
-// needs to be updated everytime to method of checkpointing changes |
|
13 |
-#define ARCHIVE_MAGIC_NUM 0xCE45D32A |
|
14 |
+// needs to be updated everytime the method of checkpointing changes |
|
15 |
+#define ARCHIVE_MAGIC_NUM 0xCE45D32B // v3.3.22 |
|
14 | 16 |
|
15 | 17 |
class Archive |
16 | 18 |
{ |
... | ... |
@@ -21,10 +23,28 @@ private: |
21 | 23 |
public: |
22 | 24 |
|
23 | 25 |
Archive(const std::string &path, std::ios_base::openmode flags) |
24 |
- : mStream(path.c_str(), std::ios::binary | flags) |
|
25 |
- {} |
|
26 |
+ : |
|
27 |
+ mStream(path.c_str(), std::ios::binary | flags) |
|
28 |
+ { |
|
29 |
+ if (flags == ARCHIVE_WRITE) |
|
30 |
+ { |
|
31 |
+ *this << static_cast<uint32_t>(ARCHIVE_MAGIC_NUM); |
|
32 |
+ } |
|
33 |
+ else // read |
|
34 |
+ { |
|
35 |
+ uint32_t magic = 0; |
|
36 |
+ *this >> magic; |
|
37 |
+ if (magic != ARCHIVE_MAGIC_NUM) |
|
38 |
+ { |
|
39 |
+ GAPS_ERROR("incompatible checkpoint file\n"); |
|
40 |
+ } |
|
41 |
+ } |
|
42 |
+ } |
|
26 | 43 |
|
27 |
- void close() {mStream.close();} |
|
44 |
+ void close() |
|
45 |
+ { |
|
46 |
+ mStream.close(); |
|
47 |
+ } |
|
28 | 48 |
|
29 | 49 |
template<typename T> |
30 | 50 |
friend Archive& writeToArchive(Archive &ar, T val) |
... | ... |
@@ -3,6 +3,40 @@ |
3 | 3 |
|
4 | 4 |
#include <vector> |
5 | 5 |
|
6 |
+////////////////////////////////// HELPER ////////////////////////////////////// |
|
7 |
+ |
|
8 |
+// used with std::lower_bound |
|
9 |
+static bool compareAtomLower(const Atom &lhs, uint64_t pos) |
|
10 |
+{ |
|
11 |
+ return lhs.pos < pos; |
|
12 |
+} |
|
13 |
+ |
|
14 |
+// used with std::binary_search |
|
15 |
+static bool compareAtom(const Atom &lhs, const Atom &rhs) |
|
16 |
+{ |
|
17 |
+ return lhs.pos < rhs.pos; |
|
18 |
+} |
|
19 |
+ |
|
20 |
+// check if a position in contained in a vector of atoms |
|
21 |
+static bool vecContains(const std::vector<Atom> &vec, uint64_t pos) |
|
22 |
+{ |
|
23 |
+ Atom temp(pos, 0.f); |
|
24 |
+ return std::binary_search(vec.begin(), vec.end(), temp, compareAtom); |
|
25 |
+} |
|
26 |
+ |
|
27 |
+// used in debug mode to check if vector is always sorted |
|
28 |
+static bool isSorted(const std::vector<Atom> &vec) |
|
29 |
+{ |
|
30 |
+ for (unsigned i = 1; i < vec.size(); ++i) |
|
31 |
+ { |
|
32 |
+ if (vec[i].pos <= vec[i-1].pos) |
|
33 |
+ { |
|
34 |
+ return false; |
|
35 |
+ } |
|
36 |
+ } |
|
37 |
+ return true; |
|
38 |
+} |
|
39 |
+ |
|
6 | 40 |
////////////////////////////////// ATOM //////////////////////////////////////// |
7 | 41 |
|
8 | 42 |
Atom::Atom() : pos(0), mass(0.f) {} |
... | ... |
@@ -46,7 +80,7 @@ bool AtomNeighborhood::hasRight() |
46 | 80 |
|
47 | 81 |
////////////////////////////// ATOMIC DOMAIN /////////////////////////////////// |
48 | 82 |
|
49 |
-AtomicDomain::AtomicDomain(unsigned nBins) |
|
83 |
+AtomicDomain::AtomicDomain(uint64_t nBins) |
|
50 | 84 |
{ |
51 | 85 |
uint64_t binLength = std::numeric_limits<uint64_t>::max() / nBins; |
52 | 86 |
mDomainLength = binLength * nBins; |
... | ... |
@@ -55,12 +89,15 @@ AtomicDomain::AtomicDomain(unsigned nBins) |
55 | 89 |
Atom* AtomicDomain::front() |
56 | 90 |
{ |
57 | 91 |
GAPS_ASSERT(size() > 0); |
92 |
+ |
|
58 | 93 |
return &(mAtoms.front()); |
59 | 94 |
} |
60 | 95 |
|
61 | 96 |
Atom* AtomicDomain::randomAtom() |
62 | 97 |
{ |
63 | 98 |
GAPS_ASSERT(size() > 0); |
99 |
+ GAPS_ASSERT(isSorted(mAtoms)); |
|
100 |
+ |
|
64 | 101 |
unsigned index = mRng.uniform32(0, mAtoms.size() - 1); |
65 | 102 |
return &(mAtoms[index]); |
66 | 103 |
} |
... | ... |
@@ -68,6 +105,7 @@ Atom* AtomicDomain::randomAtom() |
68 | 105 |
AtomNeighborhood AtomicDomain::randomAtomWithNeighbors() |
69 | 106 |
{ |
70 | 107 |
GAPS_ASSERT(size() > 0); |
108 |
+ |
|
71 | 109 |
unsigned index = mRng.uniform32(0, mAtoms.size() - 1); |
72 | 110 |
Atom* left = (index == 0) ? NULL : &(mAtoms[index - 1]); |
73 | 111 |
Atom* right = (index == mAtoms.size() - 1) ? NULL : &(mAtoms[index + 1]); |
... | ... |
@@ -77,32 +115,12 @@ AtomNeighborhood AtomicDomain::randomAtomWithNeighbors() |
77 | 115 |
AtomNeighborhood AtomicDomain::randomAtomWithRightNeighbor() |
78 | 116 |
{ |
79 | 117 |
GAPS_ASSERT(size() > 0); |
118 |
+ |
|
80 | 119 |
unsigned index = mRng.uniform32(0, mAtoms.size() - 1); |
81 | 120 |
Atom* right = (index == mAtoms.size() - 1) ? NULL : &(mAtoms[index + 1]); |
82 | 121 |
return AtomNeighborhood(NULL, &(mAtoms[index]), right); |
83 | 122 |
} |
84 | 123 |
|
85 |
-static bool compareAtomLower(const Atom &lhs, uint64_t pos) |
|
86 |
-{ |
|
87 |
- return lhs.pos < pos; |
|
88 |
-} |
|
89 |
- |
|
90 |
-static bool compareAtomUpper(uint64_t pos, const Atom &lhs) |
|
91 |
-{ |
|
92 |
- return lhs.pos < pos; |
|
93 |
-} |
|
94 |
- |
|
95 |
-static bool compareAtom(const Atom &lhs, const Atom &rhs) |
|
96 |
-{ |
|
97 |
- return lhs.pos < rhs.pos; |
|
98 |
-} |
|
99 |
- |
|
100 |
-static bool vecContains(const std::vector<Atom> &vec, uint64_t pos) |
|
101 |
-{ |
|
102 |
- Atom temp(pos, 0.f); |
|
103 |
- return std::binary_search(vec.begin(), vec.end(), temp, compareAtom); |
|
104 |
-} |
|
105 |
- |
|
106 | 124 |
uint64_t AtomicDomain::randomFreePosition() const |
107 | 125 |
{ |
108 | 126 |
uint64_t pos = mRng.uniform64(0, mDomainLength); |
... | ... |
@@ -149,6 +167,8 @@ void AtomicDomain::resetCache(unsigned n) |
149 | 167 |
void AtomicDomain::erase(uint64_t pos) |
150 | 168 |
{ |
151 | 169 |
GAPS_ASSERT(size() > 0); |
170 |
+ GAPS_ASSERT(vecContains(mAtoms, pos)); |
|
171 |
+ |
|
152 | 172 |
std::vector<Atom>::iterator it; |
153 | 173 |
it = std::lower_bound(mAtoms.begin(), mAtoms.end(), pos, compareAtomLower); |
154 | 174 |
mAtoms.erase(it); |
... | ... |
@@ -191,7 +211,7 @@ Archive& operator<<(Archive &ar, AtomicDomain &domain) |
191 | 211 |
Archive& operator>>(Archive &ar, AtomicDomain &domain) |
192 | 212 |
{ |
193 | 213 |
Atom temp; |
194 |
- unsigned size = 0; |
|
214 |
+ uint64_t size = 0; |
|
195 | 215 |
ar >> domain.mDomainLength >> domain.mRng >> size; |
196 | 216 |
for (unsigned i = 0; i < size; ++i) |
197 | 217 |
{ |
... | ... |
@@ -36,7 +36,7 @@ class AtomicDomain |
36 | 36 |
{ |
37 | 37 |
public: |
38 | 38 |
|
39 |
- AtomicDomain(unsigned nBins); |
|
39 |
+ AtomicDomain(uint64_t nBins); |
|
40 | 40 |
|
41 | 41 |
// access atoms |
42 | 42 |
Atom* front(); |
... | ... |
@@ -64,7 +64,7 @@ private: |
64 | 64 |
// size of atomic domain to ensure all bins are equal length |
65 | 65 |
uint64_t mDomainLength; |
66 | 66 |
|
67 |
- // domain storage, specialized hash map |
|
67 |
+ // domain storage, sorted vector |
|
68 | 68 |
std::vector<Atom> mAtoms; |
69 | 69 |
|
70 | 70 |
// holds cache of operations |
... | ... |
@@ -253,37 +253,6 @@ void GibbsSampler<T, MatA, MatB>::setMatrix(const Matrix &mat) |
253 | 253 |
mMatrix = mat; |
254 | 254 |
} |
255 | 255 |
|
256 |
-template <class T, class MatA, class MatB> |
|
257 |
-void GibbsSampler<T, MatA, MatB>::update(unsigned nSteps, unsigned nCores) |
|
258 |
-{ |
|
259 |
- unsigned n = 0; |
|
260 |
- while (n < nSteps) |
|
261 |
- { |
|
262 |
- // populate queue, prepare domain for this queue |
|
263 |
- //mQueue.populate(mDomain, nSteps - n); |
|
264 |
- mQueue.populate(mDomain, 1); |
|
265 |
- mDomain.resetCache(mQueue.size()); |
|
266 |
- n += mQueue.size(); |
|
267 |
- |
|
268 |
- // update average queue count |
|
269 |
- #ifdef GAPS_DEBUG |
|
270 |
- mNumQueues += 1.f; |
|
271 |
- mAvgQueue *= (mNumQueues - 1.f) / mNumQueues; |
|
272 |
- mAvgQueue += mQueue.size() / mNumQueues; |
|
273 |
- #endif |
|
274 |
- |
|
275 |
- // process all proposed updates |
|
276 |
- #pragma omp parallel for num_threads(nCores) |
|
277 |
- for (unsigned i = 0; i < mQueue.size(); ++i) |
|
278 |
- { |
|
279 |
- processProposal(&mQueue[i]); |
|
280 |
- } |
|
281 |
- |
|
282 |
- mDomain.flushCache(); |
|
283 |
- mQueue.clear(); |
|
284 |
- } |
|
285 |
-} |
|
286 |
- |
|
287 | 256 |
template <class T, class MatA, class MatB> |
288 | 257 |
unsigned GibbsSampler<T, MatA, MatB>::dataRows() const |
289 | 258 |
{ |
... | ... |
@@ -308,50 +277,45 @@ uint64_t GibbsSampler<T, MatA, MatB>::nAtoms() const |
308 | 277 |
return mDomain.size(); |
309 | 278 |
} |
310 | 279 |
|
311 |
-#ifdef GAPS_DEBUG |
|
312 | 280 |
template <class T, class MatA, class MatB> |
313 |
-float GibbsSampler<T, MatA, MatB>::getAvgQueue() const |
|
314 |
-{ |
|
315 |
- return mAvgQueue; |
|
316 |
-} |
|
317 |
- |
|
318 |
-template <class T, class MatA, class MatB> |
|
319 |
-bool GibbsSampler<T, MatA, MatB>::internallyConsistent() |
|
281 |
+T* GibbsSampler<T, MatA, MatB>::impl() |
|
320 | 282 |
{ |
321 |
- return true; |
|
283 |
+ return static_cast<T*>(this); |
|
322 | 284 |
} |
323 |
-#endif |
|
324 | 285 |
|
325 | 286 |
template <class T, class MatA, class MatB> |
326 |
-Archive& operator<<(Archive &ar, GibbsSampler<T, MatA, MatB> &sampler) |
|
287 |
+void GibbsSampler<T, MatA, MatB>::update(unsigned nSteps, unsigned nCores) |
|
327 | 288 |
{ |
328 |
- ar << sampler.mMatrix << sampler.mAPMatrix << sampler.mQueue << |
|
329 |
- sampler.mDomain << sampler.mLambda << sampler.mMaxGibbsMass << |
|
330 |
- sampler.mAnnealingTemp << sampler.mNumRows << sampler.mNumCols << |
|
331 |
- sampler.mBinSize << sampler.mAvgQueue << sampler.mNumQueues; |
|
332 |
- return ar; |
|
333 |
-} |
|
289 |
+ unsigned n = 0; |
|
290 |
+ while (n < nSteps) |
|
291 |
+ { |
|
292 |
+ // populate queue, prepare domain for this queue |
|
293 |
+ mQueue.populate(mDomain, nSteps - n); |
|
294 |
+ mDomain.resetCache(mQueue.size()); |
|
295 |
+ n += mQueue.size(); |
|
296 |
+ |
|
297 |
+ // update average queue count |
|
298 |
+ #ifdef GAPS_DEBUG |
|
299 |
+ mNumQueues += 1.f; |
|
300 |
+ mAvgQueue *= (mNumQueues - 1.f) / mNumQueues; |
|
301 |
+ mAvgQueue += mQueue.size() / mNumQueues; |
|
302 |
+ #endif |
|
334 | 303 |
|
335 |
-template <class T, class MatA, class MatB> |
|
336 |
-Archive& operator>>(Archive &ar, GibbsSampler<T, MatA, MatB> &sampler) |
|
337 |
-{ |
|
338 |
- ar >> sampler.mMatrix >> sampler.mAPMatrix >> sampler.mQueue >> |
|
339 |
- sampler.mDomain >> sampler.mLambda >> sampler.mMaxGibbsMass >> |
|
340 |
- sampler.mAnnealingTemp >> sampler.mNumRows >> sampler.mNumCols >> |
|
341 |
- sampler.mBinSize >> sampler.mAvgQueue >> sampler.mNumQueues; |
|
342 |
- return ar; |
|
343 |
-} |
|
304 |
+ // process all proposed updates |
|
305 |
+ #pragma omp parallel for num_threads(nCores) |
|
306 |
+ for (unsigned i = 0; i < mQueue.size(); ++i) |
|
307 |
+ { |
|
308 |
+ processProposal(&mQueue[i]); |
|
309 |
+ } |
|
344 | 310 |
|
345 |
-template <class T, class MatA, class MatB> |
|
346 |
-T* GibbsSampler<T, MatA, MatB>::impl() |
|
347 |
-{ |
|
348 |
- return static_cast<T*>(this); |
|
311 |
+ mDomain.flushCache(); |
|
312 |
+ mQueue.clear(); |
|
313 |
+ } |
|
349 | 314 |
} |
350 | 315 |
|
351 | 316 |
template <class T, class MatA, class MatB> |
352 | 317 |
void GibbsSampler<T, MatA, MatB>::processProposal(AtomicProposal *prop) |
353 | 318 |
{ |
354 |
- unsigned r1 = 0, c1 = 0, r2 = 0, c2 = 0; |
|
355 | 319 |
switch (prop->type) |
356 | 320 |
{ |
357 | 321 |
case 'B': |
... | ... |
@@ -413,8 +377,9 @@ void GibbsSampler<T, MatA, MatB>::death(AtomicProposal *prop) |
413 | 377 |
unsigned col = impl()->getCol(prop->atom1->pos); |
414 | 378 |
|
415 | 379 |
// kill off atom |
416 |
- mMatrix(row, col) = gaps::max(mMatrix(row, col) - prop->atom1->mass, 0.f); |
|
417 |
- impl()->updateAPMatrix(row, col, -1.f * prop->atom1->mass); |
|
380 |
+ float newVal = gaps::max(mMatrix(row, col) - prop->atom1->mass, 0.f); |
|
381 |
+ impl()->updateAPMatrix(row, col, newVal - mMatrix(row, col)); |
|
382 |
+ mMatrix(row, col) = newVal; |
|
418 | 383 |
|
419 | 384 |
// calculate rebirth mass |
420 | 385 |
float rebirthMass = prop->atom1->mass; |
... | ... |
@@ -459,13 +424,13 @@ void GibbsSampler<T, MatA, MatB>::move(AtomicProposal *prop) |
459 | 424 |
r2, c2, prop->atom1->mass); |
460 | 425 |
if (deltaLL * mAnnealingTemp > std::log(prop->rng.uniform())) |
461 | 426 |
{ |
462 |
- //mDomain.cacheMove(prop->atom1->pos, prop->moveDest, prop->atom1->mass); |
|
463 |
- prop->atom1->pos = prop->moveDest; // temporary for vector domain |
|
427 |
+ prop->atom1->pos = prop->moveDest; |
|
464 | 428 |
|
465 |
- mMatrix(r1, c1) = gaps::max(mMatrix(r1, c1) - prop->atom1->mass, 0.f); |
|
466 |
- mMatrix(r2, c2) += prop->atom1->mass; |
|
429 |
+ float newVal = gaps::max(mMatrix(r1, c1) - prop->atom1->mass, 0.f); |
|
430 |
+ impl()->updateAPMatrix(r1, c1, newVal - mMatrix(r1, c1)); |
|
431 |
+ mMatrix(r1, c1) = newVal; |
|
467 | 432 |
|
468 |
- impl()->updateAPMatrix(r1, c1, -1.f * prop->atom1->mass); |
|
433 |
+ mMatrix(r2, c2) += prop->atom1->mass; |
|
469 | 434 |
impl()->updateAPMatrix(r2, c2, prop->atom1->mass); |
470 | 435 |
} |
471 | 436 |
} |
... | ... |
@@ -565,10 +530,15 @@ float d1, unsigned r1, unsigned c1, unsigned r2, unsigned c2) |
565 | 530 |
mQueue.rejectDeath(); |
566 | 531 |
} |
567 | 532 |
|
568 |
- mMatrix(r1, c1) += d1; |
|
569 |
- mMatrix(r2, c2) += d2; |
|
570 |
- impl()->updateAPMatrix(r1, c1, d1); |
|
571 |
- impl()->updateAPMatrix(r2, c2, d2); |
|
533 |
+ // ensure matrix values don't go negative (truncation error at fault) |
|
534 |
+ float v1 = gaps::max(mMatrix(r1, c1) + d1, 0.f); |
|
535 |
+ impl()->updateAPMatrix(r1, c1, v1 - mMatrix(r1, c1)); |
|
536 |
+ mMatrix(r1, c1) = v1; |
|
537 |
+ |
|
538 |
+ |
|
539 |
+ float v2 = gaps::max(mMatrix(r2, c2) + d2, 0.f); |
|
540 |
+ impl()->updateAPMatrix(r2, c2, v2 - mMatrix(r2, c2)); |
|
541 |
+ mMatrix(r2, c2) = v2; |
|
572 | 542 |
} |
573 | 543 |
|
574 | 544 |
template <class T, class MatA, class MatB> |
... | ... |
@@ -618,4 +588,36 @@ float m1, float m2, GapsRng *rng) |
618 | 588 |
return std::pair<float, bool>(0.f, false); |
619 | 589 |
} |
620 | 590 |
|
621 |
-#endif |
|
591 |
+#ifdef GAPS_DEBUG |
|
592 |
+template <class T, class MatA, class MatB> |
|
593 |
+float GibbsSampler<T, MatA, MatB>::getAvgQueue() const |
|
594 |
+{ |
|
595 |
+ return mAvgQueue; |
|
596 |
+} |
|
597 |
+ |
|
598 |
+template <class T, class MatA, class MatB> |
|
599 |
+bool GibbsSampler<T, MatA, MatB>::internallyConsistent() |
|
600 |
+{ |
|
601 |
+ return true; |
|
602 |
+} |
|
603 |
+#endif // GAPS_DEBUG |
|
604 |
+ |
|
605 |
+template <class T, class MatA, class MatB> |
|
606 |
+Archive& operator<<(Archive &ar, GibbsSampler<T, MatA, MatB> &s) |
|
607 |
+{ |
|
608 |
+ ar << s.mMatrix << s.mAPMatrix << s.mQueue << s.mDomain << s.mLambda |
|
609 |
+ << s.mMaxGibbsMass << s.mAnnealingTemp << s.mNumRows << s.mNumCols |
|
610 |
+ << s.mBinSize << s.mAvgQueue << s.mNumQueues; |
|
611 |
+ return ar; |
|
612 |
+} |
|
613 |
+ |
|
614 |
+template <class T, class MatA, class MatB> |
|
615 |
+Archive& operator>>(Archive &ar, GibbsSampler<T, MatA, MatB> &s) |
|
616 |
+{ |
|
617 |
+ ar >> s.mMatrix >> s.mAPMatrix >> s.mQueue >> s.mDomain >> s.mLambda |
|
618 |
+ >> s.mMaxGibbsMass >> s.mAnnealingTemp >> s.mNumRows >> s.mNumCols |
|
619 |
+ >> s.mBinSize >> s.mAvgQueue >> s.mNumQueues; |
|
620 |
+ return ar; |
|
621 |
+} |
|
622 |
+ |
|
623 |
+#endif // __COGAPS_GIBBS_SAMPLER_H__ |
... | ... |
@@ -2,12 +2,38 @@ |
2 | 2 |
#include "ProposalQueue.h" |
3 | 3 |
#include "math/Random.h" |
4 | 4 |
|
5 |
+//////////////////////////////// AtomicProposal //////////////////////////////// |
|
6 |
+ |
|
7 |
+// birth |
|
8 |
+AtomicProposal::AtomicProposal(char t, uint64_t pos) |
|
9 |
+ : type(t), birthPos(pos), moveDest(0), atom1(NULL), atom2(NULL) |
|
10 |
+{} |
|
11 |
+ |
|
12 |
+// death |
|
13 |
+AtomicProposal::AtomicProposal(char t, Atom *atom) |
|
14 |
+ : type(t), birthPos(0), moveDest(0), atom1(atom), atom2(NULL) |
|
15 |
+{} |
|
16 |
+ |
|
17 |
+// move |
|
18 |
+AtomicProposal::AtomicProposal(char t, Atom *atom, uint64_t dest) |
|
19 |
+ : type(t), birthPos(0), moveDest(dest), atom1(atom), atom2(NULL) |
|
20 |
+{} |
|
21 |
+ |
|
22 |
+// exchange |
|
23 |
+AtomicProposal::AtomicProposal(char t, Atom *a1, Atom *a2) |
|
24 |
+ : type(t), birthPos(0), moveDest(0), atom1(a1), atom2(a2) |
|
25 |
+{} |
|
26 |
+ |
|
27 |
+ |
|
28 |
+//////////////////////////////// ProposalQueue ///////////////////////////////// |
|
29 |
+ |
|
5 | 30 |
ProposalQueue::ProposalQueue(unsigned primaryDimSize, unsigned secondaryDimSize) |
6 | 31 |
: |
7 | 32 |
mMinAtoms(0), mMaxAtoms(0), mNumBins(primaryDimSize * secondaryDimSize), |
8 | 33 |
mBinLength(std::numeric_limits<uint64_t>::max() / mNumBins), |
9 | 34 |
mSecondaryDimLength(mBinLength * secondaryDimSize), |
10 |
-mDomainLength(mBinLength * mNumBins), mSecondaryDimSize(secondaryDimSize) |
|
35 |
+mDomainLength(mBinLength * mNumBins), mSecondaryDimSize(secondaryDimSize), |
|
36 |
+mAlpha(0.f), mU1(0.f), mU2(0.f), mUseCachedRng(false) |
|
11 | 37 |
{ |
12 | 38 |
mUsedIndices.setDimensionSize(primaryDimSize); |
13 | 39 |
} |
... | ... |
@@ -19,6 +45,9 @@ void ProposalQueue::setAlpha(float alpha) |
19 | 45 |
|
20 | 46 |
void ProposalQueue::populate(AtomicDomain &domain, unsigned limit) |
21 | 47 |
{ |
48 |
+ GAPS_ASSERT(mMinAtoms == mMaxAtoms); |
|
49 |
+ GAPS_ASSERT(mMaxAtoms == domain.size()); |
|
50 |
+ |
|
22 | 51 |
unsigned nIter = 0; |
23 | 52 |
bool success = true; |
24 | 53 |
while (nIter++ < limit && success) |
... | ... |
@@ -33,10 +62,11 @@ void ProposalQueue::populate(AtomicDomain &domain, unsigned limit) |
33 | 62 |
|
34 | 63 |
void ProposalQueue::clear() |
35 | 64 |
{ |
65 |
+ GAPS_ASSERT(mMinAtoms == mMaxAtoms); |
|
66 |
+ |
|
36 | 67 |
mQueue.clear(); |
37 | 68 |
mUsedPositions.clear(); |
38 | 69 |
mUsedIndices.clear(); |
39 |
- GAPS_ASSERT(mMinAtoms == mMaxAtoms); |
|
40 | 70 |
} |
41 | 71 |
|
42 | 72 |
unsigned ProposalQueue::size() const |
... | ... |
@@ -46,6 +76,9 @@ unsigned ProposalQueue::size() const |
46 | 76 |
|
47 | 77 |
AtomicProposal& ProposalQueue::operator[](int n) |
48 | 78 |
{ |
79 |
+ GAPS_ASSERT(mQueue.size() > 0); |
|
80 |
+ GAPS_ASSERT(n < mQueue.size()); |
|
81 |
+ |
|
49 | 82 |
return mQueue[n]; |
50 | 83 |
} |
51 | 84 |
|
... | ... |
@@ -130,7 +163,8 @@ unsigned ProposalQueue::secondaryIndex(uint64_t pos) const |
130 | 163 |
} |
131 | 164 |
|
132 | 165 |
// TODO add atoms with empty mass? fill in mass in gibbssampler? |
133 |
-// inserting invalidates previous pointers |
|
166 |
+// inserting invalidates previous pointers, but not inserting |
|
167 |
+// prevents them from being selected for death |
|
134 | 168 |
bool ProposalQueue::birth(AtomicDomain &domain) |
135 | 169 |
{ |
136 | 170 |
uint64_t pos = domain.randomFreePosition(); |
... | ... |
@@ -198,7 +232,7 @@ bool ProposalQueue::move(AtomicDomain &domain) |
198 | 232 |
bool ProposalQueue::exchange(AtomicDomain &domain) |
199 | 233 |
{ |
200 | 234 |
AtomNeighborhood hood = domain.randomAtomWithRightNeighbor(); |
201 |
- Atom* a1 = hood.center; |
|
235 |
+ Atom* a1 = hood.center; |
|
202 | 236 |
Atom* a2 = hood.hasRight() ? hood.right : domain.front(); |
203 | 237 |
|
204 | 238 |
if (hood.hasRight()) // has neighbor |
... | ... |
@@ -242,20 +276,18 @@ bool ProposalQueue::exchange(AtomicDomain &domain) |
242 | 276 |
return true; |
243 | 277 |
} |
244 | 278 |
|
245 |
-Archive& operator<<(Archive &ar, ProposalQueue &queue) |
|
279 |
+Archive& operator<<(Archive &ar, ProposalQueue &q) |
|
246 | 280 |
{ |
247 |
- ar << queue.mMinAtoms << queue.mMaxAtoms << queue.mNumBins |
|
248 |
- << queue.mBinLength << queue.mSecondaryDimLength << queue.mDomainLength |
|
249 |
- << queue.mSecondaryDimSize << queue.mAlpha << queue.mRng |
|
250 |
- << queue.mU1 << queue.mU2 << queue.mUseCachedRng; |
|
281 |
+ ar << q.mMinAtoms << q.mMaxAtoms << q.mNumBins << q.mBinLength |
|
282 |
+ << q.mSecondaryDimLength << q.mDomainLength << q.mSecondaryDimSize |
|
283 |
+ << q.mAlpha << q.mRng; |
|
251 | 284 |
return ar; |
252 | 285 |
} |
253 | 286 |
|
254 |
-Archive& operator>>(Archive &ar, ProposalQueue &queue) |
|
287 |
+Archive& operator>>(Archive &ar, ProposalQueue &q) |
|
255 | 288 |
{ |
256 |
- ar >> queue.mMinAtoms >> queue.mMaxAtoms >> queue.mNumBins |
|
257 |
- >> queue.mBinLength >> queue.mSecondaryDimLength >> queue.mDomainLength |
|
258 |
- >> queue.mSecondaryDimSize >> queue.mAlpha >> queue.mRng |
|
259 |
- >> queue.mU1 >> queue.mU2 >> queue.mUseCachedRng; |
|
289 |
+ ar >> q.mMinAtoms >> q.mMaxAtoms >> q.mNumBins >> q.mBinLength |
|
290 |
+ >> q.mSecondaryDimLength >> q.mDomainLength >> q.mSecondaryDimSize |
|
291 |
+ >> q.mAlpha >> q.mRng; |
|
260 | 292 |
return ar; |
261 | 293 |
} |
... | ... |
@@ -21,25 +21,10 @@ struct AtomicProposal |
21 | 21 |
|
22 | 22 |
mutable GapsRng rng; |
23 | 23 |
|
24 |
- // birth |
|
25 |
- AtomicProposal(char t, uint64_t pos) |
|
26 |
- : type(t), birthPos(pos), moveDest(0), atom1(NULL), atom2(NULL) |
|
27 |
- {} |
|
28 |
- |
|
29 |
- // death |
|
30 |
- AtomicProposal(char t, Atom *atom) |
|
31 |
- : type(t), birthPos(0), moveDest(0), atom1(atom), atom2(NULL) |
|
32 |
- {} |
|
33 |
- |
|
34 |
- // move |
|
35 |
- AtomicProposal(char t, Atom *atom, uint64_t dest) |
|
36 |
- : type(t), birthPos(0), moveDest(dest), atom1(atom), atom2(NULL) |
|
37 |
- {} |
|
38 |
- |
|
39 |
- // exchange |
|
40 |
- AtomicProposal(char t, Atom *a1, Atom *a2) |
|
41 |
- : type(t), birthPos(0), moveDest(0), atom1(a1), atom2(a2) |
|
42 |
- {} |
|
24 |
+ AtomicProposal(char t, uint64_t pos); // birth |
|
25 |
+ AtomicProposal(char t, Atom *atom); // death |
|
26 |
+ AtomicProposal(char t, Atom *atom, uint64_t dest); // move |
|
27 |
+ AtomicProposal(char t, Atom *a1, Atom *a2); // exchange |
|
43 | 28 |
}; |
44 | 29 |
|
45 | 30 |
class ProposalQueue |
... | ... |
@@ -226,8 +226,8 @@ things like hardware and data size. The best approach is to play around with |
226 | 226 |
different values and see how it effects the estimated time. |
227 | 227 |
|
228 | 228 |
```{r} |
229 |
-CoGAPS(SimpSim.data, nIterations=10000, outputFrequency=5000, nThreads=1) |
|
230 |
-CoGAPS(SimpSim.data, nIterations=10000, outputFrequency=5000, nThreads=4) |
|
229 |
+CoGAPS(SimpSim.data, nIterations=10000, outputFrequency=5000, nThreads=1, seed=5) |
|
230 |
+CoGAPS(SimpSim.data, nIterations=10000, outputFrequency=5000, nThreads=4, seed=5) |
|
231 | 231 |
``` |
232 | 232 |
|
233 | 233 |
Note this method relies on CoGAPS being compiled with OpenMP support, use |