mathop.h
Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00008 All rights reserved.
00009 
00010 This file is part of the VLFeat library and is made available under
00011 the terms of the BSD license (see the COPYING file).
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    For the code below: An ANSI C compiler takes the two expressions,
00049    LONG_VAR and CHAR_VAR, and implicitly casts them to the type of the
00050    first member of the union. Refer to K&R Second Edition Page 148,
00051    last paragraph.
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   /* 32-bit version */
00483   union {
00484     float x ;
00485     vl_int32  i ;
00486   } u ;
00487 
00488   float xhalf = (float) 0.5 * x ;
00489 
00490   /* convert floating point value in RAW integer */
00491   u.x = x ;
00492 
00493   /* gives initial guess y0 */
00494   u.i = 0x5f3759df - (u.i >> 1);
00495   /*u.i = 0xdf59375f - (u.i>>1);*/
00496 
00497   /* two Newton steps */
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   /* 64-bit version */
00511   union {
00512     double x ;
00513     vl_int64  i ;
00514   } u ;
00515 
00516   double xhalf = (double) 0.5 * x ;
00517 
00518   /* convert floating point value in RAW integer */
00519   u.x = x ;
00520 
00521   /* gives initial guess y0 */
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   /* two Newton steps */
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 ; /* y = 2 * y */                                        \
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 /*                                Vector distances and similarities */
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 /*                                               Numerical analysis */
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 /* VL_MATHOP_H */
00719 #endif


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51