ivl 679
ivl/details/core/math/unary_functions.hpp
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations