include/opencv2/gpu/device/vec_math.hpp
Go to the documentation of this file.
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 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef __OPENCV_GPU_VECMATH_HPP__
00044 #define __OPENCV_GPU_VECMATH_HPP__
00045 
00046 #include "saturate_cast.hpp"
00047 #include "vec_traits.hpp"
00048 #include "functional.hpp"
00049 
00050 namespace cv { namespace gpu { namespace device
00051 {
00052     namespace vec_math_detail
00053     {
00054         template <int cn, typename VecD> struct SatCastHelper;
00055         template <typename VecD> struct SatCastHelper<1, VecD>
00056         {
00057             template <typename VecS> static __device__ __forceinline__ VecD cast(const VecS& v)
00058             {
00059                 typedef typename VecTraits<VecD>::elem_type D;
00060                 return VecTraits<VecD>::make(saturate_cast<D>(v.x));
00061             }
00062         };
00063         template <typename VecD> struct SatCastHelper<2, VecD>
00064         {
00065             template <typename VecS> static __device__ __forceinline__ VecD cast(const VecS& v)
00066             {
00067                 typedef typename VecTraits<VecD>::elem_type D;
00068                 return VecTraits<VecD>::make(saturate_cast<D>(v.x), saturate_cast<D>(v.y));
00069             }
00070         };
00071         template <typename VecD> struct SatCastHelper<3, VecD>
00072         {
00073             template <typename VecS> static __device__ __forceinline__ VecD cast(const VecS& v)
00074             {
00075                 typedef typename VecTraits<VecD>::elem_type D;
00076                 return VecTraits<VecD>::make(saturate_cast<D>(v.x), saturate_cast<D>(v.y), saturate_cast<D>(v.z));
00077             }
00078         };
00079         template <typename VecD> struct SatCastHelper<4, VecD>
00080         {
00081             template <typename VecS> static __device__ __forceinline__ VecD cast(const VecS& v)
00082             {
00083                 typedef typename VecTraits<VecD>::elem_type D;
00084                 return VecTraits<VecD>::make(saturate_cast<D>(v.x), saturate_cast<D>(v.y), saturate_cast<D>(v.z), saturate_cast<D>(v.w));
00085             }
00086         };
00087 
00088         template <typename VecD, typename VecS> static __device__ __forceinline__ VecD saturate_cast_caller(const VecS& v)
00089         {
00090             return SatCastHelper<VecTraits<VecD>::cn, VecD>::cast(v);
00091         }
00092     }
00093 
00094     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uchar1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00095     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const char1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00096     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const ushort1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00097     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const short1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00098     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uint1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00099     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const int1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00100     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const float1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00101     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const double1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00102 
00103     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uchar2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00104     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const char2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00105     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const ushort2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00106     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const short2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00107     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uint2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00108     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const int2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00109     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const float2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00110     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const double2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00111 
00112     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uchar3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00113     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const char3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00114     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const ushort3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00115     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const short3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00116     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uint3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00117     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const int3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00118     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const float3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00119     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const double3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00120 
00121     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uchar4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00122     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const char4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00123     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const ushort4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00124     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const short4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00125     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uint4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00126     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const int4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00127     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const float4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00128     template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const double4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00129 
00130 #define OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, op, func) \
00131     __device__ __forceinline__ TypeVec<func<type>::result_type, 1>::vec_type op(const type ## 1 & a) \
00132     { \
00133         func<type> f; \
00134         return VecTraits<TypeVec<func<type>::result_type, 1>::vec_type>::make(f(a.x)); \
00135     } \
00136     __device__ __forceinline__ TypeVec<func<type>::result_type, 2>::vec_type op(const type ## 2 & a) \
00137     { \
00138         func<type> f; \
00139         return VecTraits<TypeVec<func<type>::result_type, 2>::vec_type>::make(f(a.x), f(a.y)); \
00140     } \
00141     __device__ __forceinline__ TypeVec<func<type>::result_type, 3>::vec_type op(const type ## 3 & a) \
00142     { \
00143         func<type> f; \
00144         return VecTraits<TypeVec<func<type>::result_type, 3>::vec_type>::make(f(a.x), f(a.y), f(a.z)); \
00145     } \
00146     __device__ __forceinline__ TypeVec<func<type>::result_type, 4>::vec_type op(const type ## 4 & a) \
00147     { \
00148         func<type> f; \
00149         return VecTraits<TypeVec<func<type>::result_type, 4>::vec_type>::make(f(a.x), f(a.y), f(a.z), f(a.w)); \
00150     }
00151 
00152     namespace vec_math_detail
00153     {
00154         template <typename T1, typename T2> struct BinOpTraits
00155         {
00156             typedef int argument_type;
00157         };
00158         template <typename T> struct BinOpTraits<T, T>
00159         {
00160             typedef T argument_type;
00161         };
00162         template <typename T> struct BinOpTraits<T, double>
00163         {
00164             typedef double argument_type;
00165         };
00166         template <typename T> struct BinOpTraits<double, T>
00167         {
00168             typedef double argument_type;
00169         };
00170         template <> struct BinOpTraits<double, double>
00171         {
00172             typedef double argument_type;
00173         };
00174         template <typename T> struct BinOpTraits<T, float>
00175         {
00176             typedef float argument_type;
00177         };
00178         template <typename T> struct BinOpTraits<float, T>
00179         {
00180             typedef float argument_type;
00181         };
00182         template <> struct BinOpTraits<float, float>
00183         {
00184             typedef float argument_type;
00185         };
00186         template <> struct BinOpTraits<double, float>
00187         {
00188             typedef double argument_type;
00189         };
00190         template <> struct BinOpTraits<float, double>
00191         {
00192             typedef double argument_type;
00193         };
00194     }
00195 
00196 #define OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, op, func) \
00197     __device__ __forceinline__ TypeVec<func<type>::result_type, 1>::vec_type op(const type ## 1 & a, const type ## 1 & b) \
00198     { \
00199         func<type> f; \
00200         return VecTraits<TypeVec<func<type>::result_type, 1>::vec_type>::make(f(a.x, b.x)); \
00201     } \
00202     template <typename T> \
00203     __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 1>::vec_type op(const type ## 1 & v, T s) \
00204     { \
00205         func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00206         return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 1>::vec_type>::make(f(v.x, s)); \
00207     } \
00208     template <typename T> \
00209     __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 1>::vec_type op(T s, const type ## 1 & v) \
00210     { \
00211         func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00212         return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 1>::vec_type>::make(f(s, v.x)); \
00213     } \
00214     __device__ __forceinline__ TypeVec<func<type>::result_type, 2>::vec_type op(const type ## 2 & a, const type ## 2 & b) \
00215     { \
00216         func<type> f; \
00217         return VecTraits<TypeVec<func<type>::result_type, 2>::vec_type>::make(f(a.x, b.x), f(a.y, b.y)); \
00218     } \
00219     template <typename T> \
00220     __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 2>::vec_type op(const type ## 2 & v, T s) \
00221     { \
00222         func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00223         return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 2>::vec_type>::make(f(v.x, s), f(v.y, s)); \
00224     } \
00225     template <typename T> \
00226     __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 2>::vec_type op(T s, const type ## 2 & v) \
00227     { \
00228         func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00229         return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 2>::vec_type>::make(f(s, v.x), f(s, v.y)); \
00230     } \
00231     __device__ __forceinline__ TypeVec<func<type>::result_type, 3>::vec_type op(const type ## 3 & a, const type ## 3 & b) \
00232     { \
00233         func<type> f; \
00234         return VecTraits<TypeVec<func<type>::result_type, 3>::vec_type>::make(f(a.x, b.x), f(a.y, b.y), f(a.z, b.z)); \
00235     } \
00236     template <typename T> \
00237     __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 3>::vec_type op(const type ## 3 & v, T s) \
00238     { \
00239         func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00240         return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 3>::vec_type>::make(f(v.x, s), f(v.y, s), f(v.z, s)); \
00241     } \
00242     template <typename T> \
00243     __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 3>::vec_type op(T s, const type ## 3 & v) \
00244     { \
00245         func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00246         return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 3>::vec_type>::make(f(s, v.x), f(s, v.y), f(s, v.z)); \
00247     } \
00248     __device__ __forceinline__ TypeVec<func<type>::result_type, 4>::vec_type op(const type ## 4 & a, const type ## 4 & b) \
00249     { \
00250         func<type> f; \
00251         return VecTraits<TypeVec<func<type>::result_type, 4>::vec_type>::make(f(a.x, b.x), f(a.y, b.y), f(a.z, b.z), f(a.w, b.w)); \
00252     } \
00253     template <typename T> \
00254     __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 4>::vec_type op(const type ## 4 & v, T s) \
00255     { \
00256         func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00257         return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 4>::vec_type>::make(f(v.x, s), f(v.y, s), f(v.z, s), f(v.w, s)); \
00258     } \
00259     template <typename T> \
00260     __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 4>::vec_type op(T s, const type ## 4 & v) \
00261     { \
00262         func<typename vec_math_detail::BinOpTraits<T, type>::argument_type> f; \
00263         return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 4>::vec_type>::make(f(s, v.x), f(s, v.y), f(s, v.z), f(s, v.w)); \
00264     }
00265 
00266 #define OPENCV_GPU_IMPLEMENT_VEC_OP(type) \
00267     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator +, plus) \
00268     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator -, minus) \
00269     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator *, multiplies) \
00270     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator /, divides) \
00271     OPENCV_GPU_IMPLEMENT_VEC_UNOP (type, operator -, negate) \
00272     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator ==, equal_to) \
00273     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator !=, not_equal_to) \
00274     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator > , greater) \
00275     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator < , less) \
00276     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator >=, greater_equal) \
00277     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator <=, less_equal) \
00278     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator &&, logical_and) \
00279     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator ||, logical_or) \
00280     OPENCV_GPU_IMPLEMENT_VEC_UNOP (type, operator ! , logical_not) \
00281     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, max, maximum) \
00282     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, min, minimum) \
00283     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, fabs, fabs_func) \
00284     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, sqrt, sqrt_func) \
00285     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, exp, exp_func) \
00286     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, exp2, exp2_func) \
00287     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, exp10, exp10_func) \
00288     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, log, log_func) \
00289     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, log2, log2_func) \
00290     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, log10, log10_func) \
00291     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, sin, sin_func) \
00292     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, cos, cos_func) \
00293     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, tan, tan_func) \
00294     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, asin, asin_func) \
00295     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, acos, acos_func) \
00296     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, atan, atan_func) \
00297     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, sinh, sinh_func) \
00298     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, cosh, cosh_func) \
00299     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, tanh, tanh_func) \
00300     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, asinh, asinh_func) \
00301     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, acosh, acosh_func) \
00302     OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, atanh, atanh_func) \
00303     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, hypot, hypot_func) \
00304     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, atan2, atan2_func) \
00305     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, pow, pow_func) \
00306     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, hypot_sqr, hypot_sqr_func)
00307 
00308 #define OPENCV_GPU_IMPLEMENT_VEC_INT_OP(type) \
00309     OPENCV_GPU_IMPLEMENT_VEC_OP(type) \
00310     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator &, bit_and) \
00311     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator |, bit_or) \
00312     OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator ^, bit_xor) \
00313     OPENCV_GPU_IMPLEMENT_VEC_UNOP (type, operator ~, bit_not)
00314 
00315     OPENCV_GPU_IMPLEMENT_VEC_INT_OP(uchar)
00316     OPENCV_GPU_IMPLEMENT_VEC_INT_OP(char)
00317     OPENCV_GPU_IMPLEMENT_VEC_INT_OP(ushort)
00318     OPENCV_GPU_IMPLEMENT_VEC_INT_OP(short)
00319     OPENCV_GPU_IMPLEMENT_VEC_INT_OP(int)
00320     OPENCV_GPU_IMPLEMENT_VEC_INT_OP(uint)
00321     OPENCV_GPU_IMPLEMENT_VEC_OP(float)
00322     OPENCV_GPU_IMPLEMENT_VEC_OP(double)
00323 
00324     #undef OPENCV_GPU_IMPLEMENT_VEC_UNOP
00325     #undef OPENCV_GPU_IMPLEMENT_VEC_BINOP
00326     #undef OPENCV_GPU_IMPLEMENT_VEC_OP
00327     #undef OPENCV_GPU_IMPLEMENT_VEC_INT_OP
00328 }}} // namespace cv { namespace gpu { namespace device
00329 
00330 #endif // __OPENCV_GPU_VECMATH_HPP__