source: trunk/PROBE_SET/ps_bitmap.hxx

Last change on this file was 18730, checked in by westram, 3 years ago
  • remove trailing whitespace from c source.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.7 KB
Line 
1#ifndef PS_BITMAP_HXX
2#define PS_BITMAP_HXX
3
4#ifndef __MAP__
5#include <map>
6#endif
7#ifndef PS_BITSET_HXX
8#include "ps_bitset.hxx"
9#endif
10
11class PS_BitMap : virtual Noncopyable {
12protected:
13
14    PS_BitSet **data; // array of pointers to PS_BitSet
15
16    bool bias;     // preset for bitmap
17    long max_row;  // max used row index
18    long capacity; // number of allocated rows (and columns)
19
20    virtual bool do_reserve(const long _capacity, const bool _init_sets);
21
22    PS_BitMap(const bool _bias, const long _max_row, const long _capacity)
23        : data(NULp),
24          bias(_bias),
25          max_row(_max_row),
26          capacity(_capacity)
27    {}
28
29public:
30
31    virtual long getTrueIndicesFor(const long _index, PS_BitSet::IndexSet &_index_set);
32    virtual long getFalseIndicesFor(const long _index, PS_BitSet::IndexSet &_index_set);
33    virtual long getCountOfTrues();
34
35    virtual bool get(const long _row, const long _col);
36    virtual bool set(const long _row, const long _col, const bool _value);
37
38    virtual void setTrue(const long _row, const long _col)  = 0;
39    virtual void setFalse(const long _row, const long _col) = 0;
40
41    // triangle_ - functions reverse _row and _col if _row is greater than _col
42    // the resulting map is only triangular
43            bool triangle_get(const long _row, const long _col);
44            bool triangle_set(const long _row, const long _col, const bool _value);
45
46            void invert();
47            void x_or(const PS_BitMap *_other_map);
48
49    virtual void print(FILE *out);
50    virtual void printGNUplot(const char *_title, char *_buffer, PS_FileBuffer *_file);
51            bool save(PS_FileBuffer *_file);
52    virtual bool load(PS_FileBuffer *_file);
53
54            bool copy(const PS_BitMap *_other_bitmap);
55    virtual bool reserve(const long _capacity);
56
57    explicit PS_BitMap(const bool _bias, const long _capacity) : bias(_bias), max_row(0), capacity(_capacity) {
58        data = (PS_BitSet **)malloc(capacity * sizeof(PS_BitSet*));
59        for (long i = 0; i < capacity; ++i) {                        // init requested bitsets
60            data[i] = new PS_BitSet(bias, capacity);                 // init field
61            if (!data[i]) {
62                printf("PS_BitMap( %s,%li ) : error while init. data[%li]\n", bias ? "true" : "false", capacity, i);
63                exit(1);
64            }
65        }
66    }
67
68    explicit PS_BitMap(PS_FileBuffer *_file) : bias(false), max_row(0), capacity(0) {
69        data = NULp;
70        load(_file);
71    }
72
73    virtual ~PS_BitMap() {
74        for (long i = 0; i < capacity; ++i) {
75            if (data[i]) delete data[i];
76        }
77        if (data) free(data);
78    }
79};
80
81
82//  ############################################################
83//  # PS_BitMap_Fast
84//  ############################################################
85//   No checks are made to assure that given row/col indices
86//   point to an allocated byte. Make sure you reserve the needed
87//   space either at creation time or before accessing the bits.
88//
89class PS_BitMap_Fast FINAL_TYPE : public PS_BitMap {
90private:
91
92    bool copy(const PS_BitSet *_other_bitset);   // declared but not implemented
93    bool do_reserve(const long _capacity, const bool _init_sets) OVERRIDE;
94
95    PS_BitMap_Fast(const PS_BitMap_Fast&);
96    PS_BitMap_Fast();
97
98public:
99
100    bool get(const long _row, const long _col) OVERRIDE;
101    bool set(const long _row, const long _col, const bool _value) OVERRIDE;
102    void setTrue(const long _row, const long _col) OVERRIDE;
103    void setFalse(const long _row, const long _col) OVERRIDE;
104
105    bool load(PS_FileBuffer *_file) OVERRIDE;
106
107    bool copy(const PS_BitMap_Fast *_other_bitmap);
108    bool reserve(const long _capacity) OVERRIDE;
109
110    explicit PS_BitMap_Fast(const bool _bias, const long _capacity) : PS_BitMap(_bias, 0, _capacity) {
111        data = (PS_BitSet **)malloc(capacity * sizeof(PS_BitSet*));
112        for (long i = 0; i < capacity; ++i) {                        // init requested bitsets
113            data[i] = new PS_BitSet_Fast(bias, capacity);            // init field
114            if (!data[i]) {
115                printf("PS_BitMap_Fast( %s,%li ) : error while init. data[%li]\n", bias ? "true" : "false", capacity, i);
116                exit(1);
117            }
118        }
119    }
120};
121
122
123//  ############################################################
124//  # PS_BitMap_Counted
125//  ############################################################
126//   PS_BitMap_Counted is ALWAYS triangular.
127//   This means that the max column index in a row is the row number.
128//   The resulting bitmap is the lower left half
129//     012
130//   0 .
131//   1 ..
132//   2 ...
133//   Therefore the row index must be higher or equal than the column index
134//   when you call set/get-functions, which do not check given row,col.
135//   If you cannot assure this use the triangleSet/Get-functions.
136//
137//   count_true_per_index counts TRUEs in a row + the TRUEs in the
138//   column of the same index.
139//   Only set() automatically updates count_true_per_index.
140//
141class PS_BitMap_Counted FINAL_TYPE : public PS_BitMap { // derived from a Noncopyable
142    long *count_true_per_index;
143
144    bool copy(const PS_BitSet *_other_bitset);   // declared but not implemented because PS_BitSet has no count_true_per_index array
145    bool do_reserve(const long _capacity, const bool _init_sets) OVERRIDE;
146
147    PS_BitMap_Counted(const PS_BitMap_Counted&);
148    PS_BitMap_Counted();
149
150public:
151
152    void recalcCounters();
153    long getCountFor(const long _index) { return count_true_per_index[_index]; }
154
155    long getTrueIndicesFor(const long _index, PS_BitSet::IndexSet &_index_set) OVERRIDE;
156    long getFalseIndicesFor(const long _index, PS_BitSet::IndexSet &_index_set) OVERRIDE;
157    long getTrueIndicesForRow(const long _row, PS_BitSet::IndexSet &_index_set);
158    long getFalseIndicesForRow(const long _row, PS_BitSet::IndexSet &_index_set);
159    long getCountOfTrues() OVERRIDE;
160
161    bool get(const long _row, const long _col) OVERRIDE;
162    bool set(const long _row, const long _col, const bool _value) OVERRIDE;
163    void setTrue(const long _row, const long _col) OVERRIDE;
164    void setFalse(const long _row, const long _col) OVERRIDE;
165
166    void print(FILE *out) OVERRIDE;
167    void printGNUplot(const char *_title, char *_buffer, PS_FileBuffer *_file) OVERRIDE;
168    bool load(PS_FileBuffer *_file) OVERRIDE;
169
170    bool copy(const PS_BitMap_Counted *_other_bitmap);
171    bool reserve(const long _capacity) OVERRIDE;
172
173    explicit PS_BitMap_Counted(PS_FileBuffer *_file) : PS_BitMap(false, 0, 0) {
174        data                 = NULp;
175        count_true_per_index = NULp;
176        load(_file);
177    }
178
179    explicit PS_BitMap_Counted(const bool _bias, const long _capacity) : PS_BitMap(_bias, 0, _capacity) {
180        data = (PS_BitSet **)malloc(capacity * sizeof(PS_BitSet*));
181        for (long i = 0; i < capacity; ++i) {                        // init requested bitsets
182            data[i] = new PS_BitSet_Fast(bias, capacity);            // init field
183            if (!data[i]) {
184                printf("PS_BitMap_Counted( %s,%li ) : error while init. data[%li]\n", bias ? "true" : "false", capacity, i);
185                exit(1);
186            }
187        }
188        // alloc memory for counters
189        count_true_per_index = (long *)malloc(capacity * sizeof(long));
190
191        // preset memory of counters
192        memset(count_true_per_index, (bias) ? capacity : 0, capacity * sizeof(long));
193    }
194
195    ~PS_BitMap_Counted() OVERRIDE {
196        if (count_true_per_index) free(count_true_per_index);
197    }
198};
199
200
201long PS_BitMap::getTrueIndicesFor(const long _index, PS_BitSet::IndexSet &_index_set) {
202    // get trues in the row
203    data[_index]->getTrueIndices(_index_set, _index);
204    // scan column _index in the remaining rows
205    for (long row = _index+1; row <= max_row; ++row) {
206        if (data[row]->Get(_index)) _index_set.insert(row);
207    }
208    return _index_set.size();
209}
210
211
212long PS_BitMap::getFalseIndicesFor(const long _index, PS_BitSet::IndexSet &_index_set) {
213    // get falses in the row
214    data[_index]->getFalseIndices(_index_set, _index);
215    // scan column _index in the remaining rows
216    for (long row = _index+1; row <= max_row; ++row) {
217        if (!(data[row]->Get(_index))) _index_set.insert(row);
218    }
219    return _index_set.size();
220}
221
222
223long PS_BitMap::getCountOfTrues() {
224    long count = 0;
225    // sum up trues in the rows
226    for (long row = 0; row <= max_row; ++row) {
227        count += data[row]->getCountOfTrues();
228    }
229    return count;
230}
231
232
233bool PS_BitMap::set(const long _row, const long _col, const bool _value) {
234    reserve(_row+1);
235    if (_row > max_row) max_row = _row;
236    return data[_row]->Set(_col, _value);
237}
238
239
240bool PS_BitMap::get(const long _row, const long _col) {
241    reserve(_row+1);
242    return data[_row]->Get(_col);
243}
244
245
246bool PS_BitMap::triangle_set(const long _row, const long _col, const bool _value) {
247    if (_row > _col) {
248        return set(_col, _row, _value);
249    }
250    else {
251        return set(_row, _col, _value);
252    }
253}
254
255
256bool PS_BitMap::triangle_get(const long _row, const long _col) {
257    if (_row > _col) {
258        return get(_col, _row);
259    }
260    else {
261        return get(_row, _col);
262    }
263}
264
265
266bool PS_BitMap::copy(const PS_BitMap *_other_bitmap) {
267    bias = _other_bitmap->bias;
268    if (!do_reserve(_other_bitmap->capacity, false)) return false;
269    for (long i = 0; i < capacity; ++i) {
270        if (!data[i]) data[i] = new PS_BitSet(bias, _other_bitmap->data[i]->getCapacity());
271        if (!data[i]->copy(_other_bitmap->data[i])) return false;
272    }
273    max_row = _other_bitmap->max_row;
274    return true;
275}
276
277
278bool PS_BitMap::reserve(const long _capacity) {
279    return do_reserve(_capacity, true);
280}
281bool PS_BitMap::do_reserve(const long _capacity, const bool _init_sets) {
282    PS_BitSet **new_data;
283    long new_capacity_bytes = _capacity * sizeof(PS_BitSet*);
284    long old_capacity_bytes =  capacity * sizeof(PS_BitSet*);
285    if (_capacity <= capacity) return true;                      // smaller or same size requested ?
286    new_data = (PS_BitSet **)malloc(new_capacity_bytes);         // get new memory for pointer array
287    if (!new_data) return false;
288    if (capacity > 0) memcpy(new_data, data, old_capacity_bytes); // copy old pointers
289    if (data) free(data);                                        // free old memory
290    data = new_data;
291    if (_init_sets) {
292        for (long i = capacity; i < _capacity; ++i) {            // init new requested bitsets
293            data[i] = new PS_BitSet(bias, 1);                    // init field
294            if (!data[i]) return false;                          // check success
295        }
296    }
297    capacity = _capacity;                                        // store new capacity
298    return true;
299}
300
301
302void PS_BitMap::invert() {
303    for (long i = 0; i <= max_row; ++i) {
304        data[i]->invert();
305    }
306}
307
308
309void PS_BitMap::x_or(const PS_BitMap *_other_map) {
310    for (long i = 0; i <= max_row; ++i) {
311        data[i]->x_or(_other_map->data[i]);
312    }
313}
314
315
316void PS_BitMap::print(FILE *out) {
317    fprintf(out, "PS_BitMap : bias(%1i) max_row(%6li) capacity(%6li)\n", bias, max_row, capacity);
318    for (long i = 0; i < capacity; ++i) {
319        fprintf(out, "[%5li] ", i);
320        data[i]->print(out, true, i);
321    }
322}
323
324
325void PS_BitMap::printGNUplot(const char *_title, char *_buffer, PS_FileBuffer *_file) {
326    // write title
327    long size;
328    size = sprintf(_buffer, "# %s\n#PS_BitMap : bias(%1i) max_row(%li) capacity(%li)\n#col row\n", _title, bias, max_row, capacity);
329    _file->put(_buffer, size);
330
331    // write indices of trues per row
332    PS_BitSet::IndexSet trues;
333    for (long row = 0;
334          row < capacity;
335          ++row) {
336        data[row]->getTrueIndices(trues);
337        for (PS_BitSet::IndexSet::iterator col = trues.begin();
338              col != trues.end();
339              ++col) {
340            size = sprintf(_buffer, "%li %li\n", *col, row);
341            _file->put(_buffer, size);
342        }
343    }
344
345    _file->flush();
346}
347
348
349bool PS_BitMap::save(PS_FileBuffer *_file) {
350    if (_file->isReadonly()) return false;
351    // save max_row
352    _file->put_long(max_row);
353    // save bias
354    _file->put_char((bias) ? '1' : '0');
355    // save bitsets
356    for (long i = 0; i <= max_row; ++i) {
357        data[i]->save(_file);
358    }
359    return true;
360}
361
362
363bool PS_BitMap::load(PS_FileBuffer *_file) {
364    if (!_file->isReadonly()) return false;
365    // load max_row
366    _file->get_long(max_row);
367    // load bias
368    bias = (_file->get_char() == '1');
369    // initialize bitmap
370    if (!do_reserve(max_row+1, false)) return false;
371    for (long i = 0; i <= max_row; ++i) {
372        if (data[i]) {
373            delete data[i];
374        }
375        data[i] = new PS_BitSet(_file);
376    }
377    return true;
378}
379
380
381inline bool PS_BitMap_Fast::set(const long _row, const long _col, const bool _value) {
382    if (_row > max_row) max_row = _row;
383    return data[_row]->Set(_col, _value);
384}
385
386
387inline bool PS_BitMap_Fast::get(const long _row, const long _col) {
388    if (_row > max_row) max_row = _row;
389    return data[_row]->Get(_col);
390}
391
392
393inline void PS_BitMap_Fast::setTrue(const long _row, const long _col) {
394    if (_row > max_row) max_row = _row;
395    data[_row]->setTrue(_col);
396}
397
398
399inline void PS_BitMap_Fast::setFalse(const long _row, const long _col) {
400    if (_row > max_row) max_row = _row;
401    data[_row]->setFalse(_col);
402}
403
404
405bool PS_BitMap_Fast::load(PS_FileBuffer *_file) {
406    if (!_file->isReadonly()) return false;
407    // load max_row
408    _file->get_long(max_row);
409    // load bias
410    bias = (_file->get_char() == '1');
411    // initialize bitmap
412    if (!do_reserve(max_row+1, false)) return false;
413    for (long i = 0; i <= max_row; ++i) {
414        if (data[i]) {
415            delete data[i];
416        }
417        data[i] = new PS_BitSet_Fast(_file);
418    }
419    return true;
420}
421
422bool PS_BitMap_Fast::copy(const PS_BitMap_Fast *_other_bitmap) {
423    bias = _other_bitmap->bias;
424    if (!do_reserve(_other_bitmap->capacity, false)) return false;
425    for (long i = 0; i < capacity; ++i) {
426        if (!data[i]) data[i] = new PS_BitSet_Fast(bias, _other_bitmap->data[i]->getCapacity());
427        if (!data[i]->copy(_other_bitmap->data[i])) return false;
428    }
429    max_row = _other_bitmap->max_row;
430    return true;
431}
432
433bool PS_BitMap_Fast::reserve(const long _capacity) {
434    return do_reserve(_capacity, true);
435}
436bool PS_BitMap_Fast::do_reserve(const long _capacity, const bool _init_sets) {
437    if (_capacity <= capacity) return true;                      // smaller or same size requested ?
438    PS_BitSet **new_data;
439    long new_capacity_bytes = _capacity * sizeof(PS_BitSet*);
440    long old_capacity_bytes =  capacity * sizeof(PS_BitSet*);
441    new_data = (PS_BitSet **)malloc(new_capacity_bytes);         // get new memory for pointer array
442    if (!new_data) return false;
443    if (capacity > 0) memcpy(new_data, data, old_capacity_bytes); // copy old pointers
444    if (data) free(data);                                        // free old memory
445    data = new_data;
446    if (_init_sets) {
447        for (long i = capacity; i < _capacity; ++i) {            // init new requested bitsets
448            data[i] = new PS_BitSet_Fast(bias, 1);               // init field
449            if (!data[i]) return false;                          // check success
450        }
451    }
452    capacity = _capacity;                                        // store new capacity
453    return true;
454}
455
456
457long PS_BitMap_Counted::getTrueIndicesFor(const long _index, PS_BitSet::IndexSet &_index_set) {
458    // get total number of trues
459    unsigned long total_count_trues = count_true_per_index[_index];
460    // get trues in the row
461    data[_index]->getTrueIndices(_index_set, _index);
462    // scan column _index in the remaining rows until all trues are found
463    for (long row = _index+1;
464         ((row <= max_row) && (_index_set.size() < total_count_trues));
465         ++row) {
466        if (data[row]->Get(_index)) _index_set.insert(row);
467    }
468    return _index_set.size();
469}
470
471
472long PS_BitMap_Counted::getFalseIndicesFor(const long _index, PS_BitSet::IndexSet &_index_set) {
473    // get total number of falses
474    unsigned long total_count_falses = capacity - count_true_per_index[_index];
475    // get falses in the row
476    data[_index]->getFalseIndices(_index_set, _index);
477    // scan column _index in the remaining rows until all falses are found
478    for (long row = _index+1;
479         ((row <= max_row) && (_index_set.size() < total_count_falses));
480         ++row) {
481        if (!(data[row]->Get(_index))) _index_set.insert(row);
482    }
483    return _index_set.size();
484}
485
486
487long PS_BitMap_Counted::getTrueIndicesForRow(const long _row, PS_BitSet::IndexSet &_index_set) {
488    // get trues in the row
489    data[_row]->getTrueIndices(_index_set, _row);
490    return _index_set.size();
491}
492
493
494long PS_BitMap_Counted::getFalseIndicesForRow(const long _row, PS_BitSet::IndexSet &_index_set) {
495    // get falses in the row
496    data[_row]->getFalseIndices(_index_set, _row);
497    return _index_set.size();
498}
499
500
501long PS_BitMap_Counted::getCountOfTrues() {
502    long count = 0;
503    // sum up trues in the rows
504    for (long row = 0; row <= max_row; ++row) {
505        count += data[row]->getCountOfTrues(row);
506    }
507    return count;
508}
509
510
511bool PS_BitMap_Counted::set(const long _row, const long _col, const bool _value) {
512    if (_col > _row) printf("PS_BitMap_Counted::set( %li,%li,%1i ) not allowed\n", _row, _col, _value);
513    if (_row > max_row) max_row = _row;
514    bool previous_value = data[_row]->Set(_col, _value);
515    if (_value && !previous_value) {
516        ++count_true_per_index[_row];
517        ++count_true_per_index[_col];
518    }
519    else if (!_value && previous_value) {
520        --count_true_per_index[_row];
521        --count_true_per_index[_col];
522    }
523    return previous_value;
524}
525
526
527inline bool PS_BitMap_Counted::get(const long _row, const long _col) {
528    if (_col > _row) printf("PS_BitMap_Counted::get( %li,%li ) not allowed\n", _row, _col);
529    if (_row > max_row) max_row = _row;
530    return data[_row]->Get(_col);
531}
532
533
534inline void PS_BitMap_Counted::setTrue(const long _row, const long _col) {
535    if (_col > _row) printf("PS_BitMap_Counted::setTrue( %li,%li ) not allowed\n", _row, _col);
536    if (_row > max_row) max_row = _row;
537    data[_row]->setTrue(_col);
538}
539
540
541inline void PS_BitMap_Counted::setFalse(const long _row, const long _col) {
542    if (_col > _row) printf("PS_BitMap_Counted::setFalse( %li,%li ) not allowed\n", _row, _col);
543    if (_row > max_row) max_row = _row;
544    data[_row]->setFalse(_col);
545}
546
547
548bool PS_BitMap_Counted::load(PS_FileBuffer *_file) {
549    if (!_file->isReadonly()) return false;
550    // load max_row
551    _file->get_long(max_row);
552    // load bias
553    bias = (_file->get_char() == '1');
554    // initialize bitmap
555    if (!do_reserve(max_row+1, false)) return false;
556    for (long i = 0; i <= max_row; ++i) {
557        if (data[i]) {
558            delete data[i];
559        }
560        data[i] = new PS_BitSet_Fast(_file, i);
561    }
562    recalcCounters();
563    return true;
564}
565
566
567bool PS_BitMap_Counted::copy(const PS_BitMap_Counted *_other_bitmap) {
568    bias = _other_bitmap->bias;
569    if (!do_reserve(_other_bitmap->capacity, false)) return false;
570    memcpy(count_true_per_index, _other_bitmap->count_true_per_index, (capacity * sizeof(long)));
571    for (long i = 0; i < capacity; ++i) {
572        if (!data[i]) data[i] = new PS_BitSet_Fast(bias, _other_bitmap->data[i]->getCapacity());
573        if (!data[i]->copy(_other_bitmap->data[i])) return false;
574    }
575    max_row = _other_bitmap->max_row;
576    return true;
577}
578
579
580bool PS_BitMap_Counted::reserve(const long _capacity) {
581    return do_reserve(_capacity, true);
582}
583bool PS_BitMap_Counted::do_reserve(const long _capacity, const bool _init_sets) {
584    PS_BitSet **new_data;
585    long *new_counts;
586    if (_capacity <= capacity) return true;                      // smaller or same size requested ?
587    long new_data_bytes   = _capacity * sizeof(PS_BitSet*);
588    long old_data_bytes   =  capacity * sizeof(PS_BitSet*);
589    long new_counts_bytes = _capacity * sizeof(long);
590    long old_counts_bytes =  capacity * sizeof(long);
591    //
592    // allocate new memory
593    //
594    new_data   = (PS_BitSet **)malloc(new_data_bytes);
595    new_counts = (long *)malloc(new_counts_bytes);
596    //
597    // test is we got the memory we wanted
598    //
599    if (!new_data || !new_counts) {
600        // failed to allocate all memory so give up the parts we got
601        if (new_data)   free(new_data);
602        if (new_counts) free(new_counts);
603        return false;
604    }
605    //
606    // initialize new data-array
607    //
608    if (capacity > 0) memcpy(new_data, data, old_data_bytes);    // copy old pointers
609    if (data) free(data);                                        // free old memory
610    data = new_data;
611    if (_init_sets) {
612        for (long i = capacity; i < _capacity; ++i) {            // init new requested bitsets
613            data[i] = new PS_BitSet_Fast(bias, i+1);             // init field
614            if (!data[i]) return false;                          // check success
615        }
616    }
617    else {
618        for (long i = capacity; i < _capacity; ++i) {
619            data[i] = NULp;
620        }
621    }
622    //
623    // initialize new counts-arrays
624    //
625    if (capacity > 0) memcpy(new_counts, count_true_per_index, old_counts_bytes);
626    memset(new_counts+old_counts_bytes, 0, new_counts_bytes-old_counts_bytes);
627    if (count_true_per_index) free(count_true_per_index);
628    count_true_per_index = new_counts;
629
630    capacity = _capacity;                                        // store new capacity
631    return true;
632}
633
634
635void PS_BitMap_Counted::print(FILE *out) {
636    fprintf(out, "PS_BitMap_Counted : bias(%1i) max_row(%6li) capacity(%6li)\n", bias, max_row, capacity);
637    for (long i = 0; i < capacity; ++i) {
638        fprintf(out, "[%5li] %6li ", i, count_true_per_index[i]);
639        data[i]->print(out, false);
640    }
641}
642
643
644void PS_BitMap_Counted::printGNUplot(const char *_title, char *_buffer, PS_FileBuffer *_file) {
645    // write title and header of bitmap
646    long size;
647    size = sprintf(_buffer, "# %s\n#PS_BitMap_Counted : bias(%1i) max_row(%li) capacity(%li)\n#col row - index of a true\n", _title, bias, max_row, capacity);
648    _file->put(_buffer, size);
649
650    // write indices of trues per row
651    PS_BitSet::IndexSet trues;
652    for (long row = 0;
653          row < capacity;
654          ++row) {
655        data[row]->getTrueIndices(trues);
656        for (PS_BitSet::IndexSet::iterator col = trues.begin();
657              col != trues.end();
658              ++col) {
659            size = sprintf(_buffer, "%li %li\n", *col, row);
660            _file->put(_buffer, size);
661        }
662    }
663
664    // write dataset separator and header of counters
665    size = sprintf(_buffer, "\n\n# speciesID count (of trues)\n");
666    _file->put(_buffer, size);
667
668    // write counters per species
669    map<long, long> species_per_count;
670    for (long row = 0;
671          row < capacity;
672          ++row) {
673        size = sprintf(_buffer, "%li %li\n", row, count_true_per_index[row]);
674        _file->put(_buffer, size);
675        ++species_per_count[count_true_per_index[row]];
676    }
677
678    // write dataset separator and header of counters
679    size = sprintf(_buffer, "\n\n# count (of trues) count (of species)\n");
680    _file->put(_buffer, size);
681    for (map<long, long>::iterator count = species_per_count.begin();
682          count != species_per_count.end();
683          ++count) {
684        size = sprintf(_buffer, "%li %li\n", count->first, count->second);
685        _file->put(_buffer, size);
686    }
687
688    _file->flush();
689}
690
691
692void PS_BitMap_Counted::recalcCounters() {
693    printf("PS_BitMap_Counted::recalcCounters()\n");
694    memset(count_true_per_index, 0, capacity * sizeof(long));
695    for (long row = 0; row <= max_row; ++row) {
696        PS_BitSet *row_data = data[row];
697        if (row_data->getMaxUsedIndex() > row) printf("row %4li 0..%li ??\n", row, row_data->getMaxUsedIndex());
698        for (long col = 0; col <= row_data->getMaxUsedIndex(); ++col) {
699            if (row_data->Get(col)) {
700                ++count_true_per_index[col];
701                if (row != col) ++count_true_per_index[row];   // don't count diagonal trues twice
702            }
703        }
704    }
705}
706
707#else
708#error ps_bitmap.hxx included twice
709#endif
Note: See TracBrowser for help on using the repository browser.