source: tags/cvs_2_svn/CONSENSUS_TREE/CT_part.cxx

Last change on this file was 1258, checked in by westram, 21 years ago
  • CONSENSUS_TREE/CT_part.cxx: - untabified, indented and valgrinded
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/* This module is desined to organize the data structure partitions
2   partitions represent the edges of a tree */
3/* the partitions are implemented as an array of longs */
4/* Each leaf in a GBT-Tree is represented as one Bit in the Partition */
5
6#include <stdio.h>
7#include <stdlib.h>
8
9#include <arbdb.h>
10#include <arbdbt.h>
11
12#include "CT_mem.hxx"
13#include "CT_part.hxx"
14
15PELEM   cutmask;        /* this mask is nessary to cut the not
16                           needed bits from the last long       */
17int     longs = 0,      /* number of longs per part             */
18    plen = 0;       /* number of bits per part              */
19
20
21/** Function to initialize the variables above
22    @PARAMETER  len     number of bits the part should content
23    result:         calculate cutmask, longs, plen */
24void part_init(int len)
25{
26    int i, j;
27
28    /* cutmask is nessary to cut unused bits */
29    j = 8 * sizeof(PELEM);
30    j = len %j;
31    if(!j) j += 8 * sizeof(PELEM);
32    cutmask = 0;
33    for(i=0; i<j; i++) {
34        cutmask <<= 1;
35        cutmask |= 1;
36    }
37    longs = (((len +7) / 8)+sizeof(PELEM)-1) / sizeof(PELEM);
38    plen = len;
39}
40
41
42/** Testfunction to print a part
43    @PARAMETER  p   pointer to the part */
44void part_print(PART *p)
45{
46    int i, j, k=0;
47    PELEM l;
48
49    for(i=0; i<longs; i++) {
50        l = 1;
51        for(j=0; k<plen && size_t(j)<sizeof(PELEM)*8; j++, k++) {
52            if(p->p[i] & l)
53                printf("1");
54            else
55                printf("0");
56            l <<= 1;
57        }
58    }
59
60    printf(":%.2f,%d%%: ", p->len, p->percent);
61}
62
63
64/** construct new part */
65PART *part_new(void)
66{
67    PART *p;
68
69    p = (PART *) getmem(sizeof(PART));
70    p->p = (PELEM *) getmem(longs * sizeof(PELEM));
71
72    return p;
73}
74
75
76/** destruct part
77    @PARAMETER  p   partition */
78void part_free(PART *p)
79{
80    free(p->p);
81    free(p);
82}
83
84
85/** build a partion that totaly constited of 111111...1111 that is needed to
86    build the root of a specific ntree */
87PART *part_root(void)
88{
89    int i;
90    PART *p;
91    p = part_new();
92    for(i=0; i<longs; i++) {
93        p->p[i] = ~p->p[i];
94    }
95    p->p[longs-1] &= cutmask;
96    return p;
97}
98
99
100/** set the bit of the part p at the position pos
101    @PARAMETER  p   partion
102    pos position */
103void part_setbit(PART *p, int pos)
104{
105    p->p[(pos / sizeof(PELEM) / 8)] |= (1 << (pos % (sizeof(PELEM)*8)));
106}
107
108
109
110/* test if the part son is possibly a son of the part father, a father defined
111   in this context as a part covers every bit of his son. needed in CT_ntree
112   @PARAMETER  son part
113   father  part */
114int son(PART *son, PART *father)
115{
116    int i;
117
118    for(i=0; i<longs; i++) {
119        if((son->p[i] & father->p[i]) != son->p[i]) return 0;
120    }
121    return 1;
122}
123
124
125/** test if two parts are brothers, brothers mean that ervery bit in p1 is
126    different from p2 and vice versa. needed in CT_ntree
127    @PARAMETER  p1  part
128    p2  part */
129int brothers(PART *p1, PART *p2)
130{
131    int i;
132
133    for(i=0; i<longs; i++) {
134        if(p1->p[i] & p2->p[i]) return 0;
135    }
136    return 1;
137}
138
139
140/** invert a part
141    @PARAMETER  p   part */
142void part_invert(PART *p)
143{
144    int i;
145
146    for(i=0; i<longs; i++)
147        p->p[i] = ~p->p[i];
148    p->p[longs-1] &= cutmask;
149}
150
151
152/** d  = s or d
153    @PARMETER   s   source
154    d   destionation*/
155void part_or(PART *s, PART *d)
156{
157    int i;
158
159    for(i=0; i<longs; i++) {
160        d->p[i] |= s->p[i];
161    }
162}
163
164
165/** compare two parts p1 and p2
166    result:     1, if p1 equal p2
167    0, else */
168int part_cmp(PART *p1, PART *p2)
169{
170    int i;
171
172    for(i=0; i<longs; i++) {
173        if(p1->p[i] != p2->p[i]) return 0;
174    }
175
176    return 1;
177}
178
179
180/** calculate a hashkey from p, needed in hash */
181int part_key(PART *p)
182{
183    int i;
184    PELEM ph=0;
185
186    for(i=0; i<longs; i++) {
187        ph ^= p->p[i];
188    }
189    i = (int) ph;
190    if(i<0) i *=-1;
191
192    return i;
193}
194
195
196/** set the len of this edge (this part) */
197void part_setlen(PART *p, GBT_LEN len)
198{
199    p->len = len;
200}
201
202
203/** set the percentile appearence of this part in "entrytrees" */
204void part_setperc(PART *p, int perc)
205{
206    p->percent = perc;
207}
208
209
210/** add perc on percent from p */
211void part_addperc(PART *p, int perc)
212{
213    p->percent += perc;
214}
215
216
217/** copy part s in part d
218    @PARAMETER  s   source
219    d   destination */
220void part_copy(PART *s, PART *d)
221{
222    int i;
223
224    for(i=0; i<longs; i++)
225        d->p[i] = s->p[i];
226    d->len = s->len;
227    d->percent = s->percent;
228}
229
230
231/** standartize the partitions, two parts are equal if one is just the inverted
232    version of the other so the standart is defined that the version is the
233    representant, whos first bit is equal 1 */
234void part_standart(PART *p)
235{
236    int i;
237
238    if(p->p[0] & 1) return;
239
240    for(i=0; i<longs; i++)
241        p->p[i] = ~ p->p[i];
242    p->p[longs-1] &= cutmask;
243}
244
245
246/** calculate the first bit set in p, this is only useful if only one bit is set,
247    this is used toidentify leafs in a ntree
248    attention:  p must be != NULL !!! */
249int calc_index(PART *p)
250{
251    int i, pos=0;
252    PELEM p_temp;
253
254    for(i=0; i<longs; i++) {
255        p_temp = p->p[i];
256        pos = i * sizeof(PELEM) * 8;
257        if(p_temp) {
258            for(; p_temp; p_temp >>= 1, pos++) {
259                ;
260            }
261            break;
262        }
263    }
264    return pos-1;
265}
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
Note: See TracBrowser for help on using the repository browser.