GNU Octave  8.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-2023 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 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))
245  : FloatComplex (std::acos (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 
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:82
int __lo_ieee_float_signbit(float x)
Definition: lo-ieee.h:94
#define lo_ieee_is_NA(x)
Definition: lo-ieee.h:112
bool is_NaN_or_NA(const Complex &x)
Definition: lo-mappers.cc:71
Complex log2(const Complex &x)
Definition: lo-mappers.cc:139
Complex rc_acosh(double x)
Definition: lo-mappers.cc:249
Complex rc_atanh(double x)
Definition: lo-mappers.cc:274
Complex rc_log(double x)
Definition: lo-mappers.cc:287
Complex asin(const Complex &x)
Definition: lo-mappers.cc:107
octave_idx_type nint_big(double x)
Definition: lo-mappers.cc:184
int nint(double x)
Definition: lo-mappers.cc:212
Complex rc_asin(double x)
Definition: lo-mappers.cc:261
bool negative_sign(double x)
Definition: lo-mappers.cc:178
bool isna(double x)
Definition: lo-mappers.cc:47
Complex rc_acos(double x)
Definition: lo-mappers.cc:236
Complex rc_sqrt(double x)
Definition: lo-mappers.cc:330
Complex rc_log10(double x)
Definition: lo-mappers.cc:315
Complex acos(const Complex &x)
Definition: lo-mappers.cc:85
Complex rc_log2(double x)
Definition: lo-mappers.cc:300
double frexp(double x, int *expptr)
Definition: lo-mappers.cc:128
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
static T abs(T x)
Definition: pr-output.cc:1678