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