Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <cfloat>
00029
00030 #include "lo-error.h"
00031 #include "lo-ieee.h"
00032 #include "lo-mappers.h"
00033 #include "lo-math.h"
00034 #include "lo-specfun.h"
00035 #include "lo-utils.h"
00036 #include "oct-cmplx.h"
00037
00038 #include "f77-fcn.h"
00039
00040
00041
00042
00043
00044
00045 double
00046 xtrunc (double x)
00047 {
00048 return gnulib::trunc (x);
00049 }
00050
00051 double
00052 xcopysign (double x, double y)
00053 {
00054 return gnulib::copysign (x, y);
00055 }
00056
00057 double xfloor (double x)
00058 {
00059 return gnulib::floor (x);
00060 }
00061
00062 double
00063 xround (double x)
00064 {
00065 return gnulib::round (x);
00066 }
00067
00068 double
00069 xroundb (double x)
00070 {
00071 double t = xround (x);
00072
00073 if (fabs (x - t) == 0.5)
00074 t = 2 * xtrunc (0.5 * t);
00075
00076 return t;
00077 }
00078
00079 double
00080 signum (double x)
00081 {
00082 double tmp = 0.0;
00083
00084 if (x < 0.0)
00085 tmp = -1.0;
00086 else if (x > 0.0)
00087 tmp = 1.0;
00088
00089 return xisnan (x) ? octave_NaN : tmp;
00090 }
00091
00092 double
00093 xlog2 (double x)
00094 {
00095 #if defined (HAVE_LOG2)
00096 return log2 (x);
00097 #else
00098 #if defined (M_LN2)
00099 static double ln2 = M_LN2;
00100 #else
00101 static double ln2 = log (2);
00102 #endif
00103
00104 return log (x) / ln2;
00105 #endif
00106 }
00107
00108 Complex
00109 xlog2 (const Complex& x)
00110 {
00111 #if defined (M_LN2)
00112 static double ln2 = M_LN2;
00113 #else
00114 static double ln2 = log (2);
00115 #endif
00116
00117 return std::log (x) / ln2;
00118 }
00119
00120 double
00121 xexp2 (double x)
00122 {
00123 #if defined (HAVE_EXP2)
00124 return exp2 (x);
00125 #else
00126 #if defined (M_LN2)
00127 static double ln2 = M_LN2;
00128 #else
00129 static double ln2 = log (2);
00130 #endif
00131
00132 return exp (x * ln2);
00133 #endif
00134 }
00135
00136 double
00137 xlog2 (double x, int& exp)
00138 {
00139 return frexp (x, &exp);
00140 }
00141
00142 Complex
00143 xlog2 (const Complex& x, int& exp)
00144 {
00145 double ax = std::abs (x);
00146 double lax = xlog2 (ax, exp);
00147 return (ax != lax) ? (x / ax) * lax : x;
00148 }
00149
00150
00151
00152 #if ! defined(HAVE_CMATH_ISNAN)
00153 bool
00154 xisnan (double x)
00155 {
00156 return lo_ieee_isnan (x);
00157 }
00158 #endif
00159
00160 #if ! defined(HAVE_CMATH_ISFINITE)
00161 bool
00162 xfinite (double x)
00163 {
00164 return lo_ieee_finite (x);
00165 }
00166 #endif
00167
00168 #if ! defined(HAVE_CMATH_ISINF)
00169 bool
00170 xisinf (double x)
00171 {
00172 return lo_ieee_isinf (x);
00173 }
00174 #endif
00175
00176 bool
00177 octave_is_NA (double x)
00178 {
00179 return lo_ieee_is_NA (x);
00180 }
00181
00182 bool
00183 octave_is_NaN_or_NA (double x)
00184 {
00185 return lo_ieee_isnan (x);
00186 }
00187
00188
00189
00190
00191
00192 Complex
00193 acos (const Complex& x)
00194 {
00195 static Complex i (0, 1);
00196
00197 return -i * (log (x + i * (sqrt (1.0 - x*x))));
00198 }
00199
00200 Complex
00201 acosh (const Complex& x)
00202 {
00203 return log (x + sqrt (x*x - 1.0));
00204 }
00205
00206 Complex
00207 asin (const Complex& x)
00208 {
00209 static Complex i (0, 1);
00210
00211 return -i * log (i*x + sqrt (1.0 - x*x));
00212 }
00213
00214 Complex
00215 asinh (const Complex& x)
00216 {
00217 return log (x + sqrt (x*x + 1.0));
00218 }
00219
00220 Complex
00221 atan (const Complex& x)
00222 {
00223 static Complex i (0, 1);
00224
00225 return i * log ((i + x) / (i - x)) / 2.0;
00226 }
00227
00228 Complex
00229 atanh (const Complex& x)
00230 {
00231 return log ((1.0 + x) / (1.0 - x)) / 2.0;
00232 }
00233
00234
00235
00236 bool
00237 octave_is_NA (const Complex& x)
00238 {
00239 return (octave_is_NA (real (x)) || octave_is_NA (imag (x)));
00240 }
00241
00242 bool
00243 octave_is_NaN_or_NA (const Complex& x)
00244 {
00245 return (xisnan (real (x)) || xisnan (imag (x)));
00246 }
00247
00248
00249
00250
00251
00252 Complex
00253 xmin (const Complex& x, const Complex& y)
00254 {
00255 return abs (x) <= abs (y) ? x : (xisnan (x) ? x : y);
00256 }
00257
00258 Complex
00259 xmax (const Complex& x, const Complex& y)
00260 {
00261 return abs (x) >= abs (y) ? x : (xisnan (x) ? x : y);
00262 }
00263
00264
00265
00266
00267
00268
00269
00270 float
00271 xtrunc (float x)
00272 {
00273 return gnulib::truncf (x);
00274 }
00275
00276 float
00277 xcopysign (float x, float y)
00278 {
00279 return gnulib::copysignf (x, y);
00280 }
00281
00282 float
00283 xround (float x)
00284 {
00285 return gnulib::round (x);
00286 }
00287
00288 float
00289 xroundb (float x)
00290 {
00291 float t = xround (x);
00292
00293 if (fabsf (x - t) == 0.5)
00294 t = 2 * xtrunc (0.5 * t);
00295
00296 return t;
00297 }
00298
00299 float
00300 signum (float x)
00301 {
00302 float tmp = 0.0;
00303
00304 if (x < 0.0)
00305 tmp = -1.0;
00306 else if (x > 0.0)
00307 tmp = 1.0;
00308
00309 return xisnan (x) ? octave_Float_NaN : tmp;
00310 }
00311
00312 float
00313 xlog2 (float x)
00314 {
00315 #if defined (HAVE_LOG2)
00316 return log2 (x);
00317 #else
00318 #if defined (M_LN2)
00319 static float ln2 = M_LN2;
00320 #else
00321 static float ln2 = log2 (2);
00322 #endif
00323
00324 return log (x) / ln2;
00325 #endif
00326 }
00327
00328 FloatComplex
00329 xlog2 (const FloatComplex& x)
00330 {
00331 #if defined (M_LN2)
00332 static float ln2 = M_LN2;
00333 #else
00334 static float ln2 = log (2);
00335 #endif
00336
00337 return std::log (x) / ln2;
00338 }
00339
00340 float
00341 xexp2 (float x)
00342 {
00343 #if defined (HAVE_EXP2)
00344 return exp2 (x);
00345 #else
00346 #if defined (M_LN2)
00347 static float ln2 = M_LN2;
00348 #else
00349 static float ln2 = log2 (2);
00350 #endif
00351
00352 return exp (x * ln2);
00353 #endif
00354 }
00355
00356 float
00357 xlog2 (float x, int& exp)
00358 {
00359 return frexpf (x, &exp);
00360 }
00361
00362 FloatComplex
00363 xlog2 (const FloatComplex& x, int& exp)
00364 {
00365 float ax = std::abs (x);
00366 float lax = xlog2 (ax, exp);
00367 return (ax != lax) ? (x / ax) * lax : x;
00368 }
00369
00370
00371
00372 #if ! defined(HAVE_CMATH_ISNANF)
00373 bool
00374 xisnan (float x)
00375 {
00376 return lo_ieee_isnan (x);
00377 }
00378 #endif
00379
00380 #if ! defined(HAVE_CMATH_ISFINITEF)
00381 bool
00382 xfinite (float x)
00383 {
00384 return lo_ieee_finite (x);
00385 }
00386 #endif
00387
00388 #if ! defined(HAVE_CMATH_ISINFF)
00389 bool
00390 xisinf (float x)
00391 {
00392 return lo_ieee_isinf (x);
00393 }
00394 #endif
00395
00396 bool
00397 octave_is_NA (float x)
00398 {
00399 return lo_ieee_is_NA (x);
00400 }
00401
00402 bool
00403 octave_is_NaN_or_NA (float x)
00404 {
00405 return lo_ieee_isnan (x);
00406 }
00407
00408
00409
00410
00411
00412 FloatComplex
00413 acos (const FloatComplex& x)
00414 {
00415 static FloatComplex i (0, 1);
00416
00417 return -i * (log (x + i * (sqrt (static_cast<float>(1.0) - x*x))));
00418 }
00419
00420 FloatComplex
00421 acosh (const FloatComplex& x)
00422 {
00423 return log (x + sqrt (x*x - static_cast<float>(1.0)));
00424 }
00425
00426 FloatComplex
00427 asin (const FloatComplex& x)
00428 {
00429 static FloatComplex i (0, 1);
00430
00431 return -i * log (i*x + sqrt (static_cast<float>(1.0) - x*x));
00432 }
00433
00434 FloatComplex
00435 asinh (const FloatComplex& x)
00436 {
00437 return log (x + sqrt (x*x + static_cast<float>(1.0)));
00438 }
00439
00440 FloatComplex
00441 atan (const FloatComplex& x)
00442 {
00443 static FloatComplex i (0, 1);
00444
00445 return i * log ((i + x) / (i - x)) / static_cast<float>(2.0);
00446 }
00447
00448 FloatComplex
00449 atanh (const FloatComplex& x)
00450 {
00451 return log ((static_cast<float>(1.0) + x) / (static_cast<float>(1.0) - x)) / static_cast<float>(2.0);
00452 }
00453
00454
00455
00456 bool
00457 octave_is_NA (const FloatComplex& x)
00458 {
00459 return (octave_is_NA (real (x)) || octave_is_NA (imag (x)));
00460 }
00461
00462 bool
00463 octave_is_NaN_or_NA (const FloatComplex& x)
00464 {
00465 return (xisnan (real (x)) || xisnan (imag (x)));
00466 }
00467
00468
00469
00470
00471
00472 FloatComplex
00473 xmin (const FloatComplex& x, const FloatComplex& y)
00474 {
00475 return abs (x) <= abs (y) ? x : (xisnan (x) ? x : y);
00476 }
00477
00478 FloatComplex
00479 xmax (const FloatComplex& x, const FloatComplex& y)
00480 {
00481 return abs (x) >= abs (y) ? x : (xisnan (x) ? x : y);
00482 }
00483
00484 Complex
00485 rc_acos (double x)
00486 {
00487 return fabs (x) > 1.0 ? acos (Complex (x)) : Complex (acos (x));
00488 }
00489
00490 FloatComplex
00491 rc_acos (float x)
00492 {
00493 return fabsf (x) > 1.0f ? acos (FloatComplex (x)) : FloatComplex (acosf (x));
00494 }
00495
00496 Complex
00497 rc_acosh (double x)
00498 {
00499 return x < 1.0 ? acosh (Complex (x)) : Complex (acosh (x));
00500 }
00501
00502 FloatComplex
00503 rc_acosh (float x)
00504 {
00505 return x < 1.0f ? acosh (FloatComplex (x)) : FloatComplex (acoshf (x));
00506 }
00507
00508 Complex
00509 rc_asin (double x)
00510 {
00511 return fabs (x) > 1.0 ? asin (Complex (x)) : Complex (asin (x));
00512 }
00513
00514 FloatComplex
00515 rc_asin (float x)
00516 {
00517 return fabsf (x) > 1.0f ? asin (FloatComplex (x)) : FloatComplex (asinf (x));
00518 }
00519
00520 Complex
00521 rc_atanh (double x)
00522 {
00523 return fabs (x) > 1.0 ? atanh (Complex (x)) : Complex (atanh (x));
00524 }
00525
00526 FloatComplex
00527 rc_atanh (float x)
00528 {
00529 return fabsf (x) > 1.0f ? atanh (FloatComplex (x)) : FloatComplex (atanhf (x));
00530 }
00531
00532 Complex
00533 rc_log (double x)
00534 {
00535 const double pi = 3.14159265358979323846;
00536 return x < 0.0 ? Complex (log (-x), pi) : Complex (log (x));
00537 }
00538
00539 FloatComplex
00540 rc_log (float x)
00541 {
00542 const float pi = 3.14159265358979323846f;
00543 return x < 0.0f ? FloatComplex (logf (-x), pi) : FloatComplex (logf (x));
00544 }
00545
00546 Complex
00547 rc_log2 (double x)
00548 {
00549 const double pil2 = 4.53236014182719380962;
00550 return x < 0.0 ? Complex (xlog2 (-x), pil2) : Complex (xlog2 (x));
00551 }
00552
00553 FloatComplex
00554 rc_log2 (float x)
00555 {
00556 const float pil2 = 4.53236014182719380962f;
00557 return x < 0.0f ? FloatComplex (xlog2 (-x), pil2) : FloatComplex (xlog2 (x));
00558 }
00559
00560 Complex
00561 rc_log10 (double x)
00562 {
00563 const double pil10 = 1.36437635384184134748;
00564 return x < 0.0 ? Complex (log10 (-x), pil10) : Complex (log10 (x));
00565 }
00566
00567 FloatComplex
00568 rc_log10 (float x)
00569 {
00570 const float pil10 = 1.36437635384184134748f;
00571 return x < 0.0f ? FloatComplex (log10 (-x), pil10) : FloatComplex (log10f (x));
00572 }
00573
00574 Complex
00575 rc_sqrt (double x)
00576 {
00577 return x < 0.0 ? Complex (0.0, sqrt (-x)) : Complex (sqrt (x));
00578 }
00579
00580 FloatComplex
00581 rc_sqrt (float x)
00582 {
00583 return x < 0.0f ? FloatComplex (0.0f, sqrtf (-x)) : FloatComplex (sqrtf (x));
00584 }
00585
00586 bool
00587 xnegative_sign (double x)
00588 {
00589 return __lo_ieee_signbit (x);
00590 }
00591
00592 bool
00593 xnegative_sign (float x)
00594 {
00595 return __lo_ieee_float_signbit (x);
00596 }
00597
00598
00599
00600
00601
00602
00603 octave_idx_type
00604 NINTbig (double x)
00605 {
00606 if (x > std::numeric_limits<octave_idx_type>::max ())
00607 return std::numeric_limits<octave_idx_type>::max ();
00608 else if (x < std::numeric_limits<octave_idx_type>::min ())
00609 return std::numeric_limits<octave_idx_type>::min ();
00610 else
00611 return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5));
00612 }
00613
00614 octave_idx_type
00615 NINTbig (float x)
00616 {
00617 if (x > std::numeric_limits<octave_idx_type>::max ())
00618 return std::numeric_limits<octave_idx_type>::max ();
00619 else if (x < std::numeric_limits<octave_idx_type>::min ())
00620 return std::numeric_limits<octave_idx_type>::min ();
00621 else
00622 return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5));
00623 }
00624
00625 int
00626 NINT (double x)
00627 {
00628 if (x > std::numeric_limits<int>::max ())
00629 return std::numeric_limits<int>::max ();
00630 else if (x < std::numeric_limits<int>::min ())
00631 return std::numeric_limits<int>::min ();
00632 else
00633 return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
00634 }
00635
00636 int
00637 NINT (float x)
00638 {
00639 if (x > std::numeric_limits<int>::max ())
00640 return std::numeric_limits<int>::max ();
00641 else if (x < std::numeric_limits<int>::min ())
00642 return std::numeric_limits<int>::min ();
00643 else
00644 return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
00645 }