Joe Verbout
/
main
opencv on mbed
Embed:
(wiki syntax)
Show/hide line numbers
fast_math.hpp
00001 /*M/////////////////////////////////////////////////////////////////////////////////////// 00002 // 00003 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 00004 // 00005 // By downloading, copying, installing or using the software you agree to this license. 00006 // If you do not agree to this license, do not download, install, 00007 // copy or use the software. 00008 // 00009 // 00010 // License Agreement 00011 // For Open Source Computer Vision Library 00012 // 00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved. 00015 // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 00016 // Copyright (C) 2015, Itseez Inc., all rights reserved. 00017 // Third party copyrights are property of their respective owners. 00018 // 00019 // Redistribution and use in source and binary forms, with or without modification, 00020 // are permitted provided that the following conditions are met: 00021 // 00022 // * Redistribution's of source code must retain the above copyright notice, 00023 // this list of conditions and the following disclaimer. 00024 // 00025 // * Redistribution's in binary form must reproduce the above copyright notice, 00026 // this list of conditions and the following disclaimer in the documentation 00027 // and/or other materials provided with the distribution. 00028 // 00029 // * The name of the copyright holders may not be used to endorse or promote products 00030 // derived from this software without specific prior written permission. 00031 // 00032 // This software is provided by the copyright holders and contributors "as is" and 00033 // any express or implied warranties, including, but not limited to, the implied 00034 // warranties of merchantability and fitness for a particular purpose are disclaimed. 00035 // In no event shall the Intel Corporation or contributors be liable for any direct, 00036 // indirect, incidental, special, exemplary, or consequential damages 00037 // (including, but not limited to, procurement of substitute goods or services; 00038 // loss of use, data, or profits; or business interruption) however caused 00039 // and on any theory of liability, whether in contract, strict liability, 00040 // or tort (including negligence or otherwise) arising in any way out of 00041 // the use of this software, even if advised of the possibility of such damage. 00042 // 00043 //M*/ 00044 00045 #ifndef __OPENCV_CORE_FAST_MATH_HPP__ 00046 #define __OPENCV_CORE_FAST_MATH_HPP__ 00047 00048 #include "opencv2/core/cvdef.h" 00049 00050 //! @addtogroup core_utils 00051 //! @{ 00052 00053 /****************************************************************************************\ 00054 * fast math * 00055 \****************************************************************************************/ 00056 00057 #if defined __BORLANDC__ 00058 # include <fastmath.h> 00059 #elif defined __cplusplus 00060 # include <cmath> 00061 #else 00062 # include <math.h> 00063 #endif 00064 00065 #ifdef HAVE_TEGRA_OPTIMIZATION 00066 # include "tegra_round.hpp" 00067 #endif 00068 00069 #if CV_VFP 00070 // 1. general scheme 00071 #define ARM_ROUND(_value, _asm_string) \ 00072 int res; \ 00073 float temp; \ 00074 asm(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value)); \ 00075 return res 00076 // 2. version for double 00077 #ifdef __clang__ 00078 #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]") 00079 #else 00080 #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]") 00081 #endif 00082 // 3. version for float 00083 #define ARM_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]") 00084 #endif // CV_VFP 00085 00086 /** @brief Rounds floating-point number to the nearest integer 00087 00088 @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the 00089 result is not defined. 00090 */ 00091 CV_INLINE int 00092 cvRound( double value ) 00093 { 00094 #if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ \ 00095 && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) 00096 __m128d t = _mm_set_sd( value ); 00097 return _mm_cvtsd_si32(t); 00098 #elif defined _MSC_VER && defined _M_IX86 00099 int t; 00100 __asm 00101 { 00102 fld value; 00103 fistp t; 00104 } 00105 return t; 00106 #elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \ 00107 defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION 00108 TEGRA_ROUND_DBL(value); 00109 #elif defined CV_ICC || defined __GNUC__ 00110 # if CV_VFP 00111 ARM_ROUND_DBL(value); 00112 # else 00113 return (int)lrint(value); 00114 # endif 00115 #else 00116 /* it's ok if round does not comply with IEEE754 standard; 00117 the tests should allow +/-1 difference when the tested functions use round */ 00118 return (int)(value + (value >= 0 ? 0.5 : -0.5)); 00119 #endif 00120 } 00121 00122 00123 /** @brief Rounds floating-point number to the nearest integer not larger than the original. 00124 00125 The function computes an integer i such that: 00126 \f[i \le \texttt{value} < i+1\f] 00127 @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the 00128 result is not defined. 00129 */ 00130 CV_INLINE int cvFloor( double value ) 00131 { 00132 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) 00133 __m128d t = _mm_set_sd( value ); 00134 int i = _mm_cvtsd_si32(t); 00135 return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i))); 00136 #elif defined __GNUC__ 00137 int i = (int)value; 00138 return i - (i > value); 00139 #else 00140 int i = cvRound(value); 00141 float diff = (float)(value - i); 00142 return i - (diff < 0); 00143 #endif 00144 } 00145 00146 /** @brief Rounds floating-point number to the nearest integer not smaller than the original. 00147 00148 The function computes an integer i such that: 00149 \f[i \le \texttt{value} < i+1\f] 00150 @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the 00151 result is not defined. 00152 */ 00153 CV_INLINE int cvCeil( double value ) 00154 { 00155 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__) 00156 __m128d t = _mm_set_sd( value ); 00157 int i = _mm_cvtsd_si32(t); 00158 return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t)); 00159 #elif defined __GNUC__ 00160 int i = (int)value; 00161 return i + (i < value); 00162 #else 00163 int i = cvRound(value); 00164 float diff = (float)(i - value); 00165 return i + (diff < 0); 00166 #endif 00167 } 00168 00169 /** @brief Determines if the argument is Not A Number. 00170 00171 @param value The input floating-point value 00172 00173 The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0 00174 otherwise. */ 00175 CV_INLINE int cvIsNaN( double value ) 00176 { 00177 Cv64suf ieee754; 00178 ieee754.f = value; 00179 return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) + 00180 ((unsigned)ieee754.u != 0) > 0x7ff00000; 00181 } 00182 00183 /** @brief Determines if the argument is Infinity. 00184 00185 @param value The input floating-point value 00186 00187 The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard) 00188 and 0 otherwise. */ 00189 CV_INLINE int cvIsInf( double value ) 00190 { 00191 Cv64suf ieee754; 00192 ieee754.f = value; 00193 return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && 00194 (unsigned)ieee754.u == 0; 00195 } 00196 00197 #ifdef __cplusplus 00198 00199 /** @overload */ 00200 CV_INLINE int cvRound(float value) 00201 { 00202 #if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && \ 00203 defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) 00204 __m128 t = _mm_set_ss( value ); 00205 return _mm_cvtss_si32(t); 00206 #elif defined _MSC_VER && defined _M_IX86 00207 int t; 00208 __asm 00209 { 00210 fld value; 00211 fistp t; 00212 } 00213 return t; 00214 #elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \ 00215 defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION 00216 TEGRA_ROUND_FLT(value); 00217 #elif defined CV_ICC || defined __GNUC__ 00218 # if CV_VFP 00219 ARM_ROUND_FLT(value); 00220 # else 00221 return (int)::lrintf(value); 00222 # endif 00223 #else 00224 /* it's ok if round does not comply with IEEE754 standard; 00225 the tests should allow +/-1 difference when the tested functions use round */ 00226 return (int)(value + (value >= 0 ? 0.5f : -0.5f)); 00227 #endif 00228 } 00229 00230 /** @overload */ 00231 CV_INLINE int cvRound( int value ) 00232 { 00233 return value; 00234 } 00235 00236 /** @overload */ 00237 CV_INLINE int cvFloor( float value ) 00238 { 00239 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) 00240 __m128 t = _mm_set_ss( value ); 00241 int i = _mm_cvtss_si32(t); 00242 return i - _mm_movemask_ps(_mm_cmplt_ss(t, _mm_cvtsi32_ss(t,i))); 00243 #elif defined __GNUC__ 00244 int i = (int)value; 00245 return i - (i > value); 00246 #else 00247 int i = cvRound(value); 00248 float diff = (float)(value - i); 00249 return i - (diff < 0); 00250 #endif 00251 } 00252 00253 /** @overload */ 00254 CV_INLINE int cvFloor( int value ) 00255 { 00256 return value; 00257 } 00258 00259 /** @overload */ 00260 CV_INLINE int cvCeil( float value ) 00261 { 00262 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__) 00263 __m128 t = _mm_set_ss( value ); 00264 int i = _mm_cvtss_si32(t); 00265 return i + _mm_movemask_ps(_mm_cmplt_ss(_mm_cvtsi32_ss(t,i), t)); 00266 #elif defined __GNUC__ 00267 int i = (int)value; 00268 return i + (i < value); 00269 #else 00270 int i = cvRound(value); 00271 float diff = (float)(i - value); 00272 return i + (diff < 0); 00273 #endif 00274 } 00275 00276 /** @overload */ 00277 CV_INLINE int cvCeil( int value ) 00278 { 00279 return value; 00280 } 00281 00282 /** @overload */ 00283 CV_INLINE int cvIsNaN( float value ) 00284 { 00285 Cv32suf ieee754; 00286 ieee754.f = value; 00287 return (ieee754.u & 0x7fffffff) > 0x7f800000; 00288 } 00289 00290 /** @overload */ 00291 CV_INLINE int cvIsInf( float value ) 00292 { 00293 Cv32suf ieee754; 00294 ieee754.f = value; 00295 return (ieee754.u & 0x7fffffff) == 0x7f800000; 00296 } 00297 00298 #endif // __cplusplus 00299 00300 //! @} core_utils 00301 00302 #endif 00303
Generated on Tue Jul 12 2022 16:42:38 by 1.7.2