00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef VL_MATHOP_H
00015 #define VL_MATHOP_H
00016
00017 #include "generic.h"
00018 #include <math.h>
00019 #include <float.h>
00020
00022 #define VL_E 2.718281828459045
00023
00025 #define VL_LOG_OF_2 0.693147180559945
00026
00028 #define VL_PI 3.141592653589793
00029
00037 #define VL_EPSILON_F 1.19209290E-07F
00038
00045 #define VL_EPSILON_D 2.220446049250313e-16
00046
00047
00048
00049
00050
00051
00052
00053
00055 static union { vl_uint32 raw ; float value ; }
00056 const vl_nan_f =
00057 { 0x7FC00000UL } ;
00058
00060 static union { vl_uint32 raw ; float value ; }
00061 const vl_infinity_f =
00062 { 0x7F800000UL } ;
00063
00065 static union { vl_uint64 raw ; double value ; }
00066 const vl_nan_d =
00067 #ifdef VL_COMPILER_MSC
00068 { 0x7FF8000000000000ui64 } ;
00069 #else
00070 { 0x7FF8000000000000ULL } ;
00071 #endif
00072
00074 static union { vl_uint64 raw ; double value ; }
00075 const vl_infinity_d =
00076 #ifdef VL_COMPILER_MSC
00077 { 0x7FF0000000000000ui64 } ;
00078 #else
00079 { 0x7FF0000000000000ULL } ;
00080 #endif
00081
00083 #define VL_NAN_F (vl_nan_f.value)
00084
00086 #define VL_INFINITY_F (vl_infinity_f.value)
00087
00089 #define VL_NAN_D (vl_nan_d.value)
00090
00092 #define VL_INFINITY_D (vl_infinity_d.value)
00093
00094
00095
00109 VL_INLINE float
00110 vl_mod_2pi_f (float x)
00111 {
00112 while (x > (float)(2 * VL_PI)) x -= (float) (2 * VL_PI) ;
00113 while (x < 0.0F) x += (float) (2 * VL_PI);
00114 return x ;
00115 }
00116
00121 VL_INLINE double
00122 vl_mod_2pi_d (double x)
00123 {
00124 while (x > 2.0 * VL_PI) x -= 2 * VL_PI ;
00125 while (x < 0.0) x += 2 * VL_PI ;
00126 return x ;
00127 }
00128
00134 VL_INLINE long int
00135 vl_floor_f (float x)
00136 {
00137 long int xi = (long int) x ;
00138 if (x >= 0 || (float) xi == x) return xi ;
00139 else return xi - 1 ;
00140 }
00141
00146 VL_INLINE long int
00147 vl_floor_d (double x)
00148 {
00149 long int xi = (long int) x ;
00150 if (x >= 0 || (double) xi == x) return xi ;
00151 else return xi - 1 ;
00152 }
00153
00159 VL_INLINE long int
00160 vl_ceil_f (float x)
00161 {
00162 #ifdef VL_COMPILER_GNUC
00163 return (long int) __builtin_ceilf(x) ;
00164 #else
00165 return (long int) ceilf(x) ;
00166 #endif
00167 }
00168
00173 VL_INLINE long int
00174 vl_ceil_d (double x)
00175 {
00176 #ifdef VL_COMPILER_GNUC
00177 return __builtin_ceil(x) ;
00178 #else
00179 return (long int) ceil(x) ;
00180 #endif
00181 }
00182
00189 VL_INLINE long int
00190 vl_round_f (float x)
00191 {
00192 #ifdef VL_COMPILER_GNUC
00193 return __builtin_lroundf(x) ;
00194 #elif VL_COMPILER_MSC
00195 if (x >= 0.0F) {
00196 return vl_floor_f(x + 0.5F) ;
00197 } else {
00198 return vl_ceil_f(x - 0.5F) ;
00199 }
00200 #else
00201 return lroundf(x) ;
00202 #endif
00203 }
00204
00211 VL_INLINE long int
00212 vl_round_d (double x)
00213 {
00214 #ifdef VL_COMPILER_GNUC
00215 return __builtin_lround(x) ;
00216 #elif VL_COMPILER_MSC
00217 if (x >= 0.0) {
00218 return vl_floor_d(x + 0.5) ;
00219 } else {
00220 return vl_ceil_d(x - 0.5) ;
00221 }
00222 #else
00223 return lround(x) ;
00224 #endif
00225 }
00226
00232 VL_INLINE float
00233 vl_abs_f (float x)
00234 {
00235 #ifdef VL_COMPILER_GNUC
00236 return __builtin_fabsf (x) ;
00237 #else
00238 return fabsf(x) ;
00239 #endif
00240 }
00241
00246 VL_INLINE double
00247 vl_abs_d (double x)
00248 {
00249 #ifdef VL_COMPILER_GNUC
00250 return __builtin_fabs (x) ;
00251 #else
00252 return fabs(x) ;
00253 #endif
00254 }
00255
00261 VL_INLINE double
00262 vl_log2_d (double x)
00263 {
00264 #ifdef VL_COMPILER_GNUC
00265 return __builtin_log2(x) ;
00266 #elif VL_COMPILER_MSC
00267 return log(x) / 0.693147180559945 ;
00268 #else
00269 return log2(x) ;
00270 #endif
00271 }
00272
00274 VL_INLINE float
00275 vl_log2_f (float x)
00276 {
00277 #ifdef VL_COMPILER_GNUC
00278 return __builtin_log2f (x) ;
00279 #elif VL_COMPILER_MSC
00280 return logf(x) / 0.6931472F ;
00281 #else
00282 return log2(x) ;
00283 #endif
00284 }
00285
00291 VL_INLINE double
00292 vl_sqrt_d (double x)
00293 {
00294 #ifdef VL_COMPILER_GNUC
00295 return __builtin_sqrt(x) ;
00296 #else
00297 return sqrt(x) ;
00298 #endif
00299 }
00300
00302 VL_INLINE float
00303 vl_sqrt_f (float x)
00304 {
00305 #ifdef VL_COMPILER_GNUC
00306 return __builtin_sqrtf(x) ;
00307 #else
00308 return sqrtf(x) ;
00309 #endif
00310 }
00311
00312
00317 VL_INLINE vl_bool
00318 vl_is_nan_f (float x)
00319 {
00320 #ifdef VL_COMPILER_GNUC
00321 return __builtin_isnan (x) ;
00322 #elif VL_COMPILER_MSC
00323 return _isnan(x) ;
00324 #else
00325 return isnan(x) ;
00326 #endif
00327 }
00328
00330 VL_INLINE vl_bool
00331 vl_is_nan_d (double x)
00332 {
00333 #ifdef VL_COMPILER_GNUC
00334 return __builtin_isnan (x) ;
00335 #elif VL_COMPILER_MSC
00336 return _isnan(x) ;
00337 #else
00338 return isnan(x) ;
00339 #endif
00340 }
00341
00346 VL_INLINE vl_bool
00347 vl_is_inf_f (float x)
00348 {
00349 #ifdef VL_COMPILER_GNUC
00350 return __builtin_isinf (x) ;
00351 #elif VL_COMPILER_MSC
00352 return ! _finite(x) ;
00353 #else
00354 return isinf(x) ;
00355 #endif
00356 }
00357
00359 VL_INLINE vl_bool
00360 vl_is_inf_d (double x)
00361 {
00362 #ifdef VL_COMPILER_GNUC
00363 return __builtin_isinf (x) ;
00364 #elif VL_COMPILER_MSC
00365 return ! _finite(x) ;
00366 #else
00367 return isinf(x) ;
00368 #endif
00369 }
00370
00407 VL_INLINE float
00408 vl_fast_atan2_f (float y, float x)
00409 {
00410 float angle, r ;
00411 float const c3 = 0.1821F ;
00412 float const c1 = 0.9675F ;
00413 float abs_y = vl_abs_f (y) + VL_EPSILON_F ;
00414
00415 if (x >= 0) {
00416 r = (x - abs_y) / (x + abs_y) ;
00417 angle = (float) (VL_PI / 4) ;
00418 } else {
00419 r = (x + abs_y) / (abs_y - x) ;
00420 angle = (float) (3 * VL_PI / 4) ;
00421 }
00422 angle += (c3*r*r - c1) * r ;
00423 return (y < 0) ? - angle : angle ;
00424 }
00425
00430 VL_INLINE double
00431 vl_fast_atan2_d (double y, double x)
00432 {
00433 double angle, r ;
00434 double const c3 = 0.1821 ;
00435 double const c1 = 0.9675 ;
00436 double abs_y = vl_abs_d (y) + VL_EPSILON_D ;
00437
00438 if (x >= 0) {
00439 r = (x - abs_y) / (x + abs_y) ;
00440 angle = VL_PI / 4 ;
00441 } else {
00442 r = (x + abs_y) / (abs_y - x) ;
00443 angle = 3 * VL_PI / 4 ;
00444 }
00445 angle += (c3*r*r - c1) * r ;
00446 return (y < 0) ? - angle : angle ;
00447 }
00448
00479 VL_INLINE float
00480 vl_fast_resqrt_f (float x)
00481 {
00482
00483 union {
00484 float x ;
00485 vl_int32 i ;
00486 } u ;
00487
00488 float xhalf = (float) 0.5 * x ;
00489
00490
00491 u.x = x ;
00492
00493
00494 u.i = 0x5f3759df - (u.i >> 1);
00495
00496
00497
00498 u.x = u.x * ( (float) 1.5 - xhalf*u.x*u.x) ;
00499 u.x = u.x * ( (float) 1.5 - xhalf*u.x*u.x) ;
00500 return u.x ;
00501 }
00502
00507 VL_INLINE double
00508 vl_fast_resqrt_d (double x)
00509 {
00510
00511 union {
00512 double x ;
00513 vl_int64 i ;
00514 } u ;
00515
00516 double xhalf = (double) 0.5 * x ;
00517
00518
00519 u.x = x ;
00520
00521
00522 #ifdef VL_COMPILER_MSC
00523 u.i = 0x5fe6ec85e7de30dai64 - (u.i >> 1) ;
00524 #else
00525 u.i = 0x5fe6ec85e7de30daLL - (u.i >> 1) ;
00526 #endif
00527
00528
00529 u.x = u.x * ( (double) 1.5 - xhalf*u.x*u.x) ;
00530 u.x = u.x * ( (double) 1.5 - xhalf*u.x*u.x) ;
00531 return u.x ;
00532 }
00533
00544 VL_INLINE float
00545 vl_fast_sqrt_f (float x)
00546 {
00547 return (x < 1e-8) ? 0 : x * vl_fast_resqrt_f (x) ;
00548 }
00549
00554 VL_INLINE double
00555 vl_fast_sqrt_d (float x)
00556 {
00557 return (x < 1e-8) ? 0 : x * vl_fast_resqrt_d (x) ;
00558 }
00559
00565 VL_INLINE vl_uint64 vl_fast_sqrt_ui64 (vl_uint64 x) ;
00566
00569 VL_INLINE vl_uint32 vl_fast_sqrt_ui32 (vl_uint32 x) ;
00570
00573 VL_INLINE vl_uint16 vl_fast_sqrt_ui16 (vl_uint16 x) ;
00574
00577 VL_INLINE vl_uint8 vl_fast_sqrt_ui8 (vl_uint8 x) ;
00578
00579 #define VL_FAST_SQRT_UI(T,SFX) \
00580 VL_INLINE T \
00581 vl_fast_sqrt_ ## SFX (T x) \
00582 { \
00583 T y = 0 ; \
00584 T tmp = 0 ; \
00585 int twice_k ; \
00586 for (twice_k = 8 * sizeof(T) - 2 ; \
00587 twice_k >= 0 ; twice_k -= 2) { \
00588 y <<= 1 ; \
00589 tmp = (2*y + 1) << twice_k ; \
00590 if (x >= tmp) { \
00591 x -= tmp ; \
00592 y += 1 ; \
00593 } \
00594 } \
00595 return y ; \
00596 }
00597
00598 VL_FAST_SQRT_UI(vl_uint64,ui64)
00599 VL_FAST_SQRT_UI(vl_uint32,ui32)
00600 VL_FAST_SQRT_UI(vl_uint16,ui16)
00601 VL_FAST_SQRT_UI(vl_uint8,ui8)
00602
00603
00604
00605
00606
00610 typedef float (*VlFloatVectorComparisonFunction)(vl_size dimension, float const * X, float const * Y) ;
00611
00615 typedef double (*VlDoubleVectorComparisonFunction)(vl_size dimension, double const * X, double const * Y) ;
00616
00620 typedef float (*VlFloatVector3ComparisonFunction)(vl_size dimension, float const * X, float const * Y, float const * Z) ;
00621
00625 typedef double (*VlDoubleVector3ComparisonFunction)(vl_size dimension, double const * X, double const * Y, double const * Z) ;
00626
00628 enum _VlVectorComparisonType {
00629 VlDistanceL1,
00630 VlDistanceL2,
00631 VlDistanceChi2,
00632 VlDistanceHellinger,
00633 VlDistanceJS,
00634 VlDistanceMahalanobis,
00635 VlKernelL1,
00636 VlKernelL2,
00637 VlKernelChi2,
00638 VlKernelHellinger,
00639 VlKernelJS
00640 } ;
00641
00643 typedef enum _VlVectorComparisonType VlVectorComparisonType ;
00644
00650 VL_INLINE char const *
00651 vl_get_vector_comparison_type_name (int type)
00652 {
00653 switch (type) {
00654 case VlDistanceL1 : return "l1" ;
00655 case VlDistanceL2 : return "l2" ;
00656 case VlDistanceChi2 : return "chi2" ;
00657 case VlDistanceMahalanobis : return "mahalanobis" ;
00658 case VlKernelL1 : return "kl1" ;
00659 case VlKernelL2 : return "kl2" ;
00660 case VlKernelChi2 : return "kchi2" ;
00661 default: return NULL ;
00662 }
00663 }
00664
00665 VL_EXPORT VlFloatVectorComparisonFunction
00666 vl_get_vector_comparison_function_f (VlVectorComparisonType type) ;
00667
00668 VL_EXPORT VlDoubleVectorComparisonFunction
00669 vl_get_vector_comparison_function_d (VlVectorComparisonType type) ;
00670
00671 VL_EXPORT VlFloatVector3ComparisonFunction
00672 vl_get_vector_3_comparison_function_f (VlVectorComparisonType type) ;
00673
00674 VL_EXPORT VlDoubleVector3ComparisonFunction
00675 vl_get_vector_3_comparison_function_d (VlVectorComparisonType type) ;
00676
00677
00678 VL_EXPORT void
00679 vl_eval_vector_comparison_on_all_pairs_f (float * result, vl_size dimension,
00680 float const * X, vl_size numDataX,
00681 float const * Y, vl_size numDataY,
00682 VlFloatVectorComparisonFunction function) ;
00683
00684 VL_EXPORT void
00685 vl_eval_vector_comparison_on_all_pairs_d (double * result, vl_size dimension,
00686 double const * X, vl_size numDataX,
00687 double const * Y, vl_size numDataY,
00688 VlDoubleVectorComparisonFunction function) ;
00689
00690
00691
00692
00693
00694 VL_EXPORT void
00695 vl_svd2 (double* S, double *U, double *V, double const *M) ;
00696
00697 VL_EXPORT void
00698 vl_lapack_dlasv2 (double *smin,
00699 double *smax,
00700 double *sv,
00701 double *cv,
00702 double *su,
00703 double *cu,
00704 double f,
00705 double g,
00706 double h) ;
00707
00708
00709 VL_EXPORT int
00710 vl_solve_linear_system_3 (double * x, double const * A, double const *b) ;
00711
00712 VL_EXPORT int
00713 vl_solve_linear_system_2 (double * x, double const * A, double const *b) ;
00714
00715 VL_EXPORT int
00716 vl_gaussian_elimination (double * A, vl_size numRows, vl_size numColumns) ;
00717
00718
00719 #endif