GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
lo-mappers.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2021 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 (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "lo-mappers.h"
31 #include "lo-specfun.h"
32 #include "math-wrappers.h"
33 
34 // FIXME: We used to have this situation:
35 //
36 // Functions that forward to gnulib belong here so we can keep
37 // gnulib:: out of lo-mappers.h.
38 //
39 // but now we just use std:: and explicit wrappers in C++ code so maybe
40 // some of the forwarding functions can be defined inline here.
41 
42 namespace octave
43 {
44  namespace math
45  {
46  bool
47  isna (double x)
48  {
49  return lo_ieee_is_NA (x);
50  }
51 
52  bool
53  isna (const Complex& x)
54  {
55  return (isna (std::real (x)) || isna (std::imag (x)));
56  }
57 
58  bool
59  isna (float x)
60  {
61  return lo_ieee_is_NA (x);
62  }
63 
64  bool
65  isna (const FloatComplex& x)
66  {
67  return (isna (std::real (x)) || isna (std::imag (x)));
68  }
69 
70  bool
72  {
73  return (isnan (std::real (x)) || isnan (std::imag (x)));
74  }
75 
76  bool
78  {
79  return (isnan (std::real (x)) || isnan (std::imag (x)));
80  }
81 
82  // Matlab returns a different phase for acos, asin then std library
83  // which requires a small function to remap the phase.
84  Complex
85  acos (const Complex& x)
86  {
87  Complex y = std::acos (x);
88 
89  if (std::imag (x) == 0.0 && std::real (x) > 1.0)
90  return std::conj (y);
91  else
92  return y;
93  }
94 
96  acos (const FloatComplex& x)
97  {
98  FloatComplex y = std::acos (x);
99 
100  if (std::imag (x) == 0.0f && std::real (x) > 1.0f)
101  return std::conj (y);
102  else
103  return y;
104  }
105 
106  Complex
107  asin (const Complex& x)
108  {
109  Complex y = std::asin (x);
110 
111  if (std::imag (x) == 0.0 && std::real (x) > 1.0)
112  return std::conj (y);
113  else
114  return y;
115  }
116 
118  asin (const FloatComplex& x)
119  {
120  FloatComplex y = std::asin (x);
121 
122  if (std::imag (x) == 0.0f && std::real (x) > 1.0f)
123  return std::conj (y);
124  else
125  return y;
126  }
127 
128  double frexp (double x, int *expptr)
129  {
130  return octave_frexp_wrapper (x, expptr);
131  }
132 
133  float frexp (float x, int *expptr)
134  {
135  return octave_frexpf_wrapper (x, expptr);
136  }
137 
138  Complex
139  log2 (const Complex& x)
140  {
141  return std::log (x) / M_LN2;
142  }
143 
145  log2 (const FloatComplex& x)
146  {
147  return std::log (x) / static_cast<float> (M_LN2);
148  }
149 
150  double
151  log2 (double x, int& exp)
152  {
153  return frexp (x, &exp);
154  }
155 
156  float
157  log2 (float x, int& exp)
158  {
159  return frexp (x, &exp);
160  }
161 
162  Complex
163  log2 (const Complex& x, int& exp)
164  {
165  double ax = std::abs (x);
166  double lax = log2 (ax, exp);
167  return (ax != lax) ? (x / ax) * lax : x;
168  }
169 
171  log2 (const FloatComplex& x, int& exp)
172  {
173  float ax = std::abs (x);
174  float lax = log2 (ax, exp);
175  return (ax != lax) ? (x / ax) * lax : x;
176  }
177 
178  bool negative_sign (double x) { return __lo_ieee_signbit (x); }
179  bool negative_sign (float x) { return __lo_ieee_float_signbit (x); }
180 
181  // Sometimes you need a large integer, but not always.
182 
184  nint_big (double x)
185  {
190  else
191  return static_cast<octave_idx_type> ((x > 0.0) ? (x + 0.5)
192  : (x - 0.5));
193  }
194 
196  nint_big (float x)
197  {
202  else
203  return static_cast<octave_idx_type> ((x > 0.0f) ? (x + 0.5f)
204  : (x - 0.5f));
205  }
206 
207  int
208  nint (double x)
209  {
212  else if (x < std::numeric_limits<int>::min ())
214  else
215  return static_cast<int> ((x > 0.0) ? (x + 0.5) : (x - 0.5));
216  }
217 
218  int
219  nint (float x)
220  {
223  else if (x < std::numeric_limits<int>::min ())
225  else
226  return static_cast<int> ((x > 0.0f) ? (x + 0.5f) : (x - 0.5f));
227  }
228 
229  Complex
230  rc_acos (double x)
231  {
232  return fabs (x) > 1.0 ? acos (Complex (x)) : Complex (std::acos (x));
233  }
234 
236  rc_acos (float x)
237  {
238  return fabsf (x) > 1.0f ? acos (FloatComplex (x))
239  : FloatComplex (std::acos (x));
240  }
241 
242  Complex
243  rc_acosh (double x)
244  {
245  return x < 1.0 ? acosh (Complex (x)) : Complex (acosh (x));
246  }
247 
249  rc_acosh (float x)
250  {
251  return x < 1.0f ? acosh (FloatComplex (x)) : FloatComplex (acosh (x));
252  }
253 
254  Complex
255  rc_asin (double x)
256  {
257  return fabs (x) > 1.0 ? asin (Complex (x)) : Complex (std::asin (x));
258  }
259 
261  rc_asin (float x)
262  {
263  return fabsf (x) > 1.0f ? asin (FloatComplex (x))
264  : FloatComplex (::asinf (x));
265  }
266 
267  Complex
268  rc_atanh (double x)
269  {
270  return fabs (x) > 1.0 ? atanh (Complex (x)) : Complex (atanh (x));
271  }
272 
274  rc_atanh (float x)
275  {
276  return fabsf (x) > 1.0f ? atanh (FloatComplex (x))
277  : FloatComplex (atanh (x));
278  }
279 
280  Complex
281  rc_log (double x)
282  {
283  return x < 0.0 ? Complex (std::log (-x), M_PI) : Complex (std::log (x));
284  }
285 
287  rc_log (float x)
288  {
289  return x < 0.0f ? FloatComplex (std::log (-x), static_cast<float> (M_PI))
290  : FloatComplex (std::log (x));
291  }
292 
293  Complex
294  rc_log2 (double x)
295  {
296  constexpr double PI_LN2 = 4.53236014182719380962; // = pi / log(2)
297  return x < 0.0 ? Complex (log2 (-x), PI_LN2) : Complex (log2 (x));
298  }
299 
301  rc_log2 (float x)
302  {
303  constexpr float PI_LN2 = 4.53236014182719380962f; // = pi / log(2)
304  return x < 0.0f ? FloatComplex (log2 (-x), PI_LN2)
305  : FloatComplex (log2 (x));
306  }
307 
308  Complex
309  rc_log10 (double x)
310  {
311  constexpr double PI_LN10 = 1.36437635384184134748; // = pi / log(10)
312  return x < 0.0 ? Complex (log10 (-x), PI_LN10) : Complex (log10 (x));
313  }
314 
316  rc_log10 (float x)
317  {
318  constexpr float PI_LN10 = 1.36437635384184134748f; // = pi / log(10)
319  return x < 0.0f ? FloatComplex (log10 (-x), PI_LN10)
320  : FloatComplex (log10f (x));
321  }
322 
323  Complex
324  rc_sqrt (double x)
325  {
326  return x < 0.0 ? Complex (0.0, std::sqrt (-x)) : Complex (std::sqrt (x));
327  }
328 
330  rc_sqrt (float x)
331  {
332  return x < 0.0f ? FloatComplex (0.0f, std::sqrt (-x))
333  : FloatComplex (std::sqrt (x));
334  }
335  }
336 }
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:217
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:137
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:143
int __lo_ieee_signbit(double x)
Definition: lo-ieee.h:94
int __lo_ieee_float_signbit(float x)
Definition: lo-ieee.h:106
#define lo_ieee_is_NA(x)
Definition: lo-ieee.h:124
F77_RET_T const F77_DBLE * x
double octave_frexp_wrapper(double x, int *expptr)
Definition: math-wrappers.c:40
float octave_frexpf_wrapper(float x, int *expptr)
Definition: math-wrappers.c:46
bool isna(double x)
Definition: lo-mappers.cc:47
Complex rc_acos(double x)
Definition: lo-mappers.cc:230
double atanh(double x)
Definition: lo-specfun.h:74
int nint(double x)
Definition: lo-mappers.cc:208
double frexp(double x, int *expptr)
Definition: lo-mappers.cc:128
bool isnan(bool)
Definition: lo-mappers.h:178
bool is_NaN_or_NA(const Complex &x)
Definition: lo-mappers.cc:71
octave_idx_type nint_big(double x)
Definition: lo-mappers.cc:184
Complex acos(const Complex &x)
Definition: lo-mappers.cc:85
Complex asin(const Complex &x)
Definition: lo-mappers.cc:107
Complex rc_log2(double x)
Definition: lo-mappers.cc:294
Complex rc_log(double x)
Definition: lo-mappers.cc:281
double acosh(double x)
Definition: lo-specfun.h:51
Complex rc_sqrt(double x)
Definition: lo-mappers.cc:324
Complex rc_atanh(double x)
Definition: lo-mappers.cc:268
bool negative_sign(double x)
Definition: lo-mappers.cc:178
Complex rc_acosh(double x)
Definition: lo-mappers.cc:243
FloatComplex acos(const FloatComplex &x)
Definition: lo-mappers.cc:96
Complex rc_log10(double x)
Definition: lo-mappers.cc:309
Complex rc_asin(double x)
Definition: lo-mappers.cc:255
Complex log2(const Complex &x)
Definition: lo-mappers.cc:139
FloatComplex asin(const FloatComplex &x)
Definition: lo-mappers.cc:118
std::complex< double > Complex
Definition: oct-cmplx.h:33
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34
static T abs(T x)
Definition: pr-output.cc:1678