z_log.c
Go to the documentation of this file.
00001 #include "f2c.h"
00002 
00003 #ifdef KR_headers
00004 double log(), f__cabs(), atan2();
00005 #define ANSI(x) ()
00006 #else
00007 #define ANSI(x) x
00008 #undef abs
00009 #include "math.h"
00010 #ifdef __cplusplus
00011 extern "C" {
00012 #endif
00013 extern double f__cabs(double, double);
00014 #endif
00015 
00016 #ifndef NO_DOUBLE_EXTENDED
00017 #ifndef GCC_COMPARE_BUG_FIXED
00018 #ifndef Pre20000310
00019 #ifdef Comment
00020 Some versions of gcc, such as 2.95.3 and 3.0.4, are buggy under -O2 or -O3:
00021 on IA32 (Intel 80x87) systems, they may do comparisons on values computed
00022 in extended-precision registers.  This can lead to the test "s > s0" that
00023 was used below being carried out incorrectly.  The fix below cannot be
00024 spoiled by overzealous optimization, since the compiler cannot know
00025 whether gcc_bug_bypass_diff_F2C will be nonzero.  (We expect it always
00026 to be zero.  The weird name is unlikely to collide with anything.)
00027 
00028 An example (provided by Ulrich Jakobus) where the bug fix matters is
00029 
00030         double complex a, b
00031         a = (.1099557428756427618354862829619, .9857360542953131909982289471372)
00032         b = log(a)
00033 
00034 An alternative to the fix below would be to use 53-bit rounding precision,
00035 but the means of specifying this 80x87 feature are highly unportable.
00036 #endif /*Comment*/
00037 #define BYPASS_GCC_COMPARE_BUG
00038 double (*gcc_bug_bypass_diff_F2C) ANSI((double*,double*));
00039  static double
00040 #ifdef KR_headers
00041 diff1(a,b) double *a, *b;
00042 #else
00043 diff1(double *a, double *b)
00044 #endif
00045 { return *a - *b; }
00046 #endif /*Pre20000310*/
00047 #endif /*GCC_COMPARE_BUG_FIXED*/
00048 #endif /*NO_DOUBLE_EXTENDED*/
00049 
00050 #ifdef KR_headers
00051 VOID z_log(r, z) doublecomplex *r, *z;
00052 #else
00053 void z_log(doublecomplex *r, doublecomplex *z)
00054 #endif
00055 {
00056         double s, s0, t, t2, u, v;
00057         double zi = z->i, zr = z->r;
00058 #ifdef BYPASS_GCC_COMPARE_BUG
00059         double (*diff) ANSI((double*,double*));
00060 #endif
00061 
00062         r->i = atan2(zi, zr);
00063 #ifdef Pre20000310
00064         r->r = log( f__cabs( zr, zi ) );
00065 #else
00066         if (zi < 0)
00067                 zi = -zi;
00068         if (zr < 0)
00069                 zr = -zr;
00070         if (zr < zi) {
00071                 t = zi;
00072                 zi = zr;
00073                 zr = t;
00074                 }
00075         t = zi/zr;
00076         s = zr * sqrt(1 + t*t);
00077         /* now s = f__cabs(zi,zr), and zr = |zr| >= |zi| = zi */
00078         if ((t = s - 1) < 0)
00079                 t = -t;
00080         if (t > .01)
00081                 r->r = log(s);
00082         else {
00083 
00084 #ifdef Comment
00085 
00086         log(1+x) = x - x^2/2 + x^3/3 - x^4/4 + - ...
00087 
00088                  = x(1 - x/2 + x^2/3 -+...)
00089 
00090         [sqrt(y^2 + z^2) - 1] * [sqrt(y^2 + z^2) + 1] = y^2 + z^2 - 1, so
00091 
00092         sqrt(y^2 + z^2) - 1 = (y^2 + z^2 - 1) / [sqrt(y^2 + z^2) + 1]
00093 
00094 #endif /*Comment*/
00095 
00096 #ifdef BYPASS_GCC_COMPARE_BUG
00097                 if (!(diff = gcc_bug_bypass_diff_F2C))
00098                         diff = diff1;
00099 #endif
00100                 t = ((zr*zr - 1.) + zi*zi) / (s + 1);
00101                 t2 = t*t;
00102                 s = 1. - 0.5*t;
00103                 u = v = 1;
00104                 do {
00105                         s0 = s;
00106                         u *= t2;
00107                         v += 2;
00108                         s += u/v - t*u/(v+1);
00109                         }
00110 #ifdef BYPASS_GCC_COMPARE_BUG
00111                         while(s - s0 > 1e-18 || (*diff)(&s,&s0) > 0.);
00112 #else
00113                         while(s > s0);
00114 #endif
00115                 r->r = s*t;
00116                 }
00117 #endif
00118         }
00119 #ifdef __cplusplus
00120 }
00121 #endif


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:16