ivl 679
|
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>. 00002 A C++ template library extending syntax towards mathematical notation. 00003 00004 Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr> 00005 Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr> 00006 00007 ivl is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License 00009 version 3 as published by the Free Software Foundation. 00010 00011 Alternatively, you can redistribute it and/or modify it under the terms 00012 of the GNU General Public License version 2 as published by the Free 00013 Software Foundation. 00014 00015 ivl is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00018 See the GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 and a copy of the GNU Lesser General Public License along 00022 with ivl. If not, see <http://www.gnu.org/licenses/>. */ 00023 00024 #ifndef IVL_CORE_DETAILS_MATH_UNARY_FUNCTIONS_HPP 00025 #define IVL_CORE_DETAILS_MATH_UNARY_FUNCTIONS_HPP 00026 00027 namespace ivl { 00028 namespace math { 00029 00030 // ------------------------------------------------------------- 00031 // basic mathematical unary functions 00032 // about numbers definitions etc. 00033 00034 template <class T> 00035 inline 00036 int isinf(T x) 00037 { 00038 if(x == std::numeric_limits<T>::infinity()) 00039 return 1; 00040 else if(x == -std::numeric_limits<T>::infinity()) 00041 return -1; 00042 else 00043 return 0; 00044 } 00045 00046 #include "platform_specific/isnan_impl.hpp" 00047 00048 template <class T> 00049 inline 00050 int isinf(const std::complex<T>& x) 00051 { 00052 return isinf(x.real()) || isinf(x.imag()); 00053 } 00054 00055 template <class T> 00056 inline 00057 int isnan(std::complex<T> x) 00058 { 00059 return isnan(x.real()) || isnan(x.imag()); 00060 } 00061 00062 template <class T> 00063 T sign(const T& a) 00064 { 00065 if (a > T(0)) 00066 return T(1); 00067 else if (a < T(0)) 00068 return T(-1); 00069 else 00070 return T(0); 00071 } 00072 00073 template <class T> 00074 T sign(const std::complex<T>& a) 00075 { 00076 if (a.real() > T(0)) 00077 return T(1); 00078 else if (a.real() < T(0)) 00079 return T(-1); 00080 else 00081 return T(0); 00082 } 00083 // ------------------------------------------------------------------- 00084 // unary mathematical functions 00085 // simple ones. already existant in std, or in some implementations 00086 // of std, or half-implemented (not for complex). 00087 // TODO: some might need to be moved to the next section 00088 // ------------------------------------------------------------------- 00089 00090 using std::abs; 00091 using std::exp; 00092 using std::sqrt; 00093 00094 using std::floor; 00095 00096 template <class T> 00097 inline 00098 std::complex<T> floor(const std::complex<T> &x) 00099 { 00100 return std::complex<T>(std::floor(x.real()), std::floor(x.imag())); 00101 } 00102 00103 using std::ceil; 00104 00105 template <class T> 00106 inline 00107 std::complex<T> ceil(const std::complex<T> &x) 00108 { 00109 return std::complex<T>(std::ceil(x.real()), std::ceil(x.imag())); 00110 } 00111 00112 #include "platform_specific/round_impl.hpp" 00113 00114 template <class T> 00115 inline 00116 std::complex<T> round(const std::complex<T> &x) 00117 { 00118 return std::complex<T>(::round(x.real()), ::round(x.imag())); 00119 } 00120 00121 template <class T> 00122 inline 00123 std::complex<T> conj(const std::complex<T> &x) 00124 { 00125 return std::complex<T>(x.real(), -x.imag()); 00126 } 00127 00128 template <class T> 00129 inline 00130 T angle(const std::complex<T> &x) 00131 { 00132 return std::log(x).imag(); 00133 } 00134 00135 template <class T> 00136 inline 00137 T sqr(const T& x) 00138 { 00139 return x * x; 00140 } 00141 00142 // ------------------------------------------------------------------ 00143 // functions that are not defined in std 00144 // ------------------------------------------------------------------ 00145 00146 template <class T> 00147 inline 00148 T fix(const T elem) 00149 { 00150 T res = floor(abs(elem)); 00151 return (elem < cast<T>(0.0)) ? -res : res; 00152 } 00153 00154 template <class T> 00155 inline 00156 T fix(const std::complex<T>& elem) 00157 { 00158 T res = floor(abs(elem)); 00159 return (elem.real() < cast<T>(0.0)) ? -res : res; 00160 } 00161 00162 using std::log; 00163 00164 // todo : speed improve. dont call actual log function for log10 00165 template <class T> 00166 inline 00167 T log10(const T elem) 00168 { 00169 return cast<T>(log(elem)) / cast<T>(log(T(10))); 00170 } 00171 00172 // todo : speed improve. dont call actual log function for log2 00173 template <class T> 00174 inline 00175 T log2(const T elem) 00176 { 00177 return cast<T>(log(elem)) / cast<T>(log(T(2))); 00178 } 00179 00180 template <class T> 00181 inline 00182 T ln(const T elem) 00183 { 00184 return cast<T>(log(elem)); 00185 } 00186 00187 template <class T> 00188 inline 00189 T nextpow2(const T& elem) 00190 { 00191 return std::pow(cast<T>(2), ceil(log2(elem))); 00192 } 00193 00194 // special right now for single element only 00195 template <class T> 00196 inline 00197 T rand(const T& from, const T& to) 00198 { 00199 size_t total = size_t(to - from + 1); 00200 return T(std::rand() % total) + from; 00201 } 00202 inline 00203 double rand(double from, double to) 00204 { 00205 size_t total = size_t(to - from + 1); 00206 return std::fmod(std::rand()/1000.0, total) + from; 00207 } 00208 inline 00209 float rand(float from, float to) 00210 { 00211 size_t total = size_t(to - from + 1); 00212 return std::fmod(std::rand()/1000.0, total) + from; 00213 } 00214 00215 } /* namespace math */ 00216 } /* namespace ivl */ 00217 00218 #endif // IVL_CORE_DETAILS_MATH_UNARY_FUNCTIONS_HPP