GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
lo-mappers.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2013 John W. Eaton
4 Copyright (C) 2010 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if !defined (octave_lo_mappers_h)
25 #define octave_lo_mappers_h 1
26 
27 #include <limits>
28 
29 #include "oct-cmplx.h"
30 #include "lo-math.h"
31 
32 // Double Precision
33 extern OCTAVE_API double xtrunc (double x);
34 extern OCTAVE_API double xcopysign (double x, double y);
35 inline double xceil (double x) { return ceil (x); }
36 extern OCTAVE_API double xfloor (double x);
37 inline double arg (double x) { return atan2 (0.0, x); }
38 inline double conj (double x) { return x; }
39 inline double fix (double x) { return xtrunc (x); }
40 inline double imag (double) { return 0.0; }
41 inline double real (double x) { return x; }
42 extern OCTAVE_API double xround (double x);
43 extern OCTAVE_API double xroundb (double x);
44 extern OCTAVE_API double signum (double x);
45 extern OCTAVE_API double xlog2 (double x);
46 extern OCTAVE_API Complex xlog2 (const Complex& x);
47 extern OCTAVE_API double xlog2 (double x, int& exp);
48 extern OCTAVE_API Complex xlog2 (const Complex& x, int& exp);
49 extern OCTAVE_API double xexp2 (double x);
50 
51 // These are used by the BOOL_OP macros in mx-op-defs.h.
52 inline bool xisnan (bool) { return false; }
53 inline bool xisnan (char) { return false; }
54 
55 #if defined (HAVE_CMATH_ISNAN)
56 inline bool xisnan (double x)
57 { return std::isnan (x); }
58 #else
59 extern OCTAVE_API bool xisnan (double x);
60 #endif
61 #if defined (HAVE_CMATH_ISFINITE)
62 inline bool xfinite (double x)
63 { return std::isfinite (x); }
64 #else
65 extern OCTAVE_API bool xfinite (double x);
66 #endif
67 #if defined (HAVE_CMATH_ISINF)
68 inline bool xisinf (double x)
69 { return std::isinf (x); }
70 #else
71 extern OCTAVE_API bool xisinf (double x);
72 #endif
73 
74 extern OCTAVE_API bool octave_is_NA (double x);
75 extern OCTAVE_API bool octave_is_NaN_or_NA (double x) GCC_ATTR_DEPRECATED;
76 
77 // Generic xmin, xmax definitions
78 template <class T>
79 inline T xmin (T x, T y)
80 {
81  return x <= y ? x : y;
82 }
83 
84 template <class T>
85 inline T xmax (T x, T y)
86 {
87  return x >= y ? x : y;
88 }
89 
90 // This form is favorable. GCC will translate (x <= y ? x : y) without a
91 // jump, hence the only conditional jump involved will be the first
92 // (xisnan), infrequent and hence friendly to branch prediction.
93 inline double
94 xmin (double x, double y)
95 {
96  return xisnan (y) ? x : (x <= y ? x : y);
97 }
98 
99 inline double
100 xmax (double x, double y)
101 {
102  return xisnan (y) ? x : (x >= y ? x : y);
103 }
104 
105 extern OCTAVE_API Complex acos (const Complex& x);
106 extern OCTAVE_API Complex acosh (const Complex& x);
107 extern OCTAVE_API Complex asin (const Complex& x);
108 extern OCTAVE_API Complex asinh (const Complex& x);
109 extern OCTAVE_API Complex atan (const Complex& x);
110 extern OCTAVE_API Complex atanh (const Complex& x);
111 
112 extern OCTAVE_API bool octave_is_NA (const Complex& x);
113 extern OCTAVE_API bool octave_is_NaN_or_NA (const Complex& x);
114 
115 extern OCTAVE_API Complex xmin (const Complex& x, const Complex& y);
116 extern OCTAVE_API Complex xmax (const Complex& x, const Complex& y);
117 
118 // Single Precision
119 extern OCTAVE_API float xtrunc (float x);
120 extern OCTAVE_API float xcopysign (float x, float y);
121 inline float xceil (float x) { return ceilf (x); }
122 extern OCTAVE_API float xfloor (float x);
123 inline float arg (float x) { return atan2f (0.0f, x); }
124 inline float conj (float x) { return x; }
125 inline float fix (float x) { return xtrunc (x); }
126 inline float imag (float) { return 0.0f; }
127 inline float real (float x) { return x; }
128 extern OCTAVE_API float xround (float x);
129 extern OCTAVE_API float xroundb (float x);
130 extern OCTAVE_API float signum (float x);
131 extern OCTAVE_API float xlog2 (float x);
132 extern OCTAVE_API FloatComplex xlog2 (const FloatComplex& x);
133 extern OCTAVE_API float xlog2 (float x, int& exp);
134 extern OCTAVE_API FloatComplex xlog2 (const FloatComplex& x, int& exp);
135 extern OCTAVE_API float xexp2 (float x);
136 
137 #if defined (HAVE_CMATH_ISNANF)
138 inline bool xisnan (float x)
139 { return std::isnan (x); }
140 #else
141 extern OCTAVE_API bool xisnan (float x);
142 #endif
143 #if defined (HAVE_CMATH_ISFINITEF)
144 inline bool xfinite (float x)
145 { return std::isfinite (x); }
146 #else
147 extern OCTAVE_API bool xfinite (float x);
148 #endif
149 #if defined (HAVE_CMATH_ISINFF)
150 inline bool xisinf (float x)
151 { return std::isinf (x); }
152 #else
153 extern OCTAVE_API bool xisinf (float x);
154 #endif
155 
156 extern OCTAVE_API bool octave_is_NA (float x);
157 extern OCTAVE_API bool octave_is_NaN_or_NA (float x) GCC_ATTR_DEPRECATED;
158 
159 inline float
160 xmin (float x, float y)
161 {
162  return xisnan (y) ? x : (x <= y ? x : y);
163 }
164 
165 inline float
166 xmax (float x, float y)
167 {
168  return xisnan (y) ? x : (x >= y ? x : y);
169 }
170 
171 extern OCTAVE_API FloatComplex acos (const FloatComplex& x);
172 extern OCTAVE_API FloatComplex acosh (const FloatComplex& x);
173 extern OCTAVE_API FloatComplex asin (const FloatComplex& x);
174 extern OCTAVE_API FloatComplex asinh (const FloatComplex& x);
175 extern OCTAVE_API FloatComplex atan (const FloatComplex& x);
176 extern OCTAVE_API FloatComplex atanh (const FloatComplex& x);
177 
178 extern OCTAVE_API bool octave_is_NA (const FloatComplex& x);
179 extern OCTAVE_API bool octave_is_NaN_or_NA (const FloatComplex& x);
180 
181 extern OCTAVE_API FloatComplex xmin (const FloatComplex& x,
182  const FloatComplex& y);
183 extern OCTAVE_API FloatComplex xmax (const FloatComplex& x,
184  const FloatComplex& y);
185 
186 // These map reals to Complex.
187 
188 extern OCTAVE_API Complex rc_acos (double);
189 extern OCTAVE_API FloatComplex rc_acos (float);
190 extern OCTAVE_API Complex rc_acosh (double);
191 extern OCTAVE_API FloatComplex rc_acosh (float);
192 extern OCTAVE_API Complex rc_asin (double);
193 extern OCTAVE_API FloatComplex rc_asin (float);
194 extern OCTAVE_API Complex rc_atanh (double);
195 extern OCTAVE_API FloatComplex rc_atanh (float);
196 extern OCTAVE_API Complex rc_log (double);
197 extern OCTAVE_API FloatComplex rc_log (float);
198 extern OCTAVE_API Complex rc_log2 (double);
199 extern OCTAVE_API FloatComplex rc_log2 (float);
200 extern OCTAVE_API Complex rc_log10 (double);
201 extern OCTAVE_API FloatComplex rc_log10 (float);
202 extern OCTAVE_API Complex rc_sqrt (double);
203 extern OCTAVE_API FloatComplex rc_sqrt (float);
204 
205 // Some useful tests, that are commonly repeated.
206 // Test for a finite integer.
207 inline bool
208 xisinteger (double x)
209 {
210  return xfinite (x) && x == xround (x);
211 }
212 
213 inline bool
214 xisinteger (float x)
215 {
216  return xfinite (x) && x == xround (x);
217 }
218 
219 // Test for negative sign.
220 extern OCTAVE_API bool xnegative_sign (double x);
221 extern OCTAVE_API bool xnegative_sign (float x);
222 
223 // Test for positive sign.
224 inline bool xpositive_sign (double x) { return ! xnegative_sign (x); }
225 inline bool xpositive_sign (float x) { return ! xnegative_sign (x); }
226 
227 // Some old rounding functions.
228 
229 extern OCTAVE_API octave_idx_type NINTbig (double x);
230 extern OCTAVE_API octave_idx_type NINTbig (float x);
231 
232 extern OCTAVE_API int NINT (double x);
233 extern OCTAVE_API int NINT (float x);
234 
235 template <typename T>
236 T
238 {
239  return (xfinite (x) ? xfloor (x + 0.5) : x);
240 }
241 
242 inline OCTAVE_API double D_NINT (double x) { return X_NINT (x); }
243 inline OCTAVE_API float F_NINT (float x) { return X_NINT (x); }
244 
245 // Template functions can have either float or double arguments.
246 
247 template <typename T>
248 bool
249 xisnan (const std::complex<T>& x)
250 {
251  return (xisnan (real (x)) || xisnan (imag (x)));
252 }
253 
254 template <typename T>
255 bool
256 xfinite (const std::complex<T>& x)
257 {
258  return (xfinite (real (x)) && xfinite (imag (x)));
259 }
260 
261 template <typename T>
262 bool
263 xisinf (const std::complex<T>& x)
264 {
265  return (xisinf (real (x)) || xisinf (imag (x)));
266 }
267 
268 template <typename T>
269 std::complex<T>
270 fix (const std::complex<T>& x)
271 {
272  return std::complex<T> (fix (real (x)), fix (imag (x)));
273 }
274 
275 template <typename T>
276 std::complex<T>
277 ceil (const std::complex<T>& x)
278 {
279  return std::complex<T> (xceil (real (x)), xceil (imag (x)));
280 }
281 
282 template <typename T>
283 std::complex<T>
284 floor (const std::complex<T>& x)
285 {
286  return std::complex<T> (xfloor (real (x)), xfloor (imag (x)));
287 }
288 
289 template <typename T>
290 std::complex<T>
291 xround (const std::complex<T>& x)
292 {
293  return std::complex<T> (xround (real (x)), xround (imag (x)));
294 }
295 
296 template <typename T>
297 std::complex<T>
298 xroundb (const std::complex<T>& x)
299 {
300  return std::complex<T> (xroundb (real (x)), xroundb (imag (x)));
301 }
302 
303 template <typename T>
304 std::complex<T>
305 signum (const std::complex<T>& x)
306 {
307  T tmp = abs (x);
308 
309  return tmp == 0 ? 0.0 : x / tmp;
310 }
311 
312 template <typename T>
313 T
314 xmod (T x, T y)
315 {
316  T retval;
317 
318  if (y == 0)
319  retval = x;
320  else
321  {
322  T q = x / y;
323 
324  T n = xfloor (q);
325 
326  if (X_NINT (y) != y)
327  {
328  if (X_NINT (q) == q)
329  n = q;
330  else
331  {
332  if (x >= -1 && x <= 1)
333  {
334  if (std::abs (q - X_NINT (q))
335  < std::numeric_limits<T>::epsilon ())
336  n = X_NINT (q);
337  }
338  else
339  {
340  if (std::abs ((q - X_NINT (q))/ X_NINT (q))
341  < std::numeric_limits<T>::epsilon ())
342  n = X_NINT (q);
343  }
344  }
345  }
346 
347  // Prevent use of extra precision.
348  volatile T tmp = y * n;
349 
350  retval = x - tmp;
351  }
352 
353  if (x != y && y != 0 && retval != 0)
354  retval = xcopysign (retval, y);
355 
356  return retval;
357 }
358 
359 template <typename T>
360 T
361 xrem (T x, T y)
362 {
363  T retval;
364 
365  if (y == 0)
366  retval = x;
367  else
368  {
369  T q = x / y;
370 
371  T n = xtrunc (q);
372 
373  if (X_NINT (y) != y)
374  {
375  if (X_NINT (q) == q)
376  n = q;
377  else
378  {
379  if (x >= -1 && x <= 1)
380  {
381  if (std::abs (q - X_NINT (q))
382  < std::numeric_limits<T>::epsilon ())
383  n = X_NINT (q);
384  }
385  else
386  {
387  if (std::abs ((q - X_NINT (q))/ X_NINT (q))
388  < std::numeric_limits<T>::epsilon ())
389  n = X_NINT (q);
390  }
391  }
392  }
393 
394  // Prevent use of extra precision.
395  volatile T tmp = y * n;
396 
397  retval = x - tmp;
398  }
399 
400  if (x != y && y != 0 && retval != 0)
401  retval = xcopysign (retval, x);
402 
403  return retval;
404 }
405 
406 template <typename T>
407 T
409 {
410  return signbit (x);
411 }
412 
413 #endif