1 static char rcsid[] = "$Id: interval.c 207855 2017-06-29 20:34:17Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include "interval.h"
7 #include <stdio.h>
8 #include <stdlib.h> /* For qsort */
9 #include "mem.h"
10
11
12 #ifdef DEBUG
13 #define debug(x) x
14 #else
15 #define debug(x)
16 #endif
17
18
19 #define T Interval_T
20
21 T
Interval_new(Chrpos_T low,Chrpos_T high,int type)22 Interval_new (Chrpos_T low, Chrpos_T high, int type) {
23 T new = (T) MALLOC(sizeof(*new));
24
25 if (low < high) {
26 new->low = low;
27 new->high = high;
28 new->sign = +1;
29 } else if (low > high) {
30 new->low = high;
31 new->high = low;
32 new->sign = -1;
33 } else {
34 new->low = low;
35 new->high = high;
36 new->sign = 0;
37 }
38 new->type = type;
39 return new;
40 }
41
42 T
Interval_copy(T old)43 Interval_copy (T old) {
44 T new = (T) MALLOC(sizeof(*new));
45
46 new->low = old->low;
47 new->high = old->high;
48 new->sign = old->sign;
49 new->type = old->type;
50 return new;
51 }
52
53 void
Interval_copy_existing(T dest,T src)54 Interval_copy_existing (T dest, T src) {
55 dest->low = src->low;
56 dest->high = src->high;
57 dest->sign = src->sign;
58 dest->type = src->type;
59 return;
60 }
61
62 void
Interval_free(T * old)63 Interval_free (T *old) {
64 if (*old) {
65 FREE(*old);
66 }
67 return;
68 }
69
70 void
Interval_print(T this)71 Interval_print (T this) {
72 printf("%u %u %d",this->low,this->high,this->type);
73 return;
74 }
75
76 Chrpos_T
Interval_low(T this)77 Interval_low (T this) {
78 return this->low;
79 }
80
81 Chrpos_T
Interval_high(T this)82 Interval_high (T this) {
83 return this->high;
84 }
85
86 void
Interval_store_length(T this,Chrpos_T length)87 Interval_store_length (T this, Chrpos_T length) {
88 this->high = this->low - 1 + length;
89 return;
90 }
91
92 int
Interval_sign(T this)93 Interval_sign (T this) {
94 return this->sign;
95 }
96
97 Chrpos_T
Interval_length(T this)98 Interval_length (T this) {
99 return this->high - this->low + 1;
100 }
101
102 int
Interval_type(T this)103 Interval_type (T this) {
104 return this->type;
105 }
106
107 /* Have to subtract 1 because intervals array is zero-based */
108 Chrpos_T
Interval_array_low(struct T * intervals,int index)109 Interval_array_low (struct T *intervals, int index) {
110 return intervals[index-1].low;
111 }
112
113 /* Have to subtract 1 because intervals array is zero-based */
114 Chrpos_T
Interval_array_high(struct T * intervals,int index)115 Interval_array_high (struct T *intervals, int index) {
116 return intervals[index-1].high;
117 }
118
119
120 /* Have to subtract 1 because intervals array is zero-based */
121 bool
Interval_is_contained(Chrpos_T x,struct T * intervals,int index)122 Interval_is_contained (Chrpos_T x, struct T *intervals, int index) {
123 Chrpos_T low = intervals[index-1].low;
124 Chrpos_T high = intervals[index-1].high;
125
126 if (low <= x && x <= high) {
127 return true;
128 } else {
129 return false;
130 }
131 }
132
133 /* Have to subtract 1 because intervals array is zero-based */
134 bool
Interval_overlap_p(Chrpos_T x,Chrpos_T y,struct T * intervals,int index)135 Interval_overlap_p (Chrpos_T x, Chrpos_T y, struct T *intervals, int index) {
136 Chrpos_T low = intervals[index-1].low;
137 Chrpos_T high = intervals[index-1].high;
138
139 if (x <= high && y >= low) {
140 return true;
141 } else {
142 return false;
143 }
144 }
145
146 #if 0
147 /* Was previously called Interval_contained_p */
148 /* Have to subtract 1 because intervals array is zero-based */
149 bool
150 Interval_contains_region_p (unsigned int x, unsigned int y, struct T *intervals, int index) {
151 unsigned int low = intervals[index-1].low;
152 unsigned int high = intervals[index-1].high;
153
154 /* interval contains region */
155 if (low <= x && y <= high) {
156 return true;
157 } else {
158 return false;
159 }
160 }
161
162 bool
163 Interval_contained_by_region_p (unsigned int x, unsigned int y, struct T *intervals, int index) {
164 unsigned int low = intervals[index-1].low;
165 unsigned int high = intervals[index-1].high;
166
167 /* region contains interval */
168 if (x <= low && high <= y) {
169 return true;
170 } else {
171 return false;
172 }
173 }
174 #endif
175
176
177 /************************************************************************/
178 /* These sorting procedures are accessed only by iit-write.c */
179 /************************************************************************/
180
181 static struct T *current_intervals;
182
183 /* Have to subtract 1 because intervals array is zero-based */
184 static int
sigma_compare(const void * i,const void * j)185 sigma_compare (const void *i, const void *j) {
186 int x = * (int *) i;
187 int y = * (int *) j;
188
189 Chrpos_T a = current_intervals[x-1].low;
190 Chrpos_T b = current_intervals[y-1].low;
191
192 if (a < b) {
193 return -1;
194 } else if (a > b) {
195 return 1;
196 } else {
197 return 0;
198 }
199 }
200
201 /* Have to subtract 1 because intervals array is zero-based */
202 static int
omega_compare(const void * i,const void * j)203 omega_compare (const void *i, const void *j) {
204 int x = * (int *) i;
205 int y = * (int *) j;
206
207 Chrpos_T a = current_intervals[x-1].high;
208 Chrpos_T b = current_intervals[y-1].high;
209
210 if (a < b) {
211 return -1;
212 } else if (a > b) {
213 return 1;
214 } else {
215 return 0;
216 }
217 }
218
219
220
221 /* These routines sort table[i..j] in place. Assume that
222 current_intervals has been set. */
223 void
Interval_qsort_by_sigma(int * table,int i,int j,struct T * intervals,bool presortedp)224 Interval_qsort_by_sigma (int *table, int i, int j, struct T *intervals,
225 bool presortedp) {
226 int k;
227 bool sortedp = true;
228
229 if (presortedp == true) {
230 for (k = i + 1; sortedp == true && k < j; k++) {
231 if (intervals[k-1].low > intervals[k].low) {
232 fprintf(stderr,"Intervals are not sorted by sigma\n");
233 sortedp = false;
234 }
235 }
236 if (sortedp == true) {
237 return;
238 }
239 }
240
241 current_intervals = intervals;
242 qsort(&(table[i]), j - i + 1, sizeof(int), sigma_compare);
243 return;
244 }
245
246 void
Interval_qsort_by_omega(int * table,int i,int j,struct T * intervals,bool presortedp)247 Interval_qsort_by_omega (int *table, int i, int j, struct T *intervals,
248 bool presortedp) {
249 int k;
250 bool sortedp = true;
251
252 if (presortedp == true) {
253 for (k = i + 1; sortedp == true && k < j; k++) {
254 if (intervals[k-1].high > intervals[k].high) {
255 fprintf(stderr,"Intervals are not sorted by omega\n");
256 sortedp = false;
257 }
258 }
259 if (sortedp == true) {
260 return;
261 }
262 }
263
264 current_intervals = intervals;
265 qsort(&(table[i]), j - i + 1, sizeof(int), omega_compare);
266 return;
267 }
268
269
270 int
Interval_cmp(const void * a,const void * b)271 Interval_cmp (const void *a, const void *b) {
272 T x = * (T *) a;
273 T y = * (T *) b;
274
275 debug(printf("Comparing %u..%u with %u..%u => ",x->low,x->high,y->low,y->high));
276 if (x->low < y->low) {
277 debug(printf("-1\n"));
278 return -1;
279 } else if (x->low > y->low) {
280 debug(printf("+1\n"));
281 return +1;
282 } else if (x->high < y->high) {
283 debug(printf("-1\n"));
284 return -1;
285 } else if (x->high > y->high) {
286 debug(printf("+1\n"));
287 return +1;
288 } else if (x->type < y->type) {
289 debug(printf("-1\n"));
290 return -1;
291 } else if (x->type > y->type) {
292 debug(printf("-1\n"));
293 return +1;
294 } else {
295 debug(printf("0\n"));
296 return 0;
297 }
298 }
299
300
301 int
Interval_cmp_low(const void * a,const void * b)302 Interval_cmp_low (const void *a, const void *b) {
303 T x = * (T *) a;
304 T y = * (T *) b;
305
306 debug(printf("Comparing %u..%u with %u..%u => ",x->low,x->high,y->low,y->high));
307 if (x->low < y->low) {
308 debug(printf("-1\n"));
309 return -1;
310 } else if (x->low > y->low) {
311 debug(printf("+1\n"));
312 return +1;
313 } else if (x->type < y->type) {
314 debug(printf("-1\n"));
315 return -1;
316 } else if (x->type > y->type) {
317 debug(printf("-1\n"));
318 return +1;
319 } else {
320 debug(printf("0\n"));
321 return 0;
322 }
323 }
324
325
326 int
Interval_cmp_high(const void * a,const void * b)327 Interval_cmp_high (const void *a, const void *b) {
328 T x = * (T *) a;
329 T y = * (T *) b;
330
331 debug(printf("Comparing %u..%u with %u..%u => ",x->low,x->high,y->low,y->high));
332 if (x->high < y->high) {
333 debug(printf("-1\n"));
334 return -1;
335 } else if (x->high > y->high) {
336 debug(printf("+1\n"));
337 return +1;
338 #if 0
339 /* Not needed by Splicetrie_retrieve_via_introns */
340 } else if (x->type < y->type) {
341 debug(printf("-1\n"));
342 return -1;
343 } else if (x->type > y->type) {
344 debug(printf("-1\n"));
345 return +1;
346 #endif
347 } else {
348 debug(printf("0\n"));
349 return 0;
350 }
351 }
352
353
354 int
Interval_cmp_low_struct(const void * a,const void * b)355 Interval_cmp_low_struct (const void *a, const void *b) {
356 struct T x = * (struct T *) a;
357 struct T y = * (struct T *) b;
358
359 debug(printf("Comparing %u..%u with %u..%u => ",x.low,x.high,y.low,y.high));
360 if (x.low < y.low) {
361 debug(printf("-1\n"));
362 return -1;
363 } else if (x.low > y.low) {
364 debug(printf("+1\n"));
365 return +1;
366 } else if (x.type < y.type) {
367 debug(printf("-1\n"));
368 return -1;
369 } else if (x.type > y.type) {
370 debug(printf("-1\n"));
371 return +1;
372 } else {
373 debug(printf("0\n"));
374 return 0;
375 }
376 }
377
378 int
Interval_windex_cmp(const void * a,const void * b)379 Interval_windex_cmp (const void *a, const void *b) {
380 struct Interval_windex_T x = * (struct Interval_windex_T *) a;
381 struct Interval_windex_T y = * (struct Interval_windex_T *) b;
382
383 return Interval_cmp((void *) &x.interval,(void *) &y.interval);
384 }
385
386