GNU Octave 7.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-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 (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
42namespace 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
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.
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 {
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 {
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
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 {
186 static const double out_of_range_top
187 = static_cast<double>(std::numeric_limits<octave_idx_type>::max ())+1.;
188 if (x >= out_of_range_top)
192 else
193 return static_cast<octave_idx_type> ((x > 0.0) ? (x + 0.5)
194 : (x - 0.5));
195 }
196
198 nint_big (float x)
199 {
200 static const float out_of_range_top
201 = static_cast<float>(std::numeric_limits<octave_idx_type>::max ())+1.;
202 if (x >= out_of_range_top)
206 else
207 return static_cast<octave_idx_type> ((x > 0.0f) ? (x + 0.5f)
208 : (x - 0.5f));
209 }
210
211 int
212 nint (double x)
213 {
216 else if (x < std::numeric_limits<int>::min ())
218 else
219 return static_cast<int> ((x > 0.0) ? (x + 0.5) : (x - 0.5));
220 }
221
222 int
223 nint (float x)
224 {
225 static const float out_of_range_top
226 = static_cast<float>(std::numeric_limits<int>::max ()) + 1.;
227 if (x >= out_of_range_top)
229 else if (x < std::numeric_limits<int>::min ())
231 else
232 return static_cast<int> ((x > 0.0f) ? (x + 0.5f) : (x - 0.5f));
233 }
234
235 Complex
236 rc_acos (double x)
237 {
238 return fabs (x) > 1.0 ? acos (Complex (x)) : Complex (std::acos (x));
239 }
240
242 rc_acos (float x)
243 {
244 return fabsf (x) > 1.0f ? acos (FloatComplex (x))
246 }
247
248 Complex
249 rc_acosh (double x)
250 {
251 return x < 1.0 ? acosh (Complex (x)) : Complex (acosh (x));
252 }
253
255 rc_acosh (float x)
256 {
257 return x < 1.0f ? acosh (FloatComplex (x)) : FloatComplex (acosh (x));
258 }
259
260 Complex
261 rc_asin (double x)
262 {
263 return fabs (x) > 1.0 ? asin (Complex (x)) : Complex (std::asin (x));
264 }
265
267 rc_asin (float x)
268 {
269 return fabsf (x) > 1.0f ? asin (FloatComplex (x))
270 : FloatComplex (::asinf (x));
271 }
272
273 Complex
274 rc_atanh (double x)
275 {
276 return fabs (x) > 1.0 ? atanh (Complex (x)) : Complex (atanh (x));
277 }
278
280 rc_atanh (float x)
281 {
282 return fabsf (x) > 1.0f ? atanh (FloatComplex (x))
283 : FloatComplex (atanh (x));
284 }
285
286 Complex
287 rc_log (double x)
288 {
289 return x < 0.0 ? Complex (std::log (-x), M_PI) : Complex (std::log (x));
290 }
291
293 rc_log (float x)
294 {
295 return x < 0.0f ? FloatComplex (std::log (-x), static_cast<float> (M_PI))
296 : FloatComplex (std::log (x));
297 }
298
299 Complex
300 rc_log2 (double x)
301 {
302 constexpr double PI_LN2 = 4.53236014182719380962; // = pi / log(2)
303 return x < 0.0 ? Complex (log2 (-x), PI_LN2) : Complex (log2 (x));
304 }
305
307 rc_log2 (float x)
308 {
309 constexpr float PI_LN2 = 4.53236014182719380962f; // = pi / log(2)
310 return x < 0.0f ? FloatComplex (log2 (-x), PI_LN2)
311 : FloatComplex (log2 (x));
312 }
313
314 Complex
315 rc_log10 (double x)
316 {
317 constexpr double PI_LN10 = 1.36437635384184134748; // = pi / log(10)
318 return x < 0.0 ? Complex (log10 (-x), PI_LN10) : Complex (log10 (x));
319 }
320
322 rc_log10 (float x)
323 {
324 constexpr float PI_LN10 = 1.36437635384184134748f; // = pi / log(10)
325 return x < 0.0f ? FloatComplex (log10 (-x), PI_LN10)
326 : FloatComplex (log10f (x));
327 }
328
329 Complex
330 rc_sqrt (double x)
331 {
332 return x < 0.0 ? Complex (0.0, std::sqrt (-x)) : Complex (std::sqrt (x));
333 }
334
336 rc_sqrt (float x)
337 {
338 return x < 0.0f ? FloatComplex (0.0f, std::sqrt (-x))
339 : FloatComplex (std::sqrt (x));
340 }
341 }
342}
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:82
int __lo_ieee_float_signbit(float x)
Definition: lo-ieee.h:94
#define lo_ieee_is_NA(x)
Definition: lo-ieee.h:112
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:236
double atanh(double x)
Definition: lo-specfun.h:63
int nint(double x)
Definition: lo-mappers.cc:212
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:300
Complex rc_log(double x)
Definition: lo-mappers.cc:287
double acosh(double x)
Definition: lo-specfun.h:40
Complex rc_sqrt(double x)
Definition: lo-mappers.cc:330
Complex rc_atanh(double x)
Definition: lo-mappers.cc:274
bool negative_sign(double x)
Definition: lo-mappers.cc:178
Complex rc_acosh(double x)
Definition: lo-mappers.cc:249
FloatComplex acos(const FloatComplex &x)
Definition: lo-mappers.cc:96
Complex rc_log10(double x)
Definition: lo-mappers.cc:315
Complex rc_asin(double x)
Definition: lo-mappers.cc:261
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