Renesas GR-PEACH OpenCV Development / gr-peach-opencv-project-sd-card_update

Fork of gr-peach-opencv-project-sd-card by the do

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fast_math.hpp Source File

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 #include "mbed.h"
00058 #if defined __BORLANDC__
00059 #  include <fastmath.h>
00060 #elif defined __cplusplus
00061 #  include <cmath>
00062 #else
00063 #  include <math.h>
00064 #endif
00065 
00066 #ifdef HAVE_TEGRA_OPTIMIZATION
00067 #  include "tegra_round.hpp"
00068 #endif
00069 
00070 #if CV_VFP
00071     // 1. general scheme
00072     #define ARM_ROUND(_value, _asm_string) \
00073         int res;  \
00074         float temp;  \
00075         asm(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value));  \
00076         return res
00077     // 2. version for double
00078     #ifdef __clang__
00079         #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]")
00080     #else
00081         #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]")
00082     #endif
00083     // 3. version for float
00084     #define ARM_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]")
00085 #endif // CV_VFP
00086 
00087 /** @brief Rounds floating-point number to the nearest integer
00088 
00089  @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
00090  result is not defined.
00091  */
00092 CV_INLINE int
00093 cvRound( double value )
00094 {
00095 #if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ \
00096     && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
00097     __m128d t = _mm_set_sd( value );
00098     return _mm_cvtsd_si32(t);
00099 #elif defined _MSC_VER && defined _M_IX86
00100     int t;
00101     __asm
00102     {
00103         fld value;
00104         fistp t;
00105     }
00106     return t;
00107 #elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \
00108         defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION
00109     TEGRA_ROUND_DBL(value);
00110 #elif defined CV_ICC || defined __GNUC__
00111 # if CV_VFP
00112 #ifdef __i386__
00113   ARM_ROUND_DBL(value);
00114 #else
00115   return (int)(value + (value >= 0 ? 0.5 : -0.5));
00116 #endif //__i386__
00117 # else
00118     return (int)lrint(value);
00119 # endif
00120 #else
00121     /* it's ok if round does not comply with IEEE754 standard;
00122        the tests should allow +/-1 difference when the tested functions use round */
00123     return (int)(value + (value >= 0 ? 0.5 : -0.5));
00124 #endif
00125 }
00126 
00127 
00128 /** @brief Rounds floating-point number to the nearest integer not larger than the original.
00129 
00130  The function computes an integer i such that:
00131  \f[i \le \texttt{value} < i+1\f]
00132  @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
00133  result is not defined.
00134  */
00135 CV_INLINE int cvFloor( double value )
00136 {
00137 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
00138     __m128d t = _mm_set_sd( value );
00139     int i = _mm_cvtsd_si32(t);
00140     return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i)));
00141 #elif defined __GNUC__
00142     int i = (int)value;
00143     return i - (i > value);
00144 #else
00145     int i = cvRound(value);
00146     float diff = (float)(value - i);
00147     return i - (diff < 0);
00148 #endif
00149 }
00150 
00151 /** @brief Rounds floating-point number to the nearest integer not smaller than the original.
00152 
00153  The function computes an integer i such that:
00154  \f[i \le \texttt{value} < i+1\f]
00155  @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
00156  result is not defined.
00157  */
00158 CV_INLINE int cvCeil( double value )
00159 {
00160 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
00161     __m128d t = _mm_set_sd( value );
00162     int i = _mm_cvtsd_si32(t);
00163     return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t));
00164 #elif defined __GNUC__
00165     int i = (int)value;
00166     return i + (i < value);
00167 #else
00168     int i = cvRound(value);
00169     float diff = (float)(i - value);
00170     return i + (diff < 0);
00171 #endif
00172 }
00173 
00174 /** @brief Determines if the argument is Not A Number.
00175 
00176  @param value The input floating-point value
00177 
00178  The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0
00179  otherwise. */
00180 CV_INLINE int cvIsNaN( double value )
00181 {
00182     Cv64suf ieee754;
00183     ieee754.f = value;
00184     return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
00185            ((unsigned)ieee754.u != 0) > 0x7ff00000;
00186 }
00187 
00188 /** @brief Determines if the argument is Infinity.
00189 
00190  @param value The input floating-point value
00191 
00192  The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard)
00193  and 0 otherwise. */
00194 CV_INLINE int cvIsInf( double value )
00195 {
00196     Cv64suf ieee754;
00197     ieee754.f = value;
00198     return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
00199             (unsigned)ieee754.u == 0;
00200 }
00201 
00202 #ifdef __cplusplus
00203 
00204 /** @overload */
00205 CV_INLINE int cvRound(float value)
00206 {
00207 #if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && \
00208       defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
00209     __m128 t = _mm_set_ss( value );
00210     return _mm_cvtss_si32(t);
00211 #elif defined _MSC_VER && defined _M_IX86
00212     int t;
00213     __asm
00214     {
00215         fld value;
00216         fistp t;
00217     }
00218     return t;
00219 #elif ((defined _MSC_VER && defined _M_ARM) || defined CV_ICC || \
00220         defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION
00221     TEGRA_ROUND_FLT(value);
00222 #elif defined CV_ICC || defined __GNUC__
00223 # if CV_VFP
00224 #ifdef __i386__
00225   ARM_ROUND_FLT(value);
00226 #else
00227   return (int)(value + (value >= 0 ? 0.5 : -0.5));
00228 #endif //__i386__
00229 # else
00230     return (int)lrintf(value);
00231 # endif
00232 #else
00233     /* it's ok if round does not comply with IEEE754 standard;
00234      the tests should allow +/-1 difference when the tested functions use round */
00235     return (int)(value + (value >= 0 ? 0.5f : -0.5f));
00236 #endif
00237 }
00238 
00239 /** @overload */
00240 CV_INLINE int cvRound( int value )
00241 {
00242     return value;
00243 }
00244 
00245 /** @overload */
00246 CV_INLINE int cvFloor( float value )
00247 {
00248 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
00249     __m128 t = _mm_set_ss( value );
00250     int i = _mm_cvtss_si32(t);
00251     return i - _mm_movemask_ps(_mm_cmplt_ss(t, _mm_cvtsi32_ss(t,i)));
00252 #elif defined __GNUC__
00253     int i = (int)value;
00254     return i - (i > value);
00255 #else
00256     int i = cvRound(value);
00257     float diff = (float)(value - i);
00258     return i - (diff < 0);
00259 #endif
00260 }
00261 
00262 /** @overload */
00263 CV_INLINE int cvFloor( int value )
00264 {
00265     return value;
00266 }
00267 
00268 /** @overload */
00269 CV_INLINE int cvCeil( float value )
00270 {
00271 #if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
00272     __m128 t = _mm_set_ss( value );
00273     int i = _mm_cvtss_si32(t);
00274     return i + _mm_movemask_ps(_mm_cmplt_ss(_mm_cvtsi32_ss(t,i), t));
00275 #elif defined __GNUC__
00276     int i = (int)value;
00277     return i + (i < value);
00278 #else
00279     int i = cvRound(value);
00280     float diff = (float)(i - value);
00281     return i + (diff < 0);
00282 #endif
00283 }
00284 
00285 /** @overload */
00286 CV_INLINE int cvCeil( int value )
00287 {
00288     return value;
00289 }
00290 
00291 /** @overload */
00292 CV_INLINE int cvIsNaN( float value )
00293 {
00294     Cv32suf ieee754;
00295     ieee754.f = value;
00296     return (ieee754.u & 0x7fffffff) > 0x7f800000;
00297 }
00298 
00299 /** @overload */
00300 CV_INLINE int cvIsInf( float value )
00301 {
00302     Cv32suf ieee754;
00303     ieee754.f = value;
00304     return (ieee754.u & 0x7fffffff) == 0x7f800000;
00305 }
00306 
00307 #endif // __cplusplus
00308 
00309 //! @} core_utils
00310 
00311 #endif
00312