comparison liboctave/numeric/lo-specfun.cc @ 21231:5f318c8ec634

eliminate feature tests from lo-specfun.h * lo-specfun.h, lo-specfun.cc (xacosh, xasinh, xatanh, xerf, xerfc xexpm1, xlog1p, xcbrt): Rename to have 'x' prefix. Conditionally define in .cc file. Change all uses Move complex versions of acosh, asinh, and atanh functions here.
author John W. Eaton <jwe@octave.org>
date Tue, 09 Feb 2016 04:15:50 -0500
parents f7121e111991
children 40de9f8f23a6
comparison
equal deleted inserted replaced
21230:721539013db4 21231:5f318c8ec634
196 F77_FUNC (dpsifn, DPSIFN) (const double*, const octave_idx_type&, 196 F77_FUNC (dpsifn, DPSIFN) (const double*, const octave_idx_type&,
197 const octave_idx_type&, const octave_idx_type&, 197 const octave_idx_type&, const octave_idx_type&,
198 double*, octave_idx_type*, octave_idx_type*); 198 double*, octave_idx_type*, octave_idx_type*);
199 } 199 }
200 200
201 #if ! defined (HAVE_ACOSH)
202 double 201 double
203 acosh (double x) 202 xacosh (double x)
204 { 203 {
204 #if defined (HAVE_ACOSH)
205 return acosh (x);
206 #else
205 double retval; 207 double retval;
206 F77_XFCN (xdacosh, XDACOSH, (x, retval)); 208 F77_XFCN (xdacosh, XDACOSH, (x, retval));
207 return retval; 209 return retval;
208 }
209 #endif 210 #endif
210 211 }
211 #if ! defined (HAVE_ACOSHF) 212
212 float 213 float
213 acoshf (float x) 214 xacosh (float x)
214 { 215 {
216 #if defined (HAVE_ACOSHF)
217 return acoshf (x);
218 #else
215 float retval; 219 float retval;
216 F77_XFCN (xacosh, XACOSH, (x, retval)); 220 F77_XFCN (xacosh, XACOSH, (x, retval));
217 return retval; 221 return retval;
218 }
219 #endif 222 #endif
220 223 }
221 #if ! defined (HAVE_ASINH) 224
225 Complex
226 xacosh (const Complex& x)
227 {
228 return log (x + sqrt (x + 1.0) * sqrt (x - 1.0));
229 }
230
231 FloatComplex
232 xacosh (const FloatComplex& x)
233 {
234 return log (x + sqrt (x + 1.0f) * sqrt (x - 1.0f));
235 }
236
222 double 237 double
223 asinh (double x) 238 xasinh (double x)
224 { 239 {
240 #if defined (HAVE_ASINH)
241 return asinh (x);
242 #else
225 double retval; 243 double retval;
226 F77_XFCN (xdasinh, XDASINH, (x, retval)); 244 F77_XFCN (xdasinh, XDASINH, (x, retval));
227 return retval; 245 return retval;
228 }
229 #endif 246 #endif
230 247 }
231 #if ! defined (HAVE_ASINHF) 248
232 float 249 float
233 asinhf (float x) 250 xasinh (float x)
234 { 251 {
252 #if defined (HAVE_ASINHF)
253 return asinhf (x);
254 #else
235 float retval; 255 float retval;
236 F77_XFCN (xasinh, XASINH, (x, retval)); 256 F77_XFCN (xasinh, XASINH, (x, retval));
237 return retval; 257 return retval;
238 }
239 #endif 258 #endif
240 259 }
241 #if ! defined (HAVE_ATANH) 260
261 Complex
262 xasinh (const Complex& x)
263 {
264 return log (x + sqrt (x*x + 1.0));
265 }
266
267 FloatComplex
268 xasinh (const FloatComplex& x)
269 {
270 return log (x + sqrt (x*x + 1.0f));
271 }
272
242 double 273 double
243 atanh (double x) 274 xatanh (double x)
244 { 275 {
276 #if defined (HAVE_ATANH)
277 return atanh (x);
278 #else
245 double retval; 279 double retval;
246 F77_XFCN (xdatanh, XDATANH, (x, retval)); 280 F77_XFCN (xdatanh, XDATANH, (x, retval));
247 return retval; 281 return retval;
248 }
249 #endif 282 #endif
250 283 }
251 #if ! defined (HAVE_ATANHF) 284
252 float 285 float
253 atanhf (float x) 286 xatanh (float x)
254 { 287 {
288 #if defined (HAVE_ATANHF)
289 return atanhf (x);
290 #else
255 float retval; 291 float retval;
256 F77_XFCN (xatanh, XATANH, (x, retval)); 292 F77_XFCN (xatanh, XATANH, (x, retval));
257 return retval; 293 return retval;
258 }
259 #endif 294 #endif
260 295 }
261 #if ! defined (HAVE_ERF) 296
297 Complex
298 xatanh (const Complex& x)
299 {
300 return log ((1.0 + x) / (1.0 - x)) / 2.0;
301 }
302
303 FloatComplex
304 xatanh (const FloatComplex& x)
305 {
306 return log ((1.0f + x) / (1.0f - x)) / 2.0f;
307 }
308
262 double 309 double
263 erf (double x) 310 xerf (double x)
264 { 311 {
312 #if defined (HAVE_ERF)
313 return erf (x);
314 #else
265 double retval; 315 double retval;
266 F77_XFCN (xderf, XDERF, (x, retval)); 316 F77_XFCN (xderf, XDERF, (x, retval));
267 return retval; 317 return retval;
268 }
269 #endif 318 #endif
270 319 }
271 #if ! defined (HAVE_ERFF) 320
272 float 321 float
273 erff (float x) 322 xerf (float x)
274 { 323 {
324 #if defined (HAVE_ERFF)
325 return erff (x);
326 #else
275 float retval; 327 float retval;
276 F77_XFCN (xerf, XERF, (x, retval)); 328 F77_XFCN (xerf, XERF, (x, retval));
277 return retval; 329 return retval;
278 }
279 #endif 330 #endif
280 331 }
281 #if ! defined (HAVE_ERFC)
282 double
283 erfc (double x)
284 {
285 double retval;
286 F77_XFCN (xderfc, XDERFC, (x, retval));
287 return retval;
288 }
289 #endif
290
291 #if ! defined (HAVE_ERFCF)
292 float
293 erfcf (float x)
294 {
295 float retval;
296 F77_XFCN (xerfc, XERFC, (x, retval));
297 return retval;
298 }
299 #endif
300 332
301 // Complex error function from the Faddeeva package 333 // Complex error function from the Faddeeva package
302 Complex 334 Complex
303 erf (const Complex& x) 335 xerf (const Complex& x)
304 { 336 {
305 return Faddeeva::erf (x); 337 return Faddeeva::erf (x);
306 } 338 }
339
307 FloatComplex 340 FloatComplex
308 erf (const FloatComplex& x) 341 xerf (const FloatComplex& x)
309 { 342 {
310 Complex xd (real (x), imag (x)); 343 Complex xd (real (x), imag (x));
311 Complex ret = Faddeeva::erf (xd, std::numeric_limits<float>::epsilon ()); 344 Complex ret = Faddeeva::erf (xd, std::numeric_limits<float>::epsilon ());
312 return FloatComplex (real (ret), imag (ret)); 345 return FloatComplex (real (ret), imag (ret));
313 } 346 }
314 347
348 double
349 xerfc (double x)
350 {
351 #if defined (HAVE_ERFC)
352 return erfc (x);
353 #else
354 double retval;
355 F77_XFCN (xderfc, XDERFC, (x, retval));
356 return retval;
357 #endif
358 }
359
360 float
361 xerfc (float x)
362 {
363 #if defined (HAVE_ERFCF)
364 return erfcf (x);
365 #else
366 float retval;
367 F77_XFCN (xerfc, XERFC, (x, retval));
368 return retval;
369 #endif
370 }
371
315 // Complex complementary error function from the Faddeeva package 372 // Complex complementary error function from the Faddeeva package
316 Complex 373 Complex
317 erfc (const Complex& x) 374 xerfc (const Complex& x)
318 { 375 {
319 return Faddeeva::erfc (x); 376 return Faddeeva::erfc (x);
320 } 377 }
378
321 FloatComplex 379 FloatComplex
322 erfc (const FloatComplex& x) 380 xerfc (const FloatComplex& x)
323 { 381 {
324 Complex xd (real (x), imag (x)); 382 Complex xd (real (x), imag (x));
325 Complex ret = Faddeeva::erfc (xd, std::numeric_limits<float>::epsilon ()); 383 Complex ret = Faddeeva::erfc (xd, std::numeric_limits<float>::epsilon ());
326 return FloatComplex (real (ret), imag (ret)); 384 return FloatComplex (real (ret), imag (ret));
327 } 385 }
516 return result + FloatComplex (0., M_PI); 574 return result + FloatComplex (0., M_PI);
517 else 575 else
518 return result; 576 return result;
519 } 577 }
520 578
521 #if ! defined (HAVE_EXPM1)
522 double 579 double
523 expm1 (double x) 580 xexpm1 (double x)
524 { 581 {
582 #if defined (HAVE_EXPM1)
583 return expm1 (x);
584 #else
525 double retval; 585 double retval;
526 586
527 double ax = fabs (x); 587 double ax = fabs (x);
528 588
529 if (ax < 0.1) 589 if (ax < 0.1)
549 } 609 }
550 else 610 else
551 retval = exp (x) - 1; 611 retval = exp (x) - 1;
552 612
553 return retval; 613 return retval;
554 }
555 #endif 614 #endif
615 }
556 616
557 Complex 617 Complex
558 expm1 (const Complex& x) 618 xexpm1 (const Complex& x)
559 { 619 {
560 Complex retval; 620 Complex retval;
561 621
562 if (std:: abs (x) < 1) 622 if (std:: abs (x) < 1)
563 { 623 {
564 double im = x.imag (); 624 double im = x.imag ();
565 double u = expm1 (x.real ()); 625 double u = xexpm1 (x.real ());
566 double v = sin (im/2); 626 double v = sin (im/2);
567 v = -2*v*v; 627 v = -2*v*v;
568 retval = Complex (u*v + u + v, (u+1) * sin (im)); 628 retval = Complex (u*v + u + v, (u+1) * sin (im));
569 } 629 }
570 else 630 else
571 retval = std::exp (x) - Complex (1); 631 retval = std::exp (x) - Complex (1);
572 632
573 return retval; 633 return retval;
574 } 634 }
575 635
576 #if ! defined (HAVE_EXPM1F)
577 float 636 float
578 expm1f (float x) 637 xexpm1 (float x)
579 { 638 {
639 #if defined (HAVE_EXPM1F)
640 return expm1f (x);
641 #else
580 float retval; 642 float retval;
581 643
582 float ax = fabs (x); 644 float ax = fabs (x);
583 645
584 if (ax < 0.1) 646 if (ax < 0.1)
604 } 666 }
605 else 667 else
606 retval = exp (x) - 1; 668 retval = exp (x) - 1;
607 669
608 return retval; 670 return retval;
609 }
610 #endif 671 #endif
672 }
611 673
612 FloatComplex 674 FloatComplex
613 expm1 (const FloatComplex& x) 675 xexpm1 (const FloatComplex& x)
614 { 676 {
615 FloatComplex retval; 677 FloatComplex retval;
616 678
617 if (std:: abs (x) < 1) 679 if (std:: abs (x) < 1)
618 { 680 {
619 float im = x.imag (); 681 float im = x.imag ();
620 float u = expm1 (x.real ()); 682 float u = xexpm1 (x.real ());
621 float v = sin (im/2); 683 float v = sin (im/2);
622 v = -2*v*v; 684 v = -2*v*v;
623 retval = FloatComplex (u*v + u + v, (u+1) * sin (im)); 685 retval = FloatComplex (u*v + u + v, (u+1) * sin (im));
624 } 686 }
625 else 687 else
626 retval = std::exp (x) - FloatComplex (1); 688 retval = std::exp (x) - FloatComplex (1);
627 689
628 return retval; 690 return retval;
629 } 691 }
630 692
631 #if ! defined (HAVE_LOG1P)
632 double 693 double
633 log1p (double x) 694 xlog1p (double x)
634 { 695 {
696 #if defined (HAVE_LOG1P)
697 return log1p (x);
698 #else
635 double retval; 699 double retval;
636 700
637 double ax = fabs (x); 701 double ax = fabs (x);
638 702
639 if (ax < 0.2) 703 if (ax < 0.2)
647 } 711 }
648 else 712 else
649 retval = gnulib::log (1 + x); 713 retval = gnulib::log (1 + x);
650 714
651 return retval; 715 return retval;
652 }
653 #endif 716 #endif
717 }
654 718
655 Complex 719 Complex
656 log1p (const Complex& x) 720 xlog1p (const Complex& x)
657 { 721 {
658 Complex retval; 722 Complex retval;
659 723
660 double r = x.real (), i = x.imag (); 724 double r = x.real (), i = x.imag ();
661 725
662 if (fabs (r) < 0.5 && fabs (i) < 0.5) 726 if (fabs (r) < 0.5 && fabs (i) < 0.5)
663 { 727 {
664 double u = 2*r + r*r + i*i; 728 double u = 2*r + r*r + i*i;
665 retval = Complex (log1p (u / (1+sqrt (u+1))), 729 retval = Complex (xlog1p (u / (1+sqrt (u+1))),
666 atan2 (1 + r, i)); 730 atan2 (1 + r, i));
667 } 731 }
668 else 732 else
669 retval = std::log (Complex (1) + x); 733 retval = std::log (Complex (1) + x);
670 734
671 return retval; 735 return retval;
672 } 736 }
673 737
674 #if ! defined (HAVE_CBRT) 738 template <typename T>
675 double cbrt (double x) 739 T
676 { 740 xxcbrt (T x)
677 static const double one_third = 0.3333333333333333333; 741 {
742 static const T one_third = 0.3333333333333333333f;
678 if (xfinite (x)) 743 if (xfinite (x))
679 { 744 {
680 // Use pow. 745 // Use pow.
681 double y = std::pow (std::abs (x), one_third) * signum (x); 746 T y = std::pow (std::abs (x), one_third) * signum (x);
682 // Correct for better accuracy. 747 // Correct for better accuracy.
683 return (x / (y*y) + y + y) / 3; 748 return (x / (y*y) + y + y) / 3;
684 } 749 }
685 else 750 else
686 return x; 751 return x;
687 } 752 }
753
754 double
755 xcbrt (double x)
756 {
757 #if defined (HAVE_CBRT)
758 return cbrt (x);
759 #else
760 return xxcbrt (x);
688 #endif 761 #endif
689 762 }
690 #if ! defined (HAVE_LOG1PF) 763
691 float 764 float
692 log1pf (float x) 765 xlog1p (float x)
693 { 766 {
767 #if defined (HAVE_LOG1PF)
768 return log1pf (x);
769 #else
694 float retval; 770 float retval;
695 771
696 float ax = fabs (x); 772 float ax = fabs (x);
697 773
698 if (ax < 0.2) 774 if (ax < 0.2)
706 } 782 }
707 else 783 else
708 retval = gnulib::logf (1.0f + x); 784 retval = gnulib::logf (1.0f + x);
709 785
710 return retval; 786 return retval;
711 }
712 #endif 787 #endif
788 }
713 789
714 FloatComplex 790 FloatComplex
715 log1p (const FloatComplex& x) 791 xlog1p (const FloatComplex& x)
716 { 792 {
717 FloatComplex retval; 793 FloatComplex retval;
718 794
719 float r = x.real (), i = x.imag (); 795 float r = x.real (), i = x.imag ();
720 796
721 if (fabs (r) < 0.5 && fabs (i) < 0.5) 797 if (fabs (r) < 0.5 && fabs (i) < 0.5)
722 { 798 {
723 float u = 2*r + r*r + i*i; 799 float u = 2*r + r*r + i*i;
724 retval = FloatComplex (log1p (u / (1+sqrt (u+1))), 800 retval = FloatComplex (xlog1p (u / (1+sqrt (u+1))),
725 atan2 (1 + r, i)); 801 atan2 (1 + r, i));
726 } 802 }
727 else 803 else
728 retval = std::log (FloatComplex (1) + x); 804 retval = std::log (FloatComplex (1) + x);
729 805
730 return retval; 806 return retval;
731 } 807 }
732 808
733 #if ! defined (HAVE_CBRTF) 809 float
734 float cbrtf (float x) 810 xcbrt (float x)
735 { 811 {
736 static const float one_third = 0.3333333333333333333f; 812 #if defined (HAVE_CBRTF)
737 if (xfinite (x)) 813 return cbrtf (x);
738 { 814 #else
739 // Use pow. 815 return xxcbrt (x);
740 float y = std::pow (std::abs (x), one_third) * signum (x);
741 // Correct for better accuracy.
742 return (x / (y*y) + y + y) / 3;
743 }
744 else
745 return x;
746 }
747 #endif 816 #endif
817 }
748 818
749 static inline Complex 819 static inline Complex
750 zbesj (const Complex& z, double alpha, int kode, octave_idx_type& ierr); 820 zbesj (const Complex& z, double alpha, int kode, octave_idx_type& ierr);
751 821
752 static inline Complex 822 static inline Complex
2890 Complex rc_log1p (double x) 2960 Complex rc_log1p (double x)
2891 { 2961 {
2892 const double pi = 3.14159265358979323846; 2962 const double pi = 3.14159265358979323846;
2893 return (x < -1.0 2963 return (x < -1.0
2894 ? Complex (gnulib::log (-(1.0 + x)), pi) 2964 ? Complex (gnulib::log (-(1.0 + x)), pi)
2895 : Complex (log1p (x))); 2965 : Complex (xlog1p (x)));
2896 } 2966 }
2897 2967
2898 FloatComplex rc_log1p (float x) 2968 FloatComplex rc_log1p (float x)
2899 { 2969 {
2900 const float pi = 3.14159265358979323846f; 2970 const float pi = 3.14159265358979323846f;
2901 return (x < -1.0f 2971 return (x < -1.0f
2902 ? FloatComplex (gnulib::logf (-(1.0f + x)), pi) 2972 ? FloatComplex (gnulib::logf (-(1.0f + x)), pi)
2903 : FloatComplex (log1pf (x))); 2973 : FloatComplex (xlog1p (x)));
2904 } 2974 }
2905 2975
2906 // This algorithm is due to P. J. Acklam. 2976 // This algorithm is due to P. J. Acklam.
2907 // 2977 //
2908 // See http://home.online.no/~pjacklam/notes/invnorm/ 2978 // See http://home.online.no/~pjacklam/notes/invnorm/