source: tags/ms_r18q1/CONSENSUS_TREE/CT_part.hxx

Last change on this file was 16628, checked in by westram, 6 years ago
  • reintegrates 'vectorize' into 'trunk'
    • fixes #700
      • documented vectorization-checks
      • fine-grained check based on gcc-version
    • drops old gcc-versions (<4.4.3)
    • new attribute __ATTR__DONT_VECTORIZE
      • disabled vectorization of POS_TREE2::init_static() for newer gcc-versions (generated code fails tests)
    • added a bunch of new vectorization-checks (probably irrelevant to overall performance)
  • adds: log:branches/vectorize@15531:16585,16595:16627
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1// ============================================================= //
2//                                                               //
3//   File      : CT_part.hxx                                     //
4//   Purpose   :                                                 //
5//                                                               //
6//   Institute of Microbiology (Technical University Munich)     //
7//   http://www.arb-home.de/                                     //
8//                                                               //
9// ============================================================= //
10
11#ifndef CT_PART_HXX
12#define CT_PART_HXX
13
14#ifndef ARBTOOLS_H
15#include <arbtools.h>
16#endif
17#ifndef ARBDB_BASE_H
18#include <arbdb_base.h>
19#endif
20#ifndef CT_DEF_HXX
21#include "CT_def.hxx"
22#endif
23#ifndef ARB_ASSERT_H
24#include <arb_assert.h>
25#endif
26#ifndef ARB_MEM_H
27#include <arb_mem.h>
28#endif
29
30
31typedef unsigned int PELEM;
32class PART;
33
34#if defined(ASSERTION_USED)
35CONSTEXPR_INLINE bool diff_smaller_epsilon(double d, double eps) {
36    return abs(d)<eps;
37}
38CONSTEXPR_INLINE bool is_similar(double d1, double d2, double eps) {
39    return diff_smaller_epsilon(d1-d2, eps);
40}
41#endif
42
43class PartitionSize {
44    PELEM cutmask;  // this mask is used to zero unused bits from the last long (in PART::p)
45    int   longs;    // number of longs per part
46    int   bits;     // number of bits per part ( = overall number of species)
47   
48    mutable size_t id;      // unique id (depending on part creation order, which depends on the added trees)
49
50public:
51    PartitionSize(int len);
52
53    int get_longs() const { return longs; }
54    int get_bits() const { return bits; }
55    size_t get_unique_id() const { id++; return id; }
56    PELEM get_cutmask() const { return cutmask; }
57
58    PART *create_root() const;
59    PELEM *alloc_mem() const { return ARB_calloc<PELEM>(get_longs()); }
60};
61
62class PART {
63    const PartitionSize *info;
64
65    PELEM   *p;
66    GBT_LEN  len;    // length between two nodes (weighted by weight)
67    double   weight; // sum of weights
68    size_t   id;
69    int      members;
70
71    PART(const PART& other)
72        : info(other.info),
73          p(info->alloc_mem()),
74          len(other.len),
75          weight(other.weight),
76          id(info->get_unique_id()),
77          members(other.members)
78    {
79        int longs = get_longs();
80        for (int i = 0; i<longs; ++i) { // IRRELEVANT_LOOP
81            p[i] = other.p[i];
82        }
83        arb_assert(is_valid());
84    }
85    DECLARE_ASSIGNMENT_OPERATOR(PART);
86
87    int count_members() const;
88
89    void set_weight(double pc) {
90        double lenScale  = pc/weight;
91        weight           = pc;
92        len             *= lenScale;
93    }
94
95    static int byte_pos(int pos) { return pos / sizeof(PELEM) / 8; }
96    static PELEM bit_mask(int pos) { return 1 << (pos % (sizeof(PELEM)*8)); }
97
98public:
99
100    PART(const PartitionSize* size_info, double weight_)
101        : info(size_info),
102          p(info->alloc_mem()),
103          len(0),
104          weight(weight_),
105          id(info->get_unique_id()),
106          members(0)
107    {
108        arb_assert(is_valid());
109    }
110    ~PART() {
111        free(p);
112    }
113
114    PART *clone() const { return new PART(*this); }
115
116    int get_longs() const { return info->get_longs(); }
117    int get_maxsize() const { return info->get_bits(); }
118    PELEM get_cutmask() const { return info->get_cutmask(); }
119
120    bool is_valid() const {
121        PELEM last = p[get_longs()-1];
122
123        bool only_valid_bits    = (last&get_cutmask()) == last;
124        bool valid_member_count = members >= 0 && members <= get_maxsize();
125        bool valid_weight       = weight >= 0.0;
126
127        return only_valid_bits && valid_member_count && valid_weight;
128    }
129
130    void setbit(int pos) {
131        /*! set the bit at position 'pos'
132         */
133        arb_assert(is_valid());
134
135        int   idx = byte_pos(pos);
136        PELEM bit = bit_mask(pos);
137
138        if (!(p[idx]&bit)) {
139            p[idx] |= bit;
140            members++;
141        }
142
143        arb_assert(is_valid());
144    }
145    bool bit_is_set(int pos) const {
146        /*! return true if the bit at the position 'pos' is set
147         */
148        arb_assert(is_valid());
149
150        int   idx = byte_pos(pos);
151        PELEM bit = bit_mask(pos);
152
153        return p[idx] & bit;
154    }
155
156    void set_len(GBT_LEN length) {
157        arb_assert(is_valid());
158        len = length*weight;
159    }
160    GBT_LEN get_len() const {
161        if (weight == 0.0) {
162            // if weight is 0.0 = > branch never occurred!
163            return 1.0; // return worst distance between these nodes (which are disjunct trees)
164        }
165        return len/weight;
166    }
167
168    double get_weight() const { return weight; }
169
170    void addWeightAndLength(const PART *other) {
171        weight += other->weight;
172        len    += other->len;
173    }
174
175    void takeMean(double overall_weight) {
176        set_weight(get_weight() / overall_weight);
177        arb_assert(is_valid());
178        arb_assert(weight <= 1.0);
179    }
180
181    void set_faked_weight(double w) { set_weight(w); }
182
183    void invert();
184    void invertInSuperset(const PART *superset);
185
186    bool is_standardized() const;
187    void standardize();
188
189    void add_members_from(const PART *source);
190
191    bool is_subset_of(const PART *other) const {
192        int longs = get_longs();
193        for (int i=0; i<longs; i++) {
194            if ((p[i] & other->p[i]) != p[i]) {
195                return false;
196            }
197        }
198        return true;
199    }
200    bool is_real_son_of(const PART *father) const { return is_subset_of(father) && differs(father); }
201
202    bool overlaps_with(const PART *other) const;
203    bool disjunct_from(const PART *other) const { return !overlaps_with(other); }
204
205    bool equals(const PART *other) const;
206    bool differs(const PART *other) const { return !equals(other); }
207
208    int index() const;
209    unsigned key() const;
210
211    int get_members() const { return members; }
212    int get_nonmembers() const { return get_maxsize() - get_members(); }
213
214    bool is_leaf_edge() const { int size = members; return size == 1 || size == (get_maxsize()-1); }
215    int distance_to_tree_center() const { return abs(get_maxsize()/2 - members); }
216
217    int insertionOrder_cmp(const PART *other) const;
218    int topological_cmp(const PART *other) const;
219
220#if defined(NTREE_DEBUG_FUNCTIONS)
221    void print() const;
222    static void start_pretty_printing(const class CharPtrArray& names_);
223    static void stop_pretty_printing();
224#endif
225};
226
227#else
228#error CT_part.hxx included twice
229#endif // CT_PART_HXX
Note: See TracBrowser for help on using the repository browser.