home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / programm / 2052 < prev    next >
Encoding:
Text File  |  1992-07-22  |  7.7 KB  |  180 lines

  1. Newsgroups: comp.programming
  2. Path: sparky!uunet!zaphod.mps.ohio-state.edu!wupost!gumby!yale!yale.edu!ira.uka.de!rz.uni-karlsruhe.de!stepsun.uni-kl.de!uklirb!posthorn!vier!neuhaus
  3. From: neuhaus@vier.informatik.uni-kl.de (Stephan Neuhaus (HiWi Mattern))
  4. Subject: Re: Calculating a cube root
  5. Message-ID: <neuhaus.711800570@vier>
  6. Sender: news@posthorn.informatik.uni-kl.de (News system account)
  7. Nntp-Posting-Host: vier.informatik.uni-kl.de
  8. Organization: University of Kaiserslautern, Germany
  9. References: <l624kmINN29e@girtab.usc.edu> <129360001@hpfcso.FC.HP.COM> <1992Jul20.123722.27958@cs.ruu.nl> <1992Jul20.160255.17562@organpipe.uug.arizona.edu>
  10. Date: Wed, 22 Jul 1992 10:22:50 GMT
  11. Lines: 167
  12.  
  13. dave@cs.arizona.edu (Dave Schaumann) writes:
  14.  
  15. >In article <1992Jul20.123722.27958@cs.ruu.nl>, jeroen@cs (Jeroen Fokker) writes:
  16. >>
  17. >>joseph@girtab.usc.edu (Randi Joseph) asked:
  18. >>
  19. >>> Can anyone present an example routine in C 
  20. >>> to calculate a cube root of a number?  Thanks!
  21. >>
  22. >>fwb@hpfcso.FC.HP.COM (Frank Bennett) replied:
  23. >>
  24. >>> y = exp(log(x)/3.0 );
  25. >>> you didn't say it had to be fast!
  26. >>
  27. >>A faster function uses Newton's method, using iteration:
  28.  
  29. >I don't think so, at least for most values.  Library routines like exp(),
  30. >log(), and pow() are generally defined using a polynomial expansion, which
  31. >require perhaps 5 floating point multiplies, and yield a reasonably accurate
  32. >answer.
  33.  
  34. This is precisely the problem with this solution.  It is
  35. possible---and quite cheaply at that---to make the answer correct to
  36. maybe two ulps using Newton's method.  Depending on the magnitude of
  37. x, this may not be the case for the exp (log (x)/3.0) method, for if
  38. you look at the relative error, you will see that it is less than
  39.  
  40.     x^{(2/3)\epsilon} - 1 + \epsilon x^{(2/3)\epsilon}
  41.  
  42. (Send email if you want the details.)  \epsilon here is the machine
  43. precision, which is usually defined to be half an ulp.  For IEEE
  44. single precision, this is about 1e-8, for double it is 1e-16,
  45. approximately.  Since the second \epsilon term is smaller than the
  46. first by a factor of 1e8, we can discard it and look at the remaining
  47. terms.
  48.  
  49. This function of x behaves like a polynomial, and is always greater
  50. than or equal to -1.  Moreover, it is strictly increasing, and will
  51. surpass every threshold sooner or later.  Let's look at the threshold
  52. for x where the relative error becomes larger than two ulps (=
  53. 4\epsilon).
  54.  
  55.     x^{(2/3)\epsilon} - 1 >= 4\epsilon
  56. <==>    x^{(2/3)\epsilon} >= 1 + 4\epsilon
  57. <==>    x >= (1 + 4\epsilon)^{3/(2\epsilon)}    (since x, \epsilon > 0)
  58.  
  59. For \epsilon = 1e-8, we get x >= 404, and for \epsilon = 1e-16, we get
  60. x >= 782.  Therefore, large arguments tend to make the exp (log
  61. (x)/3.0) solution more inaccurate than need be.
  62.  
  63. >Looking at your answer, we see
  64.  
  65. >>    #define EPSILON 0.00001
  66.  
  67. >which of course limits the accuracy quite severly.  Of course, one could
  68. >write the algorithm so that it terminates when the value stops converging.
  69.  
  70. No.  That is not possible.  A theorem of Numerical Analysis states
  71. that if you implement a theoretically at least linearly convergent
  72. series on a machine, then either the limit is exactly a machine
  73. number, in which case the process will halt, or it isn't, in which
  74. case there exists a region of indeterminacy around the limit in which
  75. your values will get stuck.  Your sequence will become periodic.  The
  76. precise a-priori formula is (in TeX notation)
  77.  
  78. |\hat{x}_n - x| < \Delta/(1-q) + {q^n \over 1-q}|\hat{x}_1 - \hat{x}_0|
  79.  
  80. Where \Delta is the worst-case error that you make when you calculate
  81. the next iterate from the most recent, q is the constant of
  82. convergence, x is the exact limit, and \hat{x}_k are the iterates.  As
  83. you can see, the formula does not tell the whole story, since it only
  84. says something about the maximum error, but then, the maximum error
  85. will not drop below \Delta/(1-q), plus I can give you the complete
  86. theorem with proof if you want.
  87.  
  88. >But this still leaves the problem of speed.  A quick check shows that your
  89. >algorithm iterates as much as 15 times for values less than 1000. Clearly,
  90. >unless you have a /very/ inefficient exp() and log(), using them will be a
  91. >speed win as well.
  92.  
  93. Typical exp and log routines will spend some time looking at the
  94. argument and performing argument reduction.  The inner loops in a
  95. Newton step can be heavily optimized by a good compiler.  Furthermore,
  96. a good initial guess for the cube root will cut down the number of
  97. iterations enormously.
  98.  
  99. >There's also another advantage to using library routines.  Presumably, someone
  100. >was paid to make sure they are correct.
  101.  
  102. Yes, but only to so many ulps.  There is (IMHO) no excuse for making a
  103. numerical routine less stable and accurate than need be.  The Newton
  104. solution wins over the exp/log solution for x > 1000, approximately.
  105.  
  106. >>        return( a-b<EPSILON && b-a<EPSILON );
  107. >                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
  108.  
  109. >This expression will always yield 0.
  110.  
  111. As some follow-uppers have already remarked, this is not true.  Worse
  112. still is the fact that no one seems to have recognized the danger of
  113. using the absolute error instead of the relative error.  Using the
  114. absolute error means that you claim that x^{1/3} behaves everywhere
  115. like the constant 1.  It's far better to root out the case x = 0 first
  116. and then use
  117.  
  118.     fabs (a - b) < EPSILON*min (a, b)
  119.  
  120. I use min here to get a worst-case bound on the relative error.  Of
  121. course, you will have to make sure that a and b are both positive, but
  122. this is not a problem, since Newton converges monotonically (I think).
  123.  
  124. For huge machine values of a and b, the absolute error cannot be less
  125. than EPSILON, unless a and b are exactly equal.  For very small values
  126. of a and b, the criterion may be satisfied immediately, even though
  127. your values might not even be close to the cube root of x.
  128.  
  129. Another approach that has been used in other routines, e.g., square
  130. root, is the following:  Write x as
  131.  
  132.     x = 2^e * f    1.0 <= f < 2.0
  133.  
  134. Then,
  135.  
  136.     x^{1/3} = 2^{e/3} * f^{1/3}.
  137.  
  138. Algorithm:
  139.  
  140.     1. Write e as 3*e' + e''    (0 <= e'' < 3)
  141.     2. Compute f' = 2^{e''} * f    (1.0 <= f' < 8.0)
  142.     3. Calculate r = f'^{1/3} by Newton's method (however, see below)
  143.     4. Set result = 2^{e'} * r
  144.  
  145. To get an initial guess for f', it usually pays to approximate the
  146. function x^{1/3} over [1,8) by a polynomial of degree 3 (say) with an
  147. approximately equal-ripple error curve.  This requires some modest
  148. amount of work but will in general provide you with excellent initial
  149. guesses.  For example, a 3rd degree polynomial for sqrt(x) over [1,2)
  150. will give you three to four correct decimals, making only three Newton
  151. steps necessary for 24 decimals (more than IEEE double has).
  152.  
  153. Careful argument reduction pays both in terms of speed (because you
  154. can do an a-priori error analysis to find out how many Newton steps
  155. you need) and accuracy (because of the fixed, rather small interval).
  156.  
  157. Everyone who is interested in these topics should read:
  158.  
  159.     F.S. Acton: _Numerical Methods that (Usually) Work_, Harper &
  160.         Row, 1990 (?)
  161.  
  162.     P.J. Plauger: _The Standard C Library_, Prentice-Hall, 1992
  163.  
  164.     W. Cody and W. Waite: _Software Manual for the Elementary
  165.         Functions_, (Publisher unknown, I can look it up.  You
  166.         can find the reference in Plauger's book, too.)
  167.  
  168. Sorry this took so long.
  169.  
  170. -- 
  171. +------- No .sig? OH, COME ON! --------+-"The derivative snuggles  close to-+
  172. | email:  neuhaus@informatik.uni-kl.de | the function---whatever to snuggle |
  173. | snail mail: Stephan Neuhaus/Hilgard- | means; I'm too old for that"       |
  174. | ring 32/6750 Kaiserslautern/Germany  |                       -- Math Prof |
  175. -- 
  176. +------- No .sig? OH, COME ON! --------+-"The derivative snuggles  close to-+
  177. | email:  neuhaus@informatik.uni-kl.de | the function---whatever to snuggle |
  178. | snail mail: Stephan Neuhaus/Hilgard- | means; I'm too old for that"       |
  179. | ring 32/6750 Kaiserslautern/Germany  |                       -- Math Prof |
  180.