GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
lo-mappers.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1996-2025 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
46bool
47isna (double x)
48{
49 return lo_ieee_is_NA (x);
50}
51
52bool
53isna (const Complex& x)
54{
55 return (isna (std::real (x)) || isna (std::imag (x)));
56}
57
58bool
59isna (float x)
60{
61 return lo_ieee_is_NA (x);
62}
63
64bool
66{
67 return (isna (std::real (x)) || isna (std::imag (x)));
68}
69
70bool
72{
73 return (isnan (std::real (x)) || isnan (std::imag (x)));
74}
75
76bool
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.
85acos (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
107asin (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
128double
129frexp (double x, int *expptr)
130{
131 return octave_frexp_wrapper (x, expptr);
132}
133
134float
135frexp (float x, int *expptr)
136{
137 return octave_frexpf_wrapper (x, expptr);
138}
139
141log2 (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
152double
153log2 (double x, int& exp)
154{
155 return frexp (x, &exp);
156}
157
158float
159log2 (float x, int& exp)
160{
161 return frexp (x, &exp);
162}
163
165log2 (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
173log2 (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
180bool
181negative_sign (double x) { return signbit (x); }
182bool
183negative_sign (float x) { return signbit (x); }
184
185// Sometimes you need a large integer, but not always.
186
188nint_big (double x)
189{
190 static constexpr double out_of_range_top
191 = static_cast<double> (std::numeric_limits<octave_idx_type>::max ()) + 1.0;
192
193 if (x >= out_of_range_top)
194 return std::numeric_limits<octave_idx_type>::max ();
195 else if (x < std::numeric_limits<octave_idx_type>::min ())
196 return std::numeric_limits<octave_idx_type>::min ();
197 else
198 return static_cast<octave_idx_type> ((x > 0.0) ? (x + 0.5) : (x - 0.5));
199}
200
202nint_big (float x)
203{
204 static constexpr float out_of_range_top
205 = static_cast<float> (std::numeric_limits<octave_idx_type>::max ()) + 1.0;
206
207 if (x >= out_of_range_top)
208 return std::numeric_limits<octave_idx_type>::max ();
209 else if (x < std::numeric_limits<octave_idx_type>::min ())
210 return std::numeric_limits<octave_idx_type>::min ();
211 else
212 return static_cast<octave_idx_type> ((x > 0.0f) ? (x + 0.5f) : (x - 0.5f));
213}
214
215int
216nint (double x)
217{
218 if (x > std::numeric_limits<int>::max ())
219 return std::numeric_limits<int>::max ();
220 else if (x < std::numeric_limits<int>::min ())
221 return std::numeric_limits<int>::min ();
222 else
223 return static_cast<int> ((x > 0.0) ? (x + 0.5) : (x - 0.5));
224}
225
226int
227nint (float x)
228{
229 static constexpr float out_of_range_top
230 = static_cast<float> (std::numeric_limits<int>::max ()) + 1.0;
231
232 if (x >= out_of_range_top)
233 return std::numeric_limits<int>::max ();
234 else if (x < std::numeric_limits<int>::min ())
235 return std::numeric_limits<int>::min ();
236 else
237 return static_cast<int> ((x > 0.0f) ? (x + 0.5f) : (x - 0.5f));
238}
239
241rc_acos (double x)
242{
243 return fabs (x) > 1.0 ? acos (Complex (x)) : Complex (std::acos (x));
244}
245
247rc_acos (float x)
248{
249 return fabsf (x) > 1.0f ? acos (FloatComplex (x))
250 : FloatComplex (std::acos (x));
251}
252
254rc_acosh (double x)
255{
256 return x < 1.0 ? acosh (Complex (x)) : Complex (acosh (x));
257}
258
260rc_acosh (float x)
261{
262 return x < 1.0f ? acosh (FloatComplex (x)) : FloatComplex (acosh (x));
263}
264
266rc_asin (double x)
267{
268 return fabs (x) > 1.0 ? asin (Complex (x)) : Complex (std::asin (x));
269}
270
272rc_asin (float x)
273{
274 return fabsf (x) > 1.0f ? asin (FloatComplex (x))
275 : FloatComplex (::asinf (x));
276}
277
279rc_atanh (double x)
280{
281 return fabs (x) > 1.0 ? atanh (Complex (x)) : Complex (atanh (x));
282}
283
285rc_atanh (float x)
286{
287 return fabsf (x) > 1.0f ? atanh (FloatComplex (x))
288 : FloatComplex (atanh (x));
289}
290
292rc_log (double x)
293{
294 return x < 0.0 ? Complex (std::log (-x), M_PI) : Complex (std::log (x));
295}
296
298rc_log (float x)
299{
300 return x < 0.0f ? FloatComplex (std::log (-x), static_cast<float> (M_PI))
301 : FloatComplex (std::log (x));
302}
303
305rc_log2 (double x)
306{
307 constexpr double PI_LN2 = 4.53236014182719380962; // = pi / log(2)
308 return x < 0.0 ? Complex (log2 (-x), PI_LN2) : Complex (log2 (x));
309}
310
312rc_log2 (float x)
313{
314 constexpr float PI_LN2 = 4.53236014182719380962f; // = pi / log(2)
315 return x < 0.0f ? FloatComplex (log2 (-x), PI_LN2)
316 : FloatComplex (log2 (x));
317}
318
320rc_log10 (double x)
321{
322 constexpr double PI_LN10 = 1.36437635384184134748; // = pi / log(10)
323 return x < 0.0 ? Complex (log10 (-x), PI_LN10) : Complex (log10 (x));
324}
325
327rc_log10 (float x)
328{
329 constexpr float PI_LN10 = 1.36437635384184134748f; // = pi / log(10)
330 return x < 0.0f ? FloatComplex (log10 (-x), PI_LN10)
331 : FloatComplex (log10f (x));
332}
333
335rc_sqrt (double x)
336{
337 return x < 0.0 ? Complex (0.0, std::sqrt (-x)) : Complex (std::sqrt (x));
338}
339
341rc_sqrt (float x)
342{
343 return x < 0.0f ? FloatComplex (0.0f, std::sqrt (-x))
344 : FloatComplex (std::sqrt (x));
345}
346
347OCTAVE_END_NAMESPACE(math)
348OCTAVE_END_NAMESPACE(octave)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define lo_ieee_is_NA(x)
Definition lo-ieee.h:144
bool is_NaN_or_NA(const Complex &x)
Definition lo-mappers.cc:71
Complex log2(const Complex &x)
Complex rc_acosh(double x)
Complex rc_atanh(double x)
Complex rc_log(double x)
Complex asin(const Complex &x)
octave_idx_type nint_big(double x)
int nint(double x)
Complex rc_asin(double x)
bool negative_sign(double x)
bool isna(double x)
Definition lo-mappers.cc:47
Complex rc_acos(double x)
Complex rc_sqrt(double x)
Complex rc_log10(double x)
Complex acos(const Complex &x)
Definition lo-mappers.cc:85
Complex rc_log2(double x)
double frexp(double x, int *expptr)
double signbit(double x)
Definition lo-mappers.h:54
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)
float octave_frexpf_wrapper(float x, int *expptr)
std::complex< double > Complex
Definition oct-cmplx.h:33
std::complex< float > FloatComplex
Definition oct-cmplx.h:34