CGR Localization
 All Classes Namespaces Files Functions Variables Macros Pages
util.h
1 /*======================================================================
2  Util.h : Numerical utility functions
3  ----------------------------------------------------------------------
4  Copyright (C) 1999-2002 James R. Bruce
5  Modified by Joydeep Biswas, 2010
6  School of Computer Science, Carnegie Mellon University
7  ----------------------------------------------------------------------
8  This software is distributed under the GNU General Public License,
9  version 2. If you do not have a copy of this licence, visit
10  www.gnu.org, or write: Free Software Foundation, 59 Temple Place,
11  Suite 330 Boston, MA 02111-1307 USA. This program is distributed
12  in the hope that it will be useful, but WITHOUT ANY WARRANTY,
13  including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  ======================================================================*/
15 
16 #ifndef __UTIL_H__
17 #define __UTIL_H__
18 
19 #include <stdint.h>
20 #include <math.h>
21 #include <string.h>
22 #include <algorithm>
23 #include <stdio.h>
24 
25 // UnusedVar can suppress gcc warnings about unused variables.
26 // MustCheckReturn lets a function emit a warning if its return value
27 // isn't used
28 #if __GNUC__ >= 3
29 # define UnusedVar __attribute__((unused))
30 # define MustUseResult __attribute__((warn_unused_result))
31 #else
32 # define UnusedVar
33 # define MustUseResult
34 #endif
35 
36 // This seems to be missing from some systems
37 #ifndef M_2PI
38 #define M_2PI 6.28318530717958647693
39 #endif
40 
41 using std::sort;
42 
43 #if 1
44 
45 using std::min;
46 using std::max;
47 using std::swap;
48 
49 #else
50 template <class num>
51 inline num max(num a,num b)
52 {
53  return((a > b)? a : b);
54 }
55 
56 template <class num>
57 inline num min(num a,num b)
58 {
59  return((a < b)? a : b);
60 }
61 
62 template <class data>
63 inline void swap(data &a,data &b)
64 {
65  data t;
66  t = a;
67  a = b;
68  b = t;
69 }
70 #endif
71 
73 template <class num>
74 inline num minVar(int n,num* list)
75 {
76  num min, a;
77  min = list[0];
78  for(int i = 1; i <= n; i++) {
79  a = list[i];
80  if(a < min)
81  min = a;
82  }
83  return min;
84 }
85 
87 template <class num>
88 inline num maxVar(int n,num* list)
89 {
90  num max, a;
91  max = list[0];
92  for(int i = 1; i <= n; i++) {
93  a = list[i];
94  if(a > max)
95  max = a;
96  }
97  return max;
98 }
99 
101 #ifndef frand
102 inline double frand()
103 {
104  return ( double(rand())/double(RAND_MAX) );
105 }
106 
107 template <class num>
108 inline num frand(num minVal,num maxVal)
109 {
110  return ( num(rand())/num(RAND_MAX)*(maxVal-minVal) +minVal );
111 }
112 #endif
113 
115 template <class num>
116 inline num randn(num stdDev = 1.0, num mean = 0.0)
117 {
118  //Uses Box-Muller transform to turn a pair of uniform random numbers into a pair of gaussian random numbers
119  num u1 = ((num)rand())/((num)RAND_MAX);
120  num u2 = ((num)rand())/((num)RAND_MAX);
121  num z1 = sqrt(-2.0*log(u1)) * sin(M_2PI*u2);
122  //float z2 = sqrt(-2*log(u1)) * cos(2*M_PI*u2);
123  num x1 = z1 * stdDev + mean;
124  //float x2 = z2 * std_dev + mean;
125  return x1;
126 }
127 
129 template <class num>
130 inline void randn2(num &x1, num &x2)
131 {
132  //Uses Box-Muller transform to turn a pair of uniform random numbers into a pair of gaussian random numbers
133  num u1 = ((num)rand())/((num)RAND_MAX);
134  num u2 = ((num)rand())/((num)RAND_MAX);
135  num r = sqrt(-2.0*log(u1));
136  x1 = r * sin(M_2PI*u2);
137  x2 = r * cos(M_2PI*u2);
138 }
139 
140 template <class num1,class num2>
141 inline num1 bound(num1 x,num2 low,num2 high) MustUseResult;
142 
143 template <class num1,class num2>
144 inline num1 bound(num1 x,num2 low,num2 high)
145 {
146  if(x < low ) x = low;
147  if(x > high) x = high;
148  return(x);
149 }
150 
151 template <class num1,class num2>
152 inline num1 abs_bound(num1 x,num2 range) MustUseResult;
153 
154 template <class num1,class num2>
155 inline num1 abs_bound(num1 x,num2 range)
156 // bound absolute value x in [-range,range]
157 {
158  if(x < -range) x = -range;
159  if(x > range) x = range;
160  return(x);
161 }
162 
163 template <class num>
164 inline num abs_max(num a,num b)
165 {
166  return((fabs(a) > fabs(b))? a : b);
167 }
168 
169 template <class num>
170 inline num abs_min(num a,num b)
171 {
172  return((fabs(a) < fabs(b))? a : b);
173 }
174 
175 template <class num>
176 inline num max3(num a,num b,num c)
177 {
178  if(a > b){
179  return((a > c)? a : c);
180  }else{
181  return((b > c)? b : c);
182  }
183 }
184 
185 template <class num>
186 inline num min3(num a,num b,num c)
187 {
188  if(a < b){
189  return((a < c)? a : c);
190  }else{
191  return((b < c)? b : c);
192  }
193 }
194 
195 template <class num>
196 inline num max4(num a,num b,num c,num d)
197 {
198  num x,y;
199  x = max(a,b);
200  y = max(c,d);
201  return(max(x,y));
202 }
203 
204 template <class num>
205 inline num min4(num a,num b,num c,num d)
206 {
207  num x,y;
208  x = min(a,b);
209  y = min(c,d);
210  return(min(x,y));
211 }
212 
213 template <class num>
214 inline num max_abs(num a,num b)
215 {
216  return((fabs(a) > fabs(b))? a : b);
217 }
218 
219 template <class num>
220 inline num min_abs(num a,num b)
221 {
222  return((fabs(a) < fabs(b))? a : b);
223 }
224 
225 template <class data_t>
226 inline int max_idx(data_t *arr,int num)
227 {
228  int mi = 0;
229  for(int i=1; i<num; i++){
230  if(arr[i] > arr[mi]) mi = i;
231  }
232  return(mi);
233 }
234 
235 template <class data_t>
236 inline int min_idx(data_t *arr,int num)
237 {
238  int mi = 0;
239  for(int i=1; i<num; i++){
240  if(arr[i] < arr[mi]) mi = i;
241  }
242  return(mi);
243 }
244 
245 template <class num>
246 inline void sort(num &a,num &b,num &c)
247 {
248  if(a > b) swap(a,b);
249  if(b > c) swap(b,c);
250  if(a > b) swap(a,b);
251 }
252 
253 template <class num>
254 inline bool take_min(num &base,num val)
255 {
256  if(val < base){
257  base = val;
258  return(true);
259  }else{
260  return(false);
261  }
262 }
263 
264 template <class num>
265 inline bool take_max(num &base,num val)
266 {
267  if(val > base){
268  base = val;
269  return(true);
270  }else{
271  return(false);
272  }
273 }
274 
275 template <class real>
276 inline real sq(real x) MustUseResult;
277 
278 template <class real>
279 real sq(real x)
280 {
281  return(x * x);
282 }
283 
284 template <class real>
285 inline real cube(real x) MustUseResult;
286 
287 template <class real>
288 real cube(real x)
289 {
290  return(x * x * x);
291 }
292 
293 template <class num>
294 inline num sign_nz(num x)
295 {
296  return((x >= 0)? 1 : -1);
297 }
298 
299 template <class num>
300 inline num sign_eq(num a,num b)
301 {
302  return((a*b)>=0);
303 }
304 
305 template <class num>
306 inline num sign(num x)
307 {
308  return((x >= 0)? (x > 0) : -1);
309 }
310 
311 template <class bool_t>
312 inline void toggle(bool_t &b)
313 {
314  b = !b;
315 }
316 
317 template <class num>
318 inline num gcd(num x,num y)
319 // returns greatest common divisor of x,y
320 // NOTE: untested
321 {
322  int w;
323  while (y != 0) {
324  w = x % y;
325  x = y;
326  y = w;
327  }
328  return x;
329 }
330 
331 template <class num>
332 num lcm(num x,num y)
333 // returns least common multiple of x,y
334 // NOTE: untested
335 {
336  num d = gcd(x,y);
337  num r = (x / d) * (y / d);
338  // num r = (x * y) / d; // faster but more likely to overflow
339  return(r);
340 }
341 
342 template <class num>
343 inline num mod(num x,num m)
344 // returns x mod m, where x e [0,m-1]
345 // note this is different from %, which can return negative numbers
346 {
347  return(((x % m) + m) % m);
348 }
349 
350 template <class real>
351 inline real fmodt(real x,real m)
352 // Does a real modulus the *right* way, using
353 // truncation instead of round to zero.
354 {
355  return(x - floor(x / m)*m);
356 }
357 
358 template <class real>
359 inline real ramp(real x,real x0,real x1)
360 // linear ramp from f(x0)=0 to f(x1)=1, with output bounded to [0,1]
361 // returns f(x)
362 {
363  if(x < x0) return(0);
364  if(x > x1) return(1);
365  return((x - x0) / (x1 - x0));
366 }
367 
368 template <class real>
369 inline real ramp(real x, real x0,real y0, real x1,real y1)
370 // linear ramp from f(x0)=y0 to f(x1)=y1, with output bounded to [y0,y1]
371 // returns f(x)
372 {
373  if(x < x0) return(y0);
374  if(x > x1) return(y1);
375  return(y0 + (y1 - y0) * (x - x0) / (x1 - x0));
376 }
377 
378 template <class num,class num2>
379 inline num bool_sat_count(num cnt,num2 min,num2 max,bool val)
380 // Saturating counter of a boolean value, clipped to the range
381 // [min,max]. True values increment the counter (up to max), while
382 // false values decrement the counter (down to min).
383 {
384  if(val){
385  return((cnt < max)? cnt+1 : max);
386  }else{
387  return((cnt > min)? cnt-1 : min);
388  }
389 }
390 
391 
392 //==== Bitwise Utilities =============================================//
393 
394 template <class num>
395 inline bool one_bit_set(num n)
396 // returns true if num has only one bit set, i.e. n=2^k for some integer k
397 {
398  return(n!=0 && ((-n) & n) == n);
399 }
400 
401 template <class num>
402 inline num num_bits_set(num x)
403 // returns the number of bits set in x
404 {
405  num numBitsSet = 0;
406  for(num i = 0; i<sizeof(num)*8; i++){
407  if(x&(1<<i))
408  numBitsSet++;
409  }
410  return numBitsSet;
411 }
412 
413 template <class num1,class num2>
414 inline bool all_bits_set(num1 x,num2 m)
415 // returns true if all set bits in <m> are present in <x>
416 {
417  return((x & m) == m);
418 }
419 
420 template <class num1,class num2>
421 inline bool any_bits_set(num1 x,num2 m)
422 // returns true if any set bits in <m> are present in <x>
423 {
424  return((x & m) != 0);
425 }
426 
427 //==== Angle Utilities ===============================================//
428 
430 template <class real>
431 inline real angle_mod(real angle) MustUseResult;
432 
433 template <class real>
434 real angle_mod(real angle)
435 {
436  angle -= M_2PI * rint(angle / M_2PI);
437 
438  return(angle);
439 }
440 
442 template <class real>
443 inline real angle_long(real angle)
444 {
445  if (angle < 0.0) {
446  return M_2PI + angle;
447  } else {
448  return -M_2PI + angle;
449  }
450 }
451 
453 template <class real>
454 inline real angle_pos(real angle)
455 {
456  return(fmod(angle+M_2PI,M_2PI));
457 }
458 
460 template <class real>
461 inline real angle_diff(real a,real b)
462 {
463  real d;
464 
465  d = a - b;
466  d -= M_2PI * rint(d / M_2PI);
467 
468  return(d);
469 }
470 
472 template <class real>
473 inline real angle_dist(real a,real b)
474 {
475  return(fabs(angle_mod(a-b)));
476 }
477 
480 template <class real>
481 inline real avg_angle(real left,real right)
482 {
483  real result;
484 
485  if(left < right) left += 2*M_PI;
486  result = (left + right)/2;
487  if(result > M_PI) result -= 2*M_PI;
488 
489  return(result);
490 }
491 
492 template <class real>
493 inline real abs_bound_angle(real bound_angle,real tolerance,real a) MustUseResult;
494 
498 template <class real>
499 real abs_bound_angle(real bound_angle,real tolerance,real a)
500 {
501  real x = angle_mod(a - bound_angle);
502  x = abs_bound(x,tolerance);
503  return(angle_mod(x + bound_angle));
504 }
505 
506 //==== Array Functions ===============================================//
507 
508 template <class data>
509 int find_item(const data *arr,int num,data key)
510 {
511  int i = 0;
512  while(i<num && !(arr[i]==key)) i++;
513  return(i);
514 }
515 
516 template <class data,class num>
517 data *alloc_array(data *arr,num &size,num new_size) MustUseResult;
518 
519 template <class data,class num>
520 data *alloc_array(data *arr,num &size,num new_size)
521 {
522  if((arr!=NULL && new_size==size) ||
523  (arr==NULL && new_size==0)) return(arr);
524 
525  delete[](arr);
526  arr = new data[new_size];
527  size = (arr != NULL)? new_size : 0;
528  return(arr);
529 }
530 
531 template <class data,class num>
532 data *resize_array(data *arr,num &size,num new_size,num cur_used)
533 {
534  if((arr!=NULL && new_size==size) ||
535  (arr==NULL && new_size==0)) return(arr);
536 
537  data *narr = new data[new_size];
538  if(narr){
539  // copy existing data
540  for(num i=0; i<cur_used; i++) narr[i] = arr[i];
541  delete[](arr);
542  size = new_size;
543  return(narr);
544  }else{
545  // could not resize
546  return(arr);
547  }
548 }
549 
550 template <class data,class num>
551 void free_array(data *&arr,num &size)
552 {
553  delete[](arr);
554  arr = NULL;
555  size = 0;
556 }
557 
558 template <class data,class num>
559 data *alloc_array2(data *arr,num &w,num &h,
560  int new_w,int new_h) MustUseResult;
561 
562 template <class data,class num>
563 data *alloc_array2(data *arr,num &w,num &h,
564  int new_w,int new_h)
565 {
566  int size = w * h;
567  int new_size = new_w * new_h;
568 
569  if((arr!=NULL && new_size==size) ||
570  (arr==NULL && new_size==0)) return(arr);
571 
572  delete[](arr);
573  arr = new data[new_size];
574  if(arr){
575  w = new_w;
576  h = new_h;
577  }else{
578  w = h = 0;
579  }
580 
581  return(arr);
582 }
583 
584 template <class data>
585 void set_range(data *arr,int start,int num,const data &val)
586 {
587  num += start;
588  for(int i=start; i<num; i++) arr[i] = val;
589 }
590 
591 //==== Template-based Memory Operations ==============================//
592 
593 template <class data>
594 inline int mcopy(data *dest,data *src,int num)
595 {
596  int i;
597 
598  for(i=0; i<num; i++) dest[i] = src[i];
599 
600  return(num);
601 }
602 
603 template <class data>
604 inline data mset(data *dest,data val,int num)
605 {
606  int i;
607 
608  for(i=0; i<num; i++) dest[i] = val;
609 
610  return(val);
611 }
612 
613 template <class data>
614 inline void mzero(data &d)
615 {
616  memset(&d,0,sizeof(d));
617 }
618 
619 template <class data>
620 inline void mzero(data *d,int n)
621 {
622  memset(d,0,sizeof(data)*n);
623 }
624 
625 #if __GNUC__ >= 3
626 # define likely(x) __builtin_expect(!!(x),1)
627 # define unlikely(x) __builtin_expect(!!(x),0)
628 #else
629 # define likely(x) (x)
630 # define unlikely(x) (x)
631 #endif
632 
633 #endif