GNU Octave  4.2.1
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.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2017 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 (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include <cfloat>
29 
30 #include "lo-error.h"
31 #include "lo-ieee.h"
32 #include "lo-mappers.h"
33 #include "lo-math.h"
34 #include "lo-specfun.h"
35 #include "lo-utils.h"
36 #include "math-wrappers.h"
37 #include "oct-cmplx.h"
38 
39 #include "f77-fcn.h"
40 
41 // FIXME: We used to have this situation:
42 //
43 // Functions that forward to gnulib belong here so we can keep
44 // gnulib:: out of lo-mappers.h.
45 //
46 // but now we just use std:: and explicit wrappers in C++ code so maybe
47 // some of the forwarding functions can be defined inline here.
48 
49 namespace octave
50 {
51  namespace math
52  {
53  bool
54  is_NA (double x)
55  {
56  return lo_ieee_is_NA (x);
57  }
58 
59  bool
60  is_NA (const Complex& x)
61  {
62  return (is_NA (std::real (x)) || is_NA (std::imag (x)));
63  }
64 
65  bool
66  is_NA (float x)
67  {
68  return lo_ieee_is_NA (x);
69  }
70 
71  bool
72  is_NA (const FloatComplex& x)
73  {
74  return (is_NA (std::real (x)) || is_NA (std::imag (x)));
75  }
76 
77  bool
79  {
80  return (isnan (std::real (x)) || isnan (std::imag (x)));
81  }
82 
83  bool
85  {
86  return (isnan (std::real (x)) || isnan (std::imag (x)));
87  }
88 
89  Complex
90  acos (const Complex& x)
91  {
92 #if defined (HAVE_COMPLEX_STD_ACOS)
93  Complex y = std::acos (x);
94 
95  if (std::imag (x) == 0.0 && std::real (x) > 1.0)
96  return std::conj (y);
97  else
98  return y;
99 #else
100  static Complex i (0, 1);
101 
102  Complex tmp;
103 
104  if (std::imag (x) == 0.0)
105  {
106  // If the imaginary part of X is 0, then avoid generating an
107  // imaginary part of -0 for the expression 1-x*x.
108  // This chooses the same phase of the branch cut as Matlab.
109  double xr = std::real (x);
110  tmp = Complex (1.0 - xr*xr);
111  }
112  else
113  tmp = 1.0 - x*x;
114 
115  return -i * log (x + i * sqrt (tmp));
116 #endif
117  }
118 
120  acos (const FloatComplex& x)
121  {
122 #if defined (HAVE_COMPLEX_STD_ACOS)
123  FloatComplex y = std::acos (x);
124 
125  if (std::imag (x) == 0.0f && std::real (x) > 1.0f)
126  return std::conj (y);
127  else
128  return y;
129 #else
130  static FloatComplex i (0, 1);
131 
133 
134  if (std::imag (x) == 0.0f)
135  {
136  // If the imaginary part of X is 0, then avoid generating an
137  // imaginary part of -0 for the expression 1-x*x.
138  // This chooses the same phase of the branch cut as Matlab.
139  float xr = std::real (x);
140  tmp = FloatComplex (1.0f - xr*xr);
141  }
142  else
143  tmp = 1.0f - x*x;
144 
145  return -i * log (x + i * sqrt (tmp));
146 #endif
147  }
148 
149  Complex
150  asin (const Complex& x)
151  {
152 #if defined (HAVE_COMPLEX_STD_ASIN)
153  Complex y = std::asin (x);
154 
155  if (std::imag (x) == 0.0 && std::real (x) > 1.0)
156  return std::conj (y);
157  else
158  return y;
159 #else
160  static Complex i (0, 1);
161 
162  Complex tmp;
163 
164  if (std::imag (x) == 0.0)
165  {
166  // If the imaginary part of X is 0, then avoid generating an
167  // imaginary part of -0 for the expression 1-x*x.
168  // This chooses the same phase of the branch cut as Matlab.
169  double xr = std::real (x);
170  tmp = Complex (1.0 - xr*xr);
171  }
172  else
173  tmp = 1.0 - x*x;
174 
175  return -i * log (i*x + sqrt (tmp));
176 #endif
177  }
178 
180  asin (const FloatComplex& x)
181  {
182 #if defined (HAVE_COMPLEX_STD_ASIN)
183  FloatComplex y = std::asin (x);
184 
185  if (std::imag (x) == 0.0f && std::real (x) > 1.0f)
186  return std::conj (y);
187  else
188  return y;
189 #else
190  static FloatComplex i (0, 1);
191 
193 
194  if (std::imag (x) == 0.0f)
195  {
196  // If the imaginary part of X is 0, then avoid generating an
197  // imaginary part of -0 for the expression 1-x*x.
198  // This chooses the same phase of the branch cut as Matlab.
199  float xr = std::real (x);
200  tmp = FloatComplex (1.0f - xr*xr);
201  }
202  else
203  tmp = 1.0f - x*x;
204 
205  return -i * log (i*x + sqrt (tmp));
206 #endif
207  }
208 
209  Complex
210  atan (const Complex& x)
211  {
212 #if defined (HAVE_COMPLEX_STD_ATAN)
213  return std::atan (x);
214 #else
215  static Complex i (0, 1);
216 
217  return i * log ((i + x) / (i - x)) / 2.0;
218 #endif
219  }
220 
222  atan (const FloatComplex& x)
223  {
224 #if defined (HAVE_COMPLEX_STD_ATAN)
225  return std::atan (x);
226 #else
227  static FloatComplex i (0, 1);
228 
229  return i * log ((i + x) / (i - x)) / 2.0f;
230 #endif
231  }
232 
233  double log2 (double x) { return std::log2 (x); }
234  float log2 (float x) { return std::log2 (x); }
235 
236  Complex
237  log2 (const Complex& x)
238  {
239 #if defined (M_LN2)
240  static double ln2 = M_LN2;
241 #else
242  static double ln2 = std::log (2.0);
243 #endif
244  return std::log (x) / ln2;
245  }
246 
248  log2 (const FloatComplex& x)
249  {
250 #if defined (M_LN2)
251  static float ln2 = M_LN2;
252 #else
253  static float ln2 = log (2.0f);
254 #endif
255  return std::log (x) / ln2;
256  }
257 
258  double
259  log2 (double x, int& exp)
260  {
261  return frexp (x, &exp);
262  }
263 
264  float
265  log2 (float x, int& exp)
266  {
267  return frexp (x, &exp);
268  }
269 
270  Complex
271  log2 (const Complex& x, int& exp)
272  {
273  double ax = std::abs (x);
274  double lax = log2 (ax, exp);
275  return (ax != lax) ? (x / ax) * lax : x;
276  }
277 
279  log2 (const FloatComplex& x, int& exp)
280  {
281  float ax = std::abs (x);
282  float lax = log2 (ax, exp);
283  return (ax != lax) ? (x / ax) * lax : x;
284  }
285 
286  double
287  exp2 (double x)
288  {
289 #if defined (HAVE_EXP2)
290  return ::exp2 (x);
291 #else
292 # if defined (M_LN2)
293  static double ln2 = M_LN2;
294 # else
295  static double ln2 = std::log (2.0);
296 # endif
297  return exp (x * ln2);
298 #endif
299  }
300 
301  float
302  exp2 (float x)
303  {
304 #if defined (HAVE_EXP2F)
305  return exp2f (x);
306 #elif defined (HAVE_EXP2)
307  return ::exp2 (x);
308 #else
309 # if defined (M_LN2)
310  static float ln2 = M_LN2;
311 # else
312  static float ln2 = log2 (2.0f);
313 # endif
314  return exp (x * ln2);
315 #endif
316  }
317 
318  double copysign (double x, double y) { return std::copysign (x, y); }
319  float copysign (float x, float y) { return std::copysign (x, y); }
320 
321  double signbit (double x) { return std::signbit (x); }
322  float signbit (float x) { return std::signbit (x); }
323 
324  bool negative_sign (double x) { return __lo_ieee_signbit (x); }
325  bool negative_sign (float x) { return __lo_ieee_float_signbit (x); }
326 
327  double trunc (double x) { return std::trunc (x); }
328  float trunc (float x) { return std::trunc (x); }
329 
330  double floor (double x) { return std::floor (x); }
331  float floor (float x) { return std::floor (x); }
332 
333  double round (double x) { return std::round (x); }
334  float round (float x) { return std::round (x); }
335 
336  double frexp (double x, int *expptr)
337  {
338  return octave_frexp_wrapper (x, expptr);
339  }
340 
341  float frexp (float x, int *expptr)
342  {
343  return octave_frexpf_wrapper (x, expptr);
344  }
345 
346  bool
347  isnan (double x)
348  {
349 #if defined (HAVE_CMATH_ISNAN)
350  return std::isnan (x);
351 #else
352  return lo_ieee_isnan (x);
353 #endif
354  }
355 
356  bool
357  isnan (float x)
358  {
359 #if defined (HAVE_CMATH_ISNANF)
360  return std::isnan (x);
361 #else
362  return lo_ieee_isnan (x);
363 #endif
364  }
365 
366  bool
367  finite (double x)
368  {
369 #if defined (HAVE_CMATH_ISFINITE)
370  return std::isfinite (x);
371 #else
372  return lo_ieee_finite (x);
373 #endif
374  }
375 
376  bool
377  finite (float x)
378  {
379 #if defined (HAVE_CMATH_ISFINITEF)
380  return std::isfinite (x);
381 #else
382  return lo_ieee_finite (x);
383 #endif
384  }
385 
386  bool
387  isinf (double x)
388  {
389 #if defined (HAVE_CMATH_ISINF)
390  return std::isinf (x);
391 #else
392  return lo_ieee_isinf (x);
393 #endif
394  }
395 
396  bool
397  isinf (float x)
398  {
399 #if defined (HAVE_CMATH_ISINFF)
400  return std::isinf (x);
401 #else
402  return lo_ieee_isinf (x);
403 #endif
404  }
405 
406  // Sometimes you need a large integer, but not always.
407 
409  nint_big (double x)
410  {
415  else
416  return static_cast<octave_idx_type> ((x > 0.0) ? (x + 0.5)
417  : (x - 0.5));
418  }
419 
421  nint_big (float x)
422  {
427  else
428  return static_cast<octave_idx_type> ((x > 0.0f) ? (x + 0.5f)
429  : (x - 0.5f));
430  }
431 
432  int
433  nint (double x)
434  {
437  else if (x < std::numeric_limits<int>::min ())
439  else
440  return static_cast<int> ((x > 0.0) ? (x + 0.5) : (x - 0.5));
441  }
442 
443  int
444  nint (float x)
445  {
448  else if (x < std::numeric_limits<int>::min ())
450  else
451  return static_cast<int> ((x > 0.0f) ? (x + 0.5f) : (x - 0.5f));
452  }
453 
454  Complex
455  rc_acos (double x)
456  {
457  return fabs (x) > 1.0 ? acos (Complex (x)) : Complex (::acos (x));
458  }
459 
461  rc_acos (float x)
462  {
463  return fabsf (x) > 1.0f ? acos (FloatComplex (x))
464  : FloatComplex (::acosf (x));
465  }
466 
467  Complex
468  rc_acosh (double x)
469  {
470  return x < 1.0 ? acosh (Complex (x)) : Complex (acosh (x));
471  }
472 
474  rc_acosh (float x)
475  {
476  return x < 1.0f ? acosh (FloatComplex (x)) : FloatComplex (acosh (x));
477  }
478 
479  Complex
480  rc_asin (double x)
481  {
482  return fabs (x) > 1.0 ? asin (Complex (x)) : Complex (::asin (x));
483  }
484 
486  rc_asin (float x)
487  {
488  return fabsf (x) > 1.0f ? asin (FloatComplex (x))
489  : FloatComplex (::asinf (x));
490  }
491 
492  Complex
493  rc_atanh (double x)
494  {
495  return fabs (x) > 1.0 ? atanh (Complex (x)) : Complex (atanh (x));
496  }
497 
499  rc_atanh (float x)
500  {
501  return fabsf (x) > 1.0f ? atanh (FloatComplex (x))
502  : FloatComplex (atanh (x));
503  }
504 
505  Complex
506  rc_log (double x)
507  {
508  const double pi = 3.14159265358979323846;
509  return x < 0.0 ? Complex (std::log (-x), pi) : Complex (std::log (x));
510  }
511 
513  rc_log (float x)
514  {
515  const float pi = 3.14159265358979323846f;
516  return x < 0.0f ? FloatComplex (std::log (-x), pi)
517  : FloatComplex (std::log (x));
518  }
519 
520  Complex
521  rc_log2 (double x)
522  {
523  const double pil2 = 4.53236014182719380962; // = pi / log(2)
524  return x < 0.0 ? Complex (log2 (-x), pil2) : Complex (log2 (x));
525  }
526 
528  rc_log2 (float x)
529  {
530  const float pil2 = 4.53236014182719380962f; // = pi / log(2)
531  return x < 0.0f ? FloatComplex (log2 (-x), pil2)
532  : FloatComplex (log2 (x));
533  }
534 
535  Complex
536  rc_log10 (double x)
537  {
538  const double pil10 = 1.36437635384184134748; // = pi / log(10)
539  return x < 0.0 ? Complex (log10 (-x), pil10) : Complex (log10 (x));
540  }
541 
543  rc_log10 (float x)
544  {
545  const float pil10 = 1.36437635384184134748f; // = pi / log(10)
546  return x < 0.0f ? FloatComplex (log10 (-x), pil10)
547  : FloatComplex (log10f (x));
548  }
549 
550  Complex
551  rc_sqrt (double x)
552  {
553  return x < 0.0 ? Complex (0.0, sqrt (-x)) : Complex (sqrt (x));
554  }
555 
557  rc_sqrt (float x)
558  {
559  return x < 0.0f ? FloatComplex (0.0f, sqrtf (-x))
560  : FloatComplex (sqrtf (x));
561  }
562  }
563 }
int __lo_ieee_signbit(double x)
Definition: lo-ieee.cc:134
#define lo_ieee_is_NA(x)
Definition: lo-ieee.h:115
Octave interface to the compression and uncompression libraries.
Definition: aepbalance.cc:47
Complex rc_log10(double x)
Definition: lo-mappers.cc:536
FloatComplex asin(const FloatComplex &x)
Definition: lo-mappers.cc:180
float round(float x)
Definition: lo-mappers.cc:334
int __lo_ieee_float_signbit(float x)
Definition: lo-ieee.cc:210
Complex rc_acosh(double x)
Definition: lo-mappers.cc:468
Complex rc_sqrt(double x)
Definition: lo-mappers.cc:551
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE * f
double exp2(double x)
Definition: lo-mappers.cc:287
bool isnan(double x)
Definition: lo-mappers.cc:347
double trunc(double x)
Definition: lo-mappers.cc:327
double atanh(double x)
Definition: lo-specfun.cc:149
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the base of natural logarithms The constant ex $e satisfies the equation log(e)
#define lo_ieee_finite(x)
Definition: lo-ieee.h:107
Complex acos(const Complex &x)
Definition: lo-mappers.cc:90
#define lo_ieee_isinf(x)
Definition: lo-ieee.h:111
Complex asin(const Complex &x)
Definition: lo-mappers.cc:150
double frexp(double x, int *expptr)
Definition: lo-mappers.cc:336
double acosh(double x)
Definition: lo-specfun.cc:61
double round(double x)
Definition: lo-mappers.cc:333
bool is_NA(double x)
Definition: lo-mappers.cc:54
#define lo_ieee_isnan(x)
Definition: lo-ieee.h:103
float signbit(float x)
Definition: lo-mappers.cc:322
Complex rc_atanh(double x)
Definition: lo-mappers.cc:493
bool isinf(float x)
Definition: lo-mappers.cc:397
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:216
float octave_frexpf_wrapper(float x, int *expptr)
Definition: math-wrappers.c:43
double octave_frexp_wrapper(double x, int *expptr)
Definition: math-wrappers.c:37
Complex atan(const Complex &x)
Definition: lo-mappers.cc:210
float floor(float x)
Definition: lo-mappers.cc:331
double copysign(double x, double y)
Definition: lo-mappers.cc:318
Complex rc_log2(double x)
Definition: lo-mappers.cc:521
double tmp
Definition: data.cc:6300
Complex rc_log(double x)
Definition: lo-mappers.cc:506
double signbit(double x)
Definition: lo-mappers.cc:321
bool finite(double x)
Definition: lo-mappers.cc:367
FloatComplex acos(const FloatComplex &x)
Definition: lo-mappers.cc:120
bool isinf(double x)
Definition: lo-mappers.cc:387
Complex rc_acos(double x)
Definition: lo-mappers.cc:455
FloatComplex log2(const FloatComplex &x, int &exp)
Definition: lo-mappers.cc:279
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:228
bool is_NaN_or_NA(const Complex &x)
Definition: lo-mappers.cc:78
float copysign(float x, float y)
Definition: lo-mappers.cc:319
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
octave_idx_type nint_big(double x)
Definition: lo-mappers.cc:409
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup abs(local error in x(i))<
bool negative_sign(double x)
Definition: lo-mappers.cc:324
Complex rc_asin(double x)
Definition: lo-mappers.cc:480
the element is set to zero In other the statement xample y
Definition: data.cc:5342
float exp2(float x)
Definition: lo-mappers.cc:302
FloatComplex atan(const FloatComplex &x)
Definition: lo-mappers.cc:222
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:142
double floor(double x)
Definition: lo-mappers.cc:330
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
std::complex< double > Complex
Definition: oct-cmplx.h:31
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:136
bool isnan(float x)
Definition: lo-mappers.cc:357
double log2(double x)
Definition: lo-mappers.cc:233
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:205
static const double pi
Definition: lo-specfun.cc:3610
int nint(double x)
Definition: lo-mappers.cc:433
float trunc(float x)
Definition: lo-mappers.cc:328