GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
lo-mappers.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1996-2022 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if ! defined (octave_lo_mappers_h)
27#define octave_lo_mappers_h 1
28
29#include "octave-config.h"
30
31#include <cmath>
32
33#include <limits>
34
35#include "lo-ieee.h"
36#include "oct-cmplx.h"
37#include "oct-inttypes-fwd.h"
38
39namespace octave
40{
41 namespace math
42 {
43 extern OCTAVE_API bool isna (double x);
44 extern OCTAVE_API bool isna (float x);
45 extern OCTAVE_API bool isna (const Complex& x);
46 extern OCTAVE_API bool isna (const FloatComplex& x);
47
48 extern OCTAVE_API bool is_NaN_or_NA (const Complex& x);
49 extern OCTAVE_API bool is_NaN_or_NA (const FloatComplex& x);
50
51 inline double copysign (double x, double y) { return std::copysign (x, y); }
52 inline float copysign (float x, float y) { return std::copysignf (x, y); }
53
54 inline double signbit (double x) { return std::signbit (x); }
55 inline float signbit (float x) { return std::signbit (x); }
56
57 // Test for negative sign.
58 extern OCTAVE_API bool negative_sign (double x);
59 extern OCTAVE_API bool negative_sign (float x);
60
61 // Test for positive sign.
62 inline bool positive_sign (double x) { return ! negative_sign (x); }
63 inline bool positive_sign (float x) { return ! negative_sign (x); }
64
65 extern OCTAVE_API Complex acos (const Complex& x);
67
68 extern OCTAVE_API Complex asin (const Complex& x);
70
71 inline Complex atan (const Complex& x) { return std::atan (x); }
72 inline FloatComplex atan (const FloatComplex& x) { return std::atan (x); }
73
74 // The C++ standard would normally return a std::complex value for conj
75 // even when the input is fully real. Octave overrides this.
76 inline double conj (double x) { return x; }
77 inline float conj (float x) { return x; }
78
79 template <typename T>
80 std::complex<T>
81 conj (const std::complex<T>& x)
82 {
83 return std::conj (x);
84 }
85
86 inline double log2 (double x) { return std::log2 (x); }
87 inline float log2 (float x) { return std::log2f (x); }
88
89 extern OCTAVE_API Complex log2 (const Complex& x);
91
92 extern OCTAVE_API double log2 (double x, int& exp);
93 extern OCTAVE_API float log2 (float x, int& exp);
94
95 extern OCTAVE_API Complex log2 (const Complex& x, int& exp);
96 extern OCTAVE_API FloatComplex log2 (const FloatComplex& x, int& exp);
97
98 inline double exp2 (double x) { return std::exp2 (x); }
99 inline float exp2 (float x) { return std::exp2f (x); }
100
101 template <typename T>
102 std::complex<T>
103 ceil (const std::complex<T>& x)
104 {
105 return std::complex<T> (std::ceil (std::real (x)),
106 std::ceil (std::imag (x)));
107 }
108
109 template <typename T>
110 std::complex<T>
111 trunc (const std::complex<T>& x)
112 {
113 return std::complex<T> (std::trunc (std::real (x)),
115 }
116
117 // Provide alias for trunc under the more familiar name of fix.
118 inline double fix (double x) { return std::trunc (x); }
119 inline float fix (float x) { return std::trunc (x); }
120
121 template <typename T>
122 std::complex<T>
123 fix (const std::complex<T>& x)
124 {
125 return trunc (x);
126 }
127
128 template <typename T>
129 std::complex<T>
130 floor (const std::complex<T>& x)
131 {
132 return std::complex<T> (std::floor (std::real (x)),
134 }
135
136 inline double round (double x) { return std::round (x); }
137 inline float round (float x) { return std::roundf (x); }
138
139 template <typename T>
140 std::complex<T>
141 round (const std::complex<T>& x)
142 {
143 return std::complex<T> (round (std::real (x)), round (std::imag (x)));
144 }
145
146 inline double
147 roundb (double x)
148 {
149 double t = round (x);
150
151 if (fabs (x - t) == 0.5)
152 t = 2 * std::trunc (0.5 * t);
153
154 return t;
155 }
156
157 inline float
158 roundb (float x)
159 {
160 float t = round (x);
161
162 if (fabsf (x - t) == 0.5f)
163 t = 2 * std::trunc (0.5f * t);
164
165 return t;
166 }
167
168 template <typename T>
169 std::complex<T>
170 roundb (const std::complex<T>& x)
171 {
172 return std::complex<T> (roundb (std::real (x)), roundb (std::imag (x)));
173 }
174
175 extern OCTAVE_API double frexp (double x, int *expptr);
176 extern OCTAVE_API float frexp (float x, int *expptr);
177
178 inline bool isnan (bool) { return false; }
179 inline bool isnan (char) { return false; }
180
181 inline bool isnan (double x) { return std::isnan (x); }
182 inline bool isnan (float x) { return std::isnan (x); }
183
184 // FIXME: Do we need the isnan overload for complex?
185 template <typename T>
186 bool
187 isnan (const std::complex<T>& x)
188 {
189 return (isnan (std::real (x)) || isnan (std::imag (x)));
190 }
191
192 inline bool isfinite (double x) { return std::isfinite (x); }
193 inline bool isfinite (float x) { return std::isfinite (x); }
194
195 // FIXME: Do we need isfinite overload for complex?
196 template <typename T>
197 bool
198 isfinite (const std::complex<T>& x)
199 {
200 return (isfinite (std::real (x)) && isfinite (std::imag (x)));
201 }
202
203 inline bool isinf (double x) { return std::isinf (x); }
204 inline bool isinf (float x) { return std::isinf (x); }
205
206 template <typename T>
207 bool
209 {
210 return false;
211 }
212
213 // FIXME: Do we need isinf overload for complex?
214 template <typename T>
215 bool
216 isinf (const std::complex<T>& x)
217 {
218 return (isinf (std::real (x)) || isinf (std::imag (x)));
219 }
220
221 // Some useful tests, that are commonly repeated.
222 // Test for a finite integer.
223
224 // FIXME: Benchmark whether trunc might be faster than round here.
225 inline bool isinteger (double x) { return isfinite (x) && x == round (x); }
226 inline bool isinteger (float x) { return isfinite (x) && x == round (x); }
227
228 inline double
229 signum (double x)
230 {
231 double tmp = 0.0;
232
233 if (x < 0.0)
234 tmp = -1.0;
235 else if (x > 0.0)
236 tmp = 1.0;
237
238 return isnan (x) ? numeric_limits<double>::NaN () : tmp;
239 }
240
241 inline float
242 signum (float x)
243 {
244 float tmp = 0.0f;
245
246 if (x < 0.0f)
247 tmp = -1.0f;
248 else if (x > 0.0f)
249 tmp = 1.0f;
250
251 return isnan (x) ? numeric_limits<float>::NaN () : tmp;
252 }
253
254 template <typename T>
255 std::complex<T>
256 signum (const std::complex<T>& x)
257 {
258 T tmp = abs (x);
259
260 return tmp == 0 ? 0.0 : x / tmp;
261 }
262
263 // Convert X to the nearest integer value. Should not pass NaN to
264 // this function.
265
266 // For integer types? Hmm. Need to be sure T is an integer type...
267 template <typename T>
268 T
270 {
271 return x;
272 }
273
274 template <>
275 inline double x_nint (double x)
276 {
277 return (isfinite (x) ? std::floor (x + 0.5) : x);
278 }
279
280 template <>
281 inline float x_nint (float x)
282 {
283 return (isfinite (x) ? std::floor (x + 0.5f) : x);
284 }
285
286 extern OCTAVE_API octave_idx_type nint_big (double x);
287 extern OCTAVE_API octave_idx_type nint_big (float x);
288
289 extern OCTAVE_API int nint (double x);
290 extern OCTAVE_API int nint (float x);
291
292 template <typename T>
293 T
294 mod (T x, T y)
295 {
296 T retval;
297
298 if (y == 0)
299 retval = x;
300 else
301 {
302 T q = x / y;
303
304 if (x_nint (y) != y
305 && (std::abs ((q - x_nint (q)) / x_nint (q))
306 < std::numeric_limits<T>::epsilon ()))
307 retval = 0;
308 else
309 {
310 T n = std::floor (q);
311
312 // Prevent use of extra precision.
313 volatile T tmp = y * n;
314
315 retval = x - tmp;
316 }
317 }
318
319 if (x != y && y != 0)
320 retval = copysign (retval, y);
321
322 return retval;
323 }
324
325 template <typename T>
326 T
327 rem (T x, T y)
328 {
329 T retval;
330
331 if (y == 0)
332 retval = numeric_limits<T>::NaN ();
333 else
334 {
335 T q = x / y;
336
337 if (x_nint (y) != y
338 && (std::abs ((q - x_nint (q)) / x_nint (q))
339 < std::numeric_limits<T>::epsilon ()))
340 retval = 0;
341 else
342 {
343 T n = std::trunc (q);
344
345 // Prevent use of extra precision.
346 volatile T tmp = y * n;
347
348 retval = x - tmp;
349 }
350 }
351
352 if (x != y && y != 0)
353 retval = copysign (retval, x);
354
355 return retval;
356 }
357
358 // Generic min, max definitions
359 template <typename T>
360 T
361 min (T x, T y)
362 {
363 return x <= y ? x : y;
364 }
365
366 template <typename T>
367 T
368 max (T x, T y)
369 {
370 return x >= y ? x : y;
371 }
372
373 // This form is favorable. GCC will translate (x <= y ? x : y) without a
374 // jump, hence the only conditional jump involved will be the first
375 // (isnan), infrequent and hence friendly to branch prediction.
376
377 inline double
378 min (double x, double y)
379 {
380 return isnan (y) ? x : (x <= y ? x : y);
381 }
382
383 inline double
384 max (double x, double y)
385 {
386 return isnan (y) ? x : (x >= y ? x : y);
387 }
388
389 inline float
390 min (float x, float y)
391 {
392 return isnan (y) ? x : (x <= y ? x : y);
393 }
394
395 inline float
396 max (float x, float y)
397 {
398 return isnan (y) ? x : (x >= y ? x : y);
399 }
400
401 inline std::complex<double>
402 min (const std::complex<double>& x, const std::complex<double>& y)
403 {
404 return abs (x) <= abs (y) ? x : (isnan (x) ? x : y);
405 }
406
407 inline std::complex<float>
408 min (const std::complex<float>& x, const std::complex<float>& y)
409 {
410 return abs (x) <= abs (y) ? x : (isnan (x) ? x : y);
411 }
412
413 inline std::complex<double>
414 max (const std::complex<double>& x, const std::complex<double>& y)
415 {
416 return abs (x) >= abs (y) ? x : (isnan (x) ? x : y);
417 }
418
419 inline std::complex<float>
420 max (const std::complex<float>& x, const std::complex<float>& y)
421 {
422 return abs (x) >= abs (y) ? x : (isnan (x) ? x : y);
423 }
424
425 template <typename T>
426 inline octave_int<T>
427 min (const octave_int<T>& x, const octave_int<T>& y)
428 {
429 return xmin (x, y);
430 }
431
432 template <typename T>
433 inline octave_int<T>
434 max (const octave_int<T>& x, const octave_int<T>& y)
435 {
436 return xmax (x, y);
437 }
438
439 // These map reals to Complex.
440
441 extern OCTAVE_API Complex rc_acos (double);
442 extern OCTAVE_API FloatComplex rc_acos (float);
443
444 extern OCTAVE_API Complex rc_acosh (double);
445 extern OCTAVE_API FloatComplex rc_acosh (float);
446
447 extern OCTAVE_API Complex rc_asin (double);
448 extern OCTAVE_API FloatComplex rc_asin (float);
449
450 extern OCTAVE_API Complex rc_atanh (double);
451 extern OCTAVE_API FloatComplex rc_atanh (float);
452
453 extern OCTAVE_API Complex rc_log (double);
454 extern OCTAVE_API FloatComplex rc_log (float);
455
456 extern OCTAVE_API Complex rc_log2 (double);
457 extern OCTAVE_API FloatComplex rc_log2 (float);
458
459 extern OCTAVE_API Complex rc_log10 (double);
460 extern OCTAVE_API FloatComplex rc_log10 (float);
461
462 extern OCTAVE_API Complex rc_sqrt (double);
463 extern OCTAVE_API FloatComplex rc_sqrt (float);
464 }
465}
466
467#endif
#define NaN
Definition: Faddeeva.cc:261
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:137
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:143
F77_RET_T const F77_DBLE * x
#define OCTAVE_API
Definition: main.in.cc:55
double fix(double x)
Definition: lo-mappers.h:118
Complex atan(const Complex &x)
Definition: lo-mappers.h:71
std::complex< T > round(const std::complex< T > &x)
Definition: lo-mappers.h:141
double exp2(double x)
Definition: lo-mappers.h:98
double signum(double x)
Definition: lo-mappers.h:229
T max(T x, T y)
Definition: lo-mappers.h:368
T x_nint(T x)
Definition: lo-mappers.h:269
bool isna(double x)
Definition: lo-mappers.cc:47
Complex rc_acos(double x)
Definition: lo-mappers.cc:236
double signbit(double x)
Definition: lo-mappers.h:54
bool isfinite(const std::complex< T > &x)
Definition: lo-mappers.h:198
std::complex< T > conj(const std::complex< T > &x)
Definition: lo-mappers.h:81
bool isfinite(double x)
Definition: lo-mappers.h:192
float signbit(float x)
Definition: lo-mappers.h:55
int nint(double x)
Definition: lo-mappers.cc:212
double roundb(double x)
Definition: lo-mappers.h:147
double copysign(double x, double y)
Definition: lo-mappers.h:51
double frexp(double x, int *expptr)
Definition: lo-mappers.cc:128
T rem(T x, T y)
Definition: lo-mappers.h:327
bool isnan(bool)
Definition: lo-mappers.h:178
bool is_NaN_or_NA(const Complex &x)
Definition: lo-mappers.cc:71
bool isinf(double x)
Definition: lo-mappers.h:203
float copysign(float x, float y)
Definition: lo-mappers.h:52
octave_idx_type nint_big(double x)
Definition: lo-mappers.cc:184
Complex acos(const Complex &x)
Definition: lo-mappers.cc:85
double round(double x)
Definition: lo-mappers.h:136
Complex asin(const Complex &x)
Definition: lo-mappers.cc:107
FloatComplex atan(const FloatComplex &x)
Definition: lo-mappers.h:72
float exp2(float x)
Definition: lo-mappers.h:99
Complex rc_log2(double x)
Definition: lo-mappers.cc:300
std::complex< T > trunc(const std::complex< T > &x)
Definition: lo-mappers.h:111
Complex rc_log(double x)
Definition: lo-mappers.cc:287
double conj(double x)
Definition: lo-mappers.h:76
Complex rc_sqrt(double x)
Definition: lo-mappers.cc:330
bool isinteger(double x)
Definition: lo-mappers.h:225
float log2(float x)
Definition: lo-mappers.h:87
Complex rc_atanh(double x)
Definition: lo-mappers.cc:274
bool negative_sign(double x)
Definition: lo-mappers.cc:178
bool isnan(const std::complex< T > &x)
Definition: lo-mappers.h:187
Complex rc_acosh(double x)
Definition: lo-mappers.cc:249
Complex rc_log10(double x)
Definition: lo-mappers.cc:315
std::complex< T > ceil(const std::complex< T > &x)
Definition: lo-mappers.h:103
T mod(T x, T y)
Definition: lo-mappers.h:294
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:130
Complex rc_asin(double x)
Definition: lo-mappers.cc:261
Complex log2(const Complex &x)
Definition: lo-mappers.cc:139
bool isinf(const std::complex< T > &x)
Definition: lo-mappers.h:216
T min(T x, T y)
Definition: lo-mappers.h:361
bool positive_sign(double x)
Definition: lo-mappers.h:62
std::complex< double > Complex
Definition: oct-cmplx.h:33
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34
octave_int< T > xmin(const octave_int< T > &x, const octave_int< T > &y)
octave_int< T > xmax(const octave_int< T > &x, const octave_int< T > &y)
static T abs(T x)
Definition: pr-output.cc:1678