GNU Octave  9.1.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-2024 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 
43 
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
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 
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 
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
129 frexp (double x, int *expptr)
130 {
131  return octave_frexp_wrapper (x, expptr);
132 }
133 
134 float
135 frexp (float x, int *expptr)
136 {
137  return octave_frexpf_wrapper (x, expptr);
138 }
139 
140 Complex
141 log2 (const Complex& x)
142 {
143  return std::log (x) / M_LN2;
144 }
145 
148 {
149  return std::log (x) / static_cast<float> (M_LN2);
150 }
151 
152 double
153 log2 (double x, int& exp)
154 {
155  return frexp (x, &exp);
156 }
157 
158 float
159 log2 (float x, int& exp)
160 {
161  return frexp (x, &exp);
162 }
163 
164 Complex
165 log2 (const Complex& x, int& exp)
166 {
167  double ax = std::abs (x);
168  double lax = log2 (ax, exp);
169  return (ax != lax) ? (x / ax) * lax : x;
170 }
171 
173 log2 (const FloatComplex& x, int& exp)
174 {
175  float ax = std::abs (x);
176  float lax = log2 (ax, exp);
177  return (ax != lax) ? (x / ax) * lax : x;
178 }
179 
180 bool
181 negative_sign (double x) { return __lo_ieee_signbit (x); }
182 bool
184 
185 // Sometimes you need a large integer, but not always.
186 
188 nint_big (double x)
189 {
190  static const double out_of_range_top
191  = static_cast<double> (std::numeric_limits<octave_idx_type>::max ())+1.;
192  if (x >= out_of_range_top)
196  else
197  return static_cast<octave_idx_type> ((x > 0.0) ? (x + 0.5)
198  : (x - 0.5));
199 }
200 
202 nint_big (float x)
203 {
204  static const float out_of_range_top
205  = static_cast<float> (std::numeric_limits<octave_idx_type>::max ())+1.;
206  if (x >= out_of_range_top)
210  else
211  return static_cast<octave_idx_type> ((x > 0.0f) ? (x + 0.5f)
212  : (x - 0.5f));
213 }
214 
215 int
216 nint (double x)
217 {
220  else if (x < std::numeric_limits<int>::min ())
222  else
223  return static_cast<int> ((x > 0.0) ? (x + 0.5) : (x - 0.5));
224 }
225 
226 int
227 nint (float x)
228 {
229  static const float out_of_range_top
230  = static_cast<float> (std::numeric_limits<int>::max ()) + 1.;
231  if (x >= out_of_range_top)
233  else if (x < std::numeric_limits<int>::min ())
235  else
236  return static_cast<int> ((x > 0.0f) ? (x + 0.5f) : (x - 0.5f));
237 }
238 
239 Complex
240 rc_acos (double x)
241 {
242  return fabs (x) > 1.0 ? acos (Complex (x)) : Complex (std::acos (x));
243 }
244 
246 rc_acos (float x)
247 {
248  return fabsf (x) > 1.0f ? acos (FloatComplex (x))
249  : FloatComplex (std::acos (x));
250 }
251 
252 Complex
253 rc_acosh (double x)
254 {
255  return x < 1.0 ? acosh (Complex (x)) : Complex (acosh (x));
256 }
257 
259 rc_acosh (float x)
260 {
261  return x < 1.0f ? acosh (FloatComplex (x)) : FloatComplex (acosh (x));
262 }
263 
264 Complex
265 rc_asin (double x)
266 {
267  return fabs (x) > 1.0 ? asin (Complex (x)) : Complex (std::asin (x));
268 }
269 
271 rc_asin (float x)
272 {
273  return fabsf (x) > 1.0f ? asin (FloatComplex (x))
274  : FloatComplex (::asinf (x));
275 }
276 
277 Complex
278 rc_atanh (double x)
279 {
280  return fabs (x) > 1.0 ? atanh (Complex (x)) : Complex (atanh (x));
281 }
282 
284 rc_atanh (float x)
285 {
286  return fabsf (x) > 1.0f ? atanh (FloatComplex (x))
287  : FloatComplex (atanh (x));
288 }
289 
290 Complex
291 rc_log (double x)
292 {
293  return x < 0.0 ? Complex (std::log (-x), M_PI) : Complex (std::log (x));
294 }
295 
297 rc_log (float x)
298 {
299  return x < 0.0f ? FloatComplex (std::log (-x), static_cast<float> (M_PI))
300  : FloatComplex (std::log (x));
301 }
302 
303 Complex
304 rc_log2 (double x)
305 {
306  constexpr double PI_LN2 = 4.53236014182719380962; // = pi / log(2)
307  return x < 0.0 ? Complex (log2 (-x), PI_LN2) : Complex (log2 (x));
308 }
309 
311 rc_log2 (float x)
312 {
313  constexpr float PI_LN2 = 4.53236014182719380962f; // = pi / log(2)
314  return x < 0.0f ? FloatComplex (log2 (-x), PI_LN2)
315  : FloatComplex (log2 (x));
316 }
317 
318 Complex
319 rc_log10 (double x)
320 {
321  constexpr double PI_LN10 = 1.36437635384184134748; // = pi / log(10)
322  return x < 0.0 ? Complex (log10 (-x), PI_LN10) : Complex (log10 (x));
323 }
324 
326 rc_log10 (float x)
327 {
328  constexpr float PI_LN10 = 1.36437635384184134748f; // = pi / log(10)
329  return x < 0.0f ? FloatComplex (log10 (-x), PI_LN10)
330  : FloatComplex (log10f (x));
331 }
332 
333 Complex
334 rc_sqrt (double x)
335 {
336  return x < 0.0 ? Complex (0.0, std::sqrt (-x)) : Complex (std::sqrt (x));
337 }
338 
340 rc_sqrt (float x)
341 {
342  return x < 0.0f ? FloatComplex (0.0f, std::sqrt (-x))
343  : FloatComplex (std::sqrt (x));
344 }
345 
346 OCTAVE_END_NAMESPACE(math)
347 OCTAVE_END_NAMESPACE(octave)
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
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
int __lo_ieee_signbit(double x)
Definition: lo-ieee.h:91
int __lo_ieee_float_signbit(float x)
Definition: lo-ieee.h:97
#define lo_ieee_is_NA(x)
Definition: lo-ieee.h:128
bool is_NaN_or_NA(const Complex &x)
Definition: lo-mappers.cc:71
Complex log2(const Complex &x)
Definition: lo-mappers.cc:141
Complex rc_acosh(double x)
Definition: lo-mappers.cc:253
Complex rc_atanh(double x)
Definition: lo-mappers.cc:278
Complex rc_log(double x)
Definition: lo-mappers.cc:291
Complex asin(const Complex &x)
Definition: lo-mappers.cc:107
octave_idx_type nint_big(double x)
Definition: lo-mappers.cc:188
int nint(double x)
Definition: lo-mappers.cc:216
Complex rc_asin(double x)
Definition: lo-mappers.cc:265
bool negative_sign(double x)
Definition: lo-mappers.cc:181
bool isna(double x)
Definition: lo-mappers.cc:47
Complex rc_acos(double x)
Definition: lo-mappers.cc:240
Complex rc_sqrt(double x)
Definition: lo-mappers.cc:334
Complex rc_log10(double x)
Definition: lo-mappers.cc:319
Complex acos(const Complex &x)
Definition: lo-mappers.cc:85
Complex rc_log2(double x)
Definition: lo-mappers.cc:304
double frexp(double x, int *expptr)
Definition: lo-mappers.cc:129
bool isnan(bool)
Definition: lo-mappers.h:178
F77_RET_T const F77_DBLE * x
double atanh(double x)
Definition: lo-specfun.h:63
double acosh(double x)
Definition: lo-specfun.h:40
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
std::complex< double > Complex
Definition: oct-cmplx.h:33
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34