Apollo 10.0
自动驾驶开放平台
i_basic.h
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17#pragma once
18
19#include <cmath>
20#include <cstring>
21
23
24namespace apollo {
25namespace perception {
26namespace algorithm {
27
28// Compute abs(a)
29inline float IAbs(float a) { return a < 0.f ? -a : a; }
30inline int IAbs(int a) { return a < 0 ? -a : a; }
31inline double IAbs(double a) { return a < 0.0 ? -a : a; }
32
33// Compute a/b, should not template this function, IRec(int, int) should return
34// * double
35inline float IDiv(float a, float b) { return ((b != 0.f) ? (a / b) : 1.0f); }
36inline float IDiv(float a, int b) {
37 return ((b != 0) ? (a / static_cast<float>(b)) : 1.0f);
38}
39inline float IDiv(float a, unsigned int b) {
40 float result = 1.0f;
41 if (b != 0) {
42 result = a / static_cast<float>(b);
43 }
44 return result;
45}
46inline double IDiv(int a, int b) {
47 return ((b != 0) ? (static_cast<double>(a) / b) : 1.0);
48}
49inline double IDiv(unsigned int a, unsigned int b) {
50 double result = 1.0;
51 if (b != 0) {
52 result = static_cast<double>(a) / b;
53 }
54 return result;
55}
56inline double IDiv(double a, double b) { return ((b != 0.0) ? (a / b) : 1.0); }
57inline double IDiv(double a, int b) { return ((b != 0) ? (a / b) : 1.0); }
58inline double IDiv(double a, unsigned int b) {
59 double result = 1.0;
60 if (b != 0) {
61 result = a / b;
62 }
63 return result;
64}
65
66// Compute 1/a, should not template this function,
67// IRecstatic_cast<int> should return
68// * double
69inline float IRec(float a) { return ((a != 0.0f) ? ((1.0f) / a) : 1.0f); }
70inline double IRec(int a) { return ((a != 0) ? ((1.0) / a) : 1.0); }
71inline double IRec(unsigned int a) { return ((a != 0) ? ((1.0) / a) : 1.0); }
72inline double IRec(double a) { return ((a != 0.0) ? ((1.0) / a) : 1.0); }
73
74// Compute sqrt(a), should not template this function, ISqrt(int) should return
75// * double
76inline float ISqrt(float a) { return (a >= 0.0f) ? (sqrtf(a)) : 0.0f; }
77inline double ISqrt(int a) {
78 return (a > 0) ? (sqrt(static_cast<double>(a))) : 0.0;
79}
80inline double ISqrt(unsigned int a) {
81 return (a > 0) ? (sqrt(static_cast<double>(a))) : 0.0;
82}
83inline double ISqrt(double a) { return (a >= 0.0) ? (sqrt(a)) : 0.0; }
84
85// Compute cubic root of a, should not template this function, ICbrt(int) should
86// * return double
87inline float ICbrt(float a) {
88 return (a >= 0.f) ? powf(a, 1.f / 3) : -powf(-a, 1.f / 3);
89}
90inline double ICbrt(int a) {
91 return (a >= 0) ? pow(static_cast<double>(a), 1.0 / 3)
92 : -pow(-static_cast<double>(a), 1.0 / 3);
93}
94inline double ICbrt(unsigned int a) {
95 return pow(static_cast<double>(a), 1.0 / 3);
96}
97inline double ICbrt(double a) {
98 return (a >= 0.0) ? pow(a, 1.0 / 3) : -pow(-a, 1.0 / 3);
99}
100
101// Compute a^2, should not template this function, ISqr(char) and ISqr(unsigned
102// * char) should return int
103inline float ISqr(float a) { return (a * a); }
104inline int ISqr(int a) { return (a * a); }
105inline unsigned int ISqr(unsigned int a) { return (a * a); }
106inline double ISqr(double a) { return (a * a); }
107inline int ISqr(char a) { return (static_cast<int>(a) * static_cast<int>(a)); }
108inline int ISqr(unsigned char a) {
109 return (static_cast<int>(a) * static_cast<int>(a));
110}
111
112// Compute a^3, should not template this function, ICub(char) and ICub(unsigned
113// * char) should return int
114inline float ICub(float a) { return (a * a * a); }
115inline int ICub(int a) { return (a * a * a); }
116inline unsigned int ICub(unsigned int a) { return (a * a * a); }
117inline double ICub(double a) { return (a * a * a); }
118inline int ICub(char a) {
119 return (static_cast<int>(a) * static_cast<int>(a) * static_cast<int>(a));
120}
121inline int ICub(unsigned char a) {
122 return (static_cast<int>(a) * static_cast<int>(a) * static_cast<int>(a));
123}
124
125// Compute log(x)
126inline float ILog(float x) { return ((x > 0.f) ? logf(x) : 0.f); }
127inline double ILog(int x) {
128 return ((x > 0) ? log(static_cast<double>(x)) : 0.0);
129}
130inline double ILog(unsigned int x) {
131 return ((x > 0) ? log(static_cast<double>(x)) : 0.0);
132}
133inline double ILog(double x) { return ((x > 0.0) ? log(x) : 0.0); }
134
135// Compute exp(x)
136inline float IExp(float x) { return (expf(x)); }
137inline double IExp(int x) { return exp(static_cast<double>(x)); }
138inline double IExp(unsigned int x) { return exp(static_cast<double>(x)); }
139inline double IExp(double x) { return exp(x); }
140
141// Compute pow(a, b) => a^b
142inline float IPow(float a, float b) { return powf(a, b); }
143inline float IPow(float a, int b) { return powf(a, static_cast<float>(b)); }
144inline double IPow(int a, int b) {
145 return pow(static_cast<double>(a), static_cast<double>(b));
146}
147inline double IPow(unsigned int a, unsigned int b) {
148 return pow(static_cast<double>(a), static_cast<double>(b));
149}
150inline double IPow(double a, double b) { return pow(a, b); }
151inline double IPow(double a, int b) { return pow(a, static_cast<double>(b)); }
152
153// Compute min(a,b)
154template <typename T>
155inline T IMin(T a, T b) {
156 return ((a <= b) ? a : b);
157}
158
159// Compute max(a,b)
160template <typename T>
161inline T IMax(T a, T b) {
162 return ((a >= b) ? a : b);
163}
164
165// Compute the average of a and b
166template <typename T>
167inline T IAverage(T a, T b) {
168 return (a + b) / 2;
169}
170
171// Compute the sign of a, return:
172// 1 if a>0
173// -1 if a<0
174// 0 if a==0
175template <typename T>
176inline T ISign(T a) {
177 if (a > T(0.0))
178 return (T(1.0));
179 else if (a < T(0.0))
180 return (T(-1.0));
181 else
182 return (T(0.0));
183}
184
185// Compute the sign of a, return:
186// 1 if a>=0
187// -1 if a<0
188template <typename T>
189inline T ISignNeverZero(T a) {
190 if (a >= T(0.0))
191 return (T(1.0));
192 else
193 return (T(-1.0));
194}
195
196// Round a to the nearest integer
197inline int IRound(int a) { return (a); }
198inline int IRound(float a) {
199 return ((a >= 0.f) ? (static_cast<int>(a + 0.5f))
200 : (static_cast<int>(a - 0.5f)));
201}
202inline int IRound(double a) {
203 return ((a >= 0.0) ? (static_cast<int>(a + 0.5))
204 : (static_cast<int>(a - 0.5)));
205}
206
207// Rounds an upward, returning the smallest integral value that is not less than
208// * a
209inline int ICeil(int a) { return (a); }
210inline int ICeil(float a) { return static_cast<int>(ceilf(a)); }
211inline int ICeil(double a) { return static_cast<int>(ceil(a)); }
212
213// Trigonometric functions
214inline float ISin(float alpha) { return sinf(alpha); }
215inline double ISin(double alpha) { return sin(alpha); }
216inline float ICos(float alpha) { return cosf(alpha); }
217inline double ICos(double alpha) { return cos(alpha); }
218inline float ITan(float alpha) { return tanf(alpha); }
219inline double ITan(double alpha) { return tan(alpha); }
220
221inline float IAsin(float alpha) {
222 if (alpha >= 1.f) {
224 }
225 if (alpha < -1.f) {
226 return -Constant<float>::HALF_PI();
227 }
228 return asinf(alpha);
229}
230inline double IAsin(double alpha) {
231 if (alpha >= 1.0) {
233 }
234 if (alpha < -1.0) {
236 }
237 return asin(alpha);
238}
239inline float IAcos(float alpha) {
240 if (alpha >= 1.f) {
241 return 0.f;
242 }
243 if (alpha < -1.f) {
244 return Constant<float>::PI();
245 }
246 return acosf(alpha);
247}
248inline double IAcos(double alpha) {
249 if (alpha >= 1.0) {
250 return 0.0;
251 }
252 if (alpha < -1.0) {
253 return Constant<double>::PI();
254 }
255 return acos(alpha);
256}
257inline float IAtan2(float y, float x) { return atan2f(y, x); }
258inline double IAtan2(double y, double x) { return atan2(y, x); }
259
260inline float IRadiansToDegree(float r) {
262}
263inline double IRadiansToDegree(double r) {
265}
266inline float IDegreeToRadians(float d) {
268}
269inline double IDegreeToRadians(double d) {
271}
272
273// Compute the Hamming distance between two (unsigned) integers (considered as
274// * binary values, that is, as sequences of bits)
275inline unsigned int IHamming(unsigned int a, unsigned int b) {
276 unsigned int distance = 0;
277 unsigned int val = a ^ b; // XOR
278 // Count the number of bits set
279 while (val != 0) {
280 // A bit is set, so increment the count and clear the bit
281 distance++;
282 val &= val - 1;
283 }
284 return distance; // Return the number of different bits
285}
286
287inline unsigned int IHammingLut(unsigned int a, unsigned int b) {
288 unsigned int distance = 0;
289 unsigned int val = a ^ b; // XOR
290 unsigned char *p = (unsigned char *)&val;
291 // count the total # of "1s" in a xor b
292 distance = kIUByteBitCountLut[p[0]] + kIUByteBitCountLut[p[1]] +
293 kIUByteBitCountLut[p[2]] + kIUByteBitCountLut[p[3]];
294 return distance; // Return the number of different bits
295}
296
297// Swap of numbers
298template <typename T>
299inline void ISwap(T &a, T &b) {
300 T temp;
301 temp = a;
302 a = b;
303 b = temp;
304}
305template <typename T>
306inline void ISwap(T *a, T *b, int n) {
307 for (int i = 0; i < n; i++) {
308 ISwap(a[i], b[i]);
309 }
310}
311template <typename T>
312inline void ISwap2(T *a, T *b) {
313 ISwap(a[0], b[0]);
314 ISwap(a[1], b[1]);
315}
316template <typename T>
317inline void ISwap3(T *a, T *b) {
318 ISwap(a[0], b[0]);
319 ISwap(a[1], b[1]);
320 ISwap(a[2], b[2]);
321}
322template <typename T>
323inline void ISwap4(T *a, T *b) {
324 ISwap(a[0], b[0]);
325 ISwap(a[1], b[1]);
326 ISwap(a[2], b[2]);
327 ISwap(a[3], b[3]);
328}
329
330// Return:
331// min_val if a <= min_val
332// max_val if a >= max_val
333template <typename T>
334inline T IInterval(T a, T min_val, T max_val) {
335 if (a <= min_val) {
336 return (min_val);
337 }
338 if (a >= max_val) {
339 return (max_val);
340 }
341 return (a);
342}
343
344template <typename T>
345inline T IIntervalHalfopen(T a, T min_val, T max_val) {
346 if (a <= min_val) {
347 return (min_val);
348 }
349 if (a >= max_val) {
350 return (max_val - 1);
351 }
352 return (a);
353}
354
355// Make p[i] to be the reference of a's ith row, where a is a mxn matrix
356template <typename T>
357inline void IMakeReference(T *a, T **p, int m, int n) {
358 for (int i = 0; i < m; i++) {
359 p[i] = &a[i * n];
360 }
361}
362template <typename T>
363inline void IMakeReference2x2(T a[4], T *p[2]) {
364 p[0] = &a[0];
365 p[1] = &a[2];
366}
367template <typename T>
368inline void IMakeReference3x3(T a[9], T *p[3]) {
369 p[0] = &a[0];
370 p[1] = &a[3];
371 p[2] = &a[6];
372}
373template <typename T>
374inline void IMakeReference4x4(T a[16], T *p[4]) {
375 p[0] = &a[0];
376 p[1] = &a[4];
377 p[2] = &a[8];
378 p[3] = &a[12];
379}
380template <typename T>
381inline void IMakeReference4x9(T a[36], T *p[4]) {
382 p[0] = &a[0];
383 p[1] = &a[9];
384 p[2] = &a[18];
385 p[3] = &a[27];
386}
387template <typename T>
388inline void IMakeReference5x9(T a[45], T *p[5]) {
389 p[0] = &a[0];
390 p[1] = &a[9];
391 p[2] = &a[18];
392 p[3] = &a[27];
393 p[4] = &a[36];
394}
395template <typename T>
396inline void IMakeReference9x9(T a[81], T *p[9]) {
397 p[0] = &a[0];
398 p[1] = &a[9];
399 p[2] = &a[18];
400 p[3] = &a[27];
401 p[4] = &a[36];
402 p[5] = &a[45];
403 p[6] = &a[54];
404 p[7] = &a[63];
405 p[8] = &a[72];
406}
407template <typename T>
408inline void IMakeReference12x12(T a[144], T *p[12]) {
409 p[0] = &a[0];
410 p[1] = &a[12];
411 p[2] = &a[24];
412 p[3] = &a[36];
413 p[4] = &a[48];
414 p[5] = &a[60];
415 p[6] = &a[72];
416 p[7] = &a[84];
417 p[8] = &a[96];
418 p[9] = &a[108];
419 p[10] = &a[120];
420 p[11] = &a[132];
421}
422
423template <typename T>
424inline void IMakeConstReference(const T *a, const T **p, int m, int n) {
425 for (int i = 0; i < m; i++) {
426 p[i] = &a[i * n];
427 }
428}
429template <typename T>
430inline void IMakeConstReference2x2(const T a[4], const T *p[2]) {
431 p[0] = &a[0];
432 p[1] = &a[2];
433}
434template <typename T>
435inline void IMakeConstReference3x3(const T a[9], const T *p[3]) {
436 p[0] = &a[0];
437 p[1] = &a[3];
438 p[2] = &a[6];
439}
440template <typename T>
441inline void IMakeConstReference4x4(const T a[16], const T *p[4]) {
442 p[0] = &a[0];
443 p[1] = &a[4];
444 p[2] = &a[8];
445 p[3] = &a[12];
446}
447template <typename T>
448inline void IMakeConstReference4x9(const T a[36], const T *p[4]) {
449 p[0] = &a[0];
450 p[1] = &a[9];
451 p[2] = &a[18];
452 p[3] = &a[27];
453}
454template <typename T>
455inline void IMakeConstReference5x9(const T a[45], const T *p[5]) {
456 p[0] = &a[0];
457 p[1] = &a[9];
458 p[2] = &a[18];
459 p[3] = &a[27];
460 p[4] = &a[36];
461}
462template <typename T>
463inline void IMakeConstReference9x9(const T a[81], const T *p[9]) {
464 p[0] = &a[0];
465 p[1] = &a[9];
466 p[2] = &a[18];
467 p[3] = &a[27];
468 p[4] = &a[36];
469 p[5] = &a[45];
470 p[6] = &a[54];
471 p[7] = &a[63];
472 p[8] = &a[72];
473}
474template <typename T>
475inline void IMakeConstReference12x12(const T a[144], const T *p[12]) {
476 p[0] = &a[0];
477 p[1] = &a[12];
478 p[2] = &a[24];
479 p[3] = &a[36];
480 p[4] = &a[48];
481 p[5] = &a[60];
482 p[6] = &a[72];
483 p[7] = &a[84];
484 p[8] = &a[96];
485 p[9] = &a[108];
486 p[10] = &a[120];
487 p[11] = &a[132];
488}
489
490// Create an array of pointers (in p) to the l*m*n memory area a
491template <typename T>
492inline void IMakeReference(T *a, T ***p, int l, int m, int n) {
493 T *temp = a;
494 for (int i = 0; i < l; i++) {
495 for (int j = 0; j < m; j++) {
496 p[i][j] = temp;
497 temp += n;
498 }
499 }
500}
501
502// Assign a[i] = i to a n-dimensional vector a
503template <typename T>
504inline void IRamp(T *a, int n) {
505 for (int i = 0; i < n; i++) {
506 a[i] = static_cast<T>(i);
507 }
508}
509
510// Construct the square 2D Gaussian Kernel (nxn) given Kernel width "n" and
511// sigma
512// * value "sigma"
513inline void IGaussian2D(float *kernel, int n, const float sigma) {
514 int r, c, i = 0;
515 const float cen = (static_cast<float>(n - 1)) / 2;
516 const float nf =
517 IDiv(0.5f, (sigma * sigma)); // normalization factor = 1/(2sigma*sigma)
518 float dr, drsqr, dc, dcsqr, v, ksum = 0.f;
519 // pre-compute filter
520 for (r = 0; r < n; ++r) {
521 dr = static_cast<float>(r) - cen;
522 drsqr = ISqr(dr);
523 for (c = 0; c < n; ++c) {
524 dc = static_cast<float>(c) - cen;
525 dcsqr = ISqr(dc);
526 v = IExp(-(drsqr + dcsqr) * nf);
527 ksum += v;
528 kernel[i++] = v;
529 }
530 }
531 // normalize the kernel
532 v = IDiv(1.0f, ksum);
533 for (i = 0; i < n * n; ++i) {
534 kernel[i] *= v;
535 }
536}
537
538inline void IGaussian2D(double *kernel, int n, const double sigma) {
539 int r, c, i = 0;
540 const double cen = (static_cast<double>(n - 1)) / 2;
541 const double nf =
542 IDiv(0.5, (sigma * sigma)); // normalization factor = 1/(2sigma*sigma)
543 double dr, drsqr, dc, dcsqr, v, ksum = 0.0;
544 // pre-compute filter
545 for (r = 0; r < n; ++r) {
546 dr = static_cast<double>(r) - cen;
547 drsqr = ISqr(dr);
548 for (c = 0; c < n; ++c) {
549 dc = static_cast<double>(c) - cen;
550 dcsqr = ISqr(dc);
551 v = IExp(-(drsqr + dcsqr) * nf);
552 ksum += v;
553 kernel[i++] = v;
554 }
555 }
556 // normalize the kernel
557 v = IDiv(1.0, ksum);
558 for (i = 0; i < n * n; ++i) {
559 kernel[i] *= v;
560 }
561}
562
563// Move an into b, without necessarily preserving the value of a. This function
564// is * specialized for types that are expensive to copy
565template <typename T>
566inline void IMove(const T &a, T *b) {
567 *b = a;
568}
569
570// Check if a point x is within the 1D rectangle bounding box defined by range
571// * [start, start + length)
572template <typename T>
573inline bool IWithin1D(const T x, const T start, const T length) {
574 return (x >= start && x < (length + start));
575}
576
577// Check if a point p(x,y) is within the 2D rectangle bounding box defined by
578// * [x_upper_left, y_upper_left, width, height], where width and height are
579// width
580// * and height of the bounding box
581template <typename T>
582inline bool IWithin2D(const T p[2], const T x_upper_left, const T y_upper_left,
583 const T width, const T height) {
584 return (p[0] >= x_upper_left && p[1] >= y_upper_left &&
585 p[0] < width + x_upper_left && p[1] < height + y_upper_left);
586}
587// Check if a point (x,y) is within the 2D rectangle bounding box defined by
588// * [x_upper_left, y_upper_left, width, height], where width and height are
589// width
590// * and height of the bounding box
591template <typename T>
592inline bool IWithin2D(const T x, const T y, const T x_upper_left,
593 const T y_upper_left, const T width, const T height) {
594 return (x >= x_upper_left && y >= y_upper_left && x < width + x_upper_left &&
595 y < height + y_upper_left);
596}
597
598} // namespace algorithm
599} // namespace perception
600} // namespace apollo
void IMakeReference4x9(T a[36], T *p[4])
Definition i_basic.h:381
float IDegreeToRadians(float d)
Definition i_basic.h:266
void IMakeReference(T *a, T **p, int m, int n)
Definition i_basic.h:357
void IMakeConstReference4x4(const T a[16], const T *p[4])
Definition i_basic.h:441
float IRadiansToDegree(float r)
Definition i_basic.h:260
void IMove(const T &a, T *b)
Definition i_basic.h:566
void ISwap3(T *a, T *b)
Definition i_basic.h:317
void ISwap4(T *a, T *b)
Definition i_basic.h:323
void IMakeConstReference2x2(const T a[4], const T *p[2])
Definition i_basic.h:430
float ISin(float alpha)
Definition i_basic.h:214
void IMakeReference12x12(T a[144], T *p[12])
Definition i_basic.h:408
float IAsin(float alpha)
Definition i_basic.h:221
void IMakeConstReference12x12(const T a[144], const T *p[12])
Definition i_basic.h:475
void IMakeConstReference9x9(const T a[81], const T *p[9])
Definition i_basic.h:463
void IGaussian2D(float *kernel, int n, const float sigma)
Definition i_basic.h:513
float ITan(float alpha)
Definition i_basic.h:218
T IIntervalHalfopen(T a, T min_val, T max_val)
Definition i_basic.h:345
float IDiv(float a, float b)
Definition i_basic.h:35
T IInterval(T a, T min_val, T max_val)
Definition i_basic.h:334
void IMakeReference5x9(T a[45], T *p[5])
Definition i_basic.h:388
unsigned int IHammingLut(unsigned int a, unsigned int b)
Definition i_basic.h:287
void IMakeConstReference3x3(const T a[9], const T *p[3])
Definition i_basic.h:435
bool IWithin2D(const T p[2], const T x_upper_left, const T y_upper_left, const T width, const T height)
Definition i_basic.h:582
void IMakeConstReference(const T *a, const T **p, int m, int n)
Definition i_basic.h:424
void IMakeConstReference5x9(const T a[45], const T *p[5])
Definition i_basic.h:455
void ISwap(T &a, T &b)
Definition i_basic.h:299
float IPow(float a, float b)
Definition i_basic.h:142
float IAtan2(float y, float x)
Definition i_basic.h:257
void IMakeReference3x3(T a[9], T *p[3])
Definition i_basic.h:368
float ICos(float alpha)
Definition i_basic.h:216
void IMakeReference2x2(T a[4], T *p[2])
Definition i_basic.h:363
float IAcos(float alpha)
Definition i_basic.h:239
void ISwap2(T *a, T *b)
Definition i_basic.h:312
bool IWithin1D(const T x, const T start, const T length)
Definition i_basic.h:573
unsigned int IHamming(unsigned int a, unsigned int b)
Definition i_basic.h:275
void IRamp(T *a, int n)
Definition i_basic.h:504
void IMakeReference4x4(T a[16], T *p[4])
Definition i_basic.h:374
void IMakeReference9x9(T a[81], T *p[9])
Definition i_basic.h:396
void IMakeConstReference4x9(const T a[36], const T *p[4])
Definition i_basic.h:448
class register implement
Definition arena_queue.h:37