lo-mappers.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 Copyright (C) 2010 VZLU Prague
00005 
00006 This file is part of Octave.
00007 
00008 Octave is free software; you can redistribute it and/or modify it
00009 under the terms of the GNU General Public License as published by the
00010 Free Software Foundation; either version 3 of the License, or (at your
00011 option) any later version.
00012 
00013 Octave is distributed in the hope that it will be useful, but WITHOUT
00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with Octave; see the file COPYING.  If not, see
00020 <http://www.gnu.org/licenses/>.
00021 
00022 */
00023 
00024 #if !defined (octave_liboctave_mappers_h)
00025 #define octave_liboctave_mappers_h 1
00026 
00027 #include <limits>
00028 
00029 #include "oct-cmplx.h"
00030 #include "lo-math.h"
00031 
00032 // Double Precision
00033 extern OCTAVE_API double xtrunc (double x);
00034 extern OCTAVE_API double xcopysign (double x, double y);
00035 inline double xceil (double x) { return ceil (x); }
00036 extern OCTAVE_API double xfloor (double x);
00037 inline double arg (double x) { return atan2 (0.0, x); }
00038 inline double conj (double x) { return x; }
00039 inline double fix (double x) { return xtrunc (x); }
00040 inline double imag (double) { return 0.0; }
00041 inline double real (double x) { return x; }
00042 extern OCTAVE_API double xround (double x);
00043 extern OCTAVE_API double xroundb (double x);
00044 extern OCTAVE_API double signum (double x);
00045 extern OCTAVE_API double xlog2 (double x);
00046 extern OCTAVE_API Complex xlog2 (const Complex& x);
00047 extern OCTAVE_API double xlog2 (double x, int& exp);
00048 extern OCTAVE_API Complex xlog2 (const Complex& x, int& exp);
00049 extern OCTAVE_API double xexp2 (double x);
00050 
00051 // These are used by the BOOL_OP macros in mx-op-defs.h.
00052 inline bool xisnan (bool) { return false; }
00053 inline bool xisnan (char) { return false; }
00054 
00055 #if defined (HAVE_CMATH_ISNAN)
00056 inline bool xisnan (double x)
00057 { return std::isnan (x); }
00058 #else
00059 extern OCTAVE_API bool xisnan (double x);
00060 #endif
00061 #if defined (HAVE_CMATH_ISFINITE)
00062 inline bool xfinite (double x)
00063 { return std::isfinite (x); }
00064 #else
00065 extern OCTAVE_API bool xfinite (double x);
00066 #endif
00067 #if defined (HAVE_CMATH_ISINF)
00068 inline bool xisinf (double x)
00069 { return std::isinf (x); }
00070 #else
00071 extern OCTAVE_API bool xisinf (double x);
00072 #endif
00073 
00074 extern OCTAVE_API bool octave_is_NA (double x);
00075 extern OCTAVE_API bool octave_is_NaN_or_NA (double x) GCC_ATTR_DEPRECATED;
00076 
00077 // Generic xmin, xmax definitions
00078 template <class T>
00079 inline T xmin (T x, T y)
00080 {
00081   return x <= y ? x : y;
00082 }
00083 
00084 template <class T>
00085 inline T xmax (T x, T y)
00086 {
00087   return x >= y ? x : y;
00088 }
00089 
00090 // This form is favorable. GCC will translate (x <= y ? x : y) without a
00091 // jump, hence the only conditional jump involved will be the first
00092 // (xisnan), infrequent and hence friendly to branch prediction.
00093 inline double
00094 xmin (double x, double y)
00095 {
00096   return xisnan (y) ? x : (x <= y ? x : y);
00097 }
00098 
00099 inline double
00100 xmax (double x, double y)
00101 {
00102   return xisnan (y) ? x : (x >= y ? x : y);
00103 }
00104 
00105 extern OCTAVE_API Complex acos (const Complex& x);
00106 extern OCTAVE_API Complex acosh (const Complex& x);
00107 extern OCTAVE_API Complex asin (const Complex& x);
00108 extern OCTAVE_API Complex asinh (const Complex& x);
00109 extern OCTAVE_API Complex atan (const Complex& x);
00110 extern OCTAVE_API Complex atanh (const Complex& x);
00111 
00112 extern OCTAVE_API bool octave_is_NA (const Complex& x);
00113 extern OCTAVE_API bool octave_is_NaN_or_NA (const Complex& x);
00114 
00115 extern OCTAVE_API Complex xmin (const Complex& x, const Complex& y);
00116 extern OCTAVE_API Complex xmax (const Complex& x, const Complex& y);
00117 
00118 // Single Precision
00119 extern OCTAVE_API float xtrunc (float x);
00120 extern OCTAVE_API float xcopysign (float x, float y);
00121 inline float xceil (float x) { return ceilf (x); }
00122 inline float xfloor (float x) { return floorf (x); }
00123 inline float arg (float x) { return atan2f (0.0f, x); }
00124 inline float conj (float x) { return x; }
00125 inline float fix (float x) { return xtrunc (x); }
00126 inline float imag (float) { return 0.0f; }
00127 inline float real (float x) { return x; }
00128 extern OCTAVE_API float xround (float x);
00129 extern OCTAVE_API float xroundb (float x);
00130 extern OCTAVE_API float signum (float x);
00131 extern OCTAVE_API float xlog2 (float x);
00132 extern OCTAVE_API FloatComplex xlog2 (const FloatComplex& x);
00133 extern OCTAVE_API float xlog2 (float x, int& exp);
00134 extern OCTAVE_API FloatComplex xlog2 (const FloatComplex& x, int& exp);
00135 extern OCTAVE_API float xexp2 (float x);
00136 
00137 #if defined (HAVE_CMATH_ISNANF)
00138 inline bool xisnan (float x)
00139 { return std::isnan (x); }
00140 #else
00141 extern OCTAVE_API bool xisnan (float x);
00142 #endif
00143 #if defined (HAVE_CMATH_ISFINITEF)
00144 inline bool xfinite (float x)
00145 { return std::isfinite (x); }
00146 #else
00147 extern OCTAVE_API bool xfinite (float x);
00148 #endif
00149 #if defined (HAVE_CMATH_ISINFF)
00150 inline bool xisinf (float x)
00151 { return std::isinf (x); }
00152 #else
00153 extern OCTAVE_API bool xisinf (float x);
00154 #endif
00155 
00156 extern OCTAVE_API bool octave_is_NA (float x);
00157 extern OCTAVE_API bool octave_is_NaN_or_NA (float x) GCC_ATTR_DEPRECATED;
00158 
00159 inline float
00160 xmin (float x, float y)
00161 {
00162   return xisnan (y) ? x : (x <= y ? x : y);
00163 }
00164 
00165 inline float
00166 xmax (float x, float y)
00167 {
00168   return xisnan (y) ? x : (x >= y ? x : y);
00169 }
00170 
00171 extern OCTAVE_API FloatComplex acos (const FloatComplex& x);
00172 extern OCTAVE_API FloatComplex acosh (const FloatComplex& x);
00173 extern OCTAVE_API FloatComplex asin (const FloatComplex& x);
00174 extern OCTAVE_API FloatComplex asinh (const FloatComplex& x);
00175 extern OCTAVE_API FloatComplex atan (const FloatComplex& x);
00176 extern OCTAVE_API FloatComplex atanh (const FloatComplex& x);
00177 
00178 extern OCTAVE_API bool octave_is_NA (const FloatComplex& x);
00179 extern OCTAVE_API bool octave_is_NaN_or_NA (const FloatComplex& x);
00180 
00181 extern OCTAVE_API FloatComplex xmin (const FloatComplex& x, const FloatComplex& y);
00182 extern OCTAVE_API FloatComplex xmax (const FloatComplex& x, const FloatComplex& y);
00183 
00184 // These map reals to Complex.
00185 
00186 extern OCTAVE_API Complex rc_acos (double);
00187 extern OCTAVE_API FloatComplex rc_acos (float);
00188 extern OCTAVE_API Complex rc_acosh (double);
00189 extern OCTAVE_API FloatComplex rc_acosh (float);
00190 extern OCTAVE_API Complex rc_asin (double);
00191 extern OCTAVE_API FloatComplex rc_asin (float);
00192 extern OCTAVE_API Complex rc_atanh (double);
00193 extern OCTAVE_API FloatComplex rc_atanh (float);
00194 extern OCTAVE_API Complex rc_log (double);
00195 extern OCTAVE_API FloatComplex rc_log (float);
00196 extern OCTAVE_API Complex rc_log2 (double);
00197 extern OCTAVE_API FloatComplex rc_log2 (float);
00198 extern OCTAVE_API Complex rc_log10 (double);
00199 extern OCTAVE_API FloatComplex rc_log10 (float);
00200 extern OCTAVE_API Complex rc_sqrt (double);
00201 extern OCTAVE_API FloatComplex rc_sqrt (float);
00202 
00203 // Some useful tests, that are commonly repeated.
00204 // Test for a finite integer.
00205 inline bool
00206 xisinteger (double x)
00207 {
00208   return xfinite (x) && x == xround (x);
00209 }
00210 
00211 inline bool
00212 xisinteger (float x)
00213 {
00214   return xfinite (x) && x == xround (x);
00215 }
00216 
00217 // Test for negative sign.
00218 extern OCTAVE_API bool xnegative_sign (double x);
00219 extern OCTAVE_API bool xnegative_sign (float x);
00220 
00221 // Test for positive sign.
00222 inline bool xpositive_sign (double x) { return ! xnegative_sign (x); }
00223 inline bool xpositive_sign (float x) { return ! xnegative_sign (x); }
00224 
00225 // Some old rounding functions.
00226 
00227 extern OCTAVE_API octave_idx_type NINTbig (double x);
00228 extern OCTAVE_API octave_idx_type NINTbig (float x);
00229 
00230 extern OCTAVE_API int NINT (double x);
00231 extern OCTAVE_API int NINT (float x);
00232 
00233 template <typename T>
00234 T
00235 X_NINT (T x)
00236 {
00237   return (xisinf (x) || xisnan (x)) ? x : xfloor (x + 0.5);
00238 }
00239 
00240 inline OCTAVE_API double D_NINT (double x) { return X_NINT (x); }
00241 inline OCTAVE_API float F_NINT (float x) { return X_NINT (x); }
00242 
00243 // Template functions can have either float or double arguments.
00244 
00245 template <typename T>
00246 bool
00247 xisnan (const std::complex<T>& x)
00248 {
00249   return (xisnan (real (x)) || xisnan (imag (x)));
00250 }
00251 
00252 template <typename T>
00253 bool
00254 xfinite (const std::complex<T>& x)
00255 {
00256   return (xfinite (real (x)) && xfinite (imag (x)));
00257 }
00258 
00259 template <typename T>
00260 bool
00261 xisinf (const std::complex<T>& x)
00262 {
00263   return (xisinf (real (x)) || xisinf (imag (x)));
00264 }
00265 
00266 template <typename T>
00267 std::complex<T>
00268 fix (const std::complex<T>& x)
00269 {
00270   return std::complex<T> (fix (real (x)), fix (imag (x)));
00271 }
00272 
00273 template <typename T>
00274 std::complex<T>
00275 ceil (const std::complex<T>& x)
00276 {
00277   return std::complex<T> (xceil (real (x)), xceil (imag (x)));
00278 }
00279 
00280 template <typename T>
00281 std::complex<T>
00282 floor (const std::complex<T>& x)
00283 {
00284   return std::complex<T> (xfloor (real (x)), xfloor (imag (x)));
00285 }
00286 
00287 template <typename T>
00288 std::complex<T>
00289 xround (const std::complex<T>& x)
00290 {
00291   return std::complex<T> (xround (real (x)), xround (imag (x)));
00292 }
00293 
00294 template <typename T>
00295 std::complex<T>
00296 xroundb (const std::complex<T>& x)
00297 {
00298   return std::complex<T> (xroundb (real (x)), xroundb (imag (x)));
00299 }
00300 
00301 template <typename T>
00302 std::complex<T>
00303 signum (const std::complex<T>& x)
00304 {
00305   T tmp = abs (x);
00306 
00307   return tmp == 0 ? 0.0 : x / tmp;
00308 }
00309 
00310 template <typename T>
00311 T
00312 xmod (T x, T y)
00313 {
00314   T retval;
00315 
00316   if (y == 0)
00317     retval = x;
00318   else
00319     {
00320       T q = x / y;
00321 
00322       T n = xfloor (q);
00323 
00324       if (X_NINT (y) != y)
00325         {
00326           if (X_NINT (q) == q)
00327             n = q;
00328           else
00329             {
00330               if (x >= -1 && x <= 1)
00331                 {
00332                   if (std::abs (q - X_NINT (q))
00333                       < std::numeric_limits<T>::epsilon ())
00334                     n = X_NINT (q);
00335                 }
00336               else
00337                 {
00338                   if (std::abs ((q - X_NINT (q))/ X_NINT (q))
00339                       < std::numeric_limits<T>::epsilon ())
00340                     n = X_NINT (q);
00341                 }
00342             }
00343         }
00344 
00345       // Prevent use of extra precision.
00346       volatile T tmp = y * n;
00347 
00348       retval = x - tmp;
00349     }
00350 
00351   if (x != y && y != 0 && retval != 0)
00352     retval = xcopysign (retval, y);
00353 
00354   return retval;
00355 }
00356 
00357 template <typename T>
00358 T
00359 xrem (T x, T y)
00360 {
00361   T retval;
00362 
00363   if (y == 0)
00364     retval = x;
00365   else
00366     {
00367       T q = x / y;
00368 
00369       T n = xtrunc (q);
00370 
00371       if (X_NINT (y) != y)
00372         {
00373           if (X_NINT (q) == q)
00374             n = q;
00375           else
00376             {
00377               if (x >= -1 && x <= 1)
00378                 {
00379                   if (std::abs (q - X_NINT (q))
00380                       < std::numeric_limits<T>::epsilon ())
00381                     n = X_NINT (q);
00382                 }
00383               else
00384                 {
00385                   if (std::abs ((q - X_NINT (q))/ X_NINT (q))
00386                       < std::numeric_limits<T>::epsilon ())
00387                     n = X_NINT (q);
00388                 }
00389             }
00390         }
00391 
00392       // Prevent use of extra precision.
00393       volatile T tmp = y * n;
00394 
00395       retval = x - tmp;
00396     }
00397 
00398   if (x != y && y != 0 && retval != 0)
00399     retval = xcopysign (retval, x);
00400 
00401   return retval;
00402 }
00403 
00404 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines