cpow(3) implementations.

Peter Jeremy peter at rulingia.com
Wed Aug 8 09:24:58 UTC 2012


On 2012-Aug-07 18:34:59 -0700, Steve Kargl <sgk at troutmask.apl.washington.edu> wrote:
>On Wed, Aug 08, 2012 at 10:03:57AM +1000, Peter Jeremy wrote:
>>   cpow(z, w) = exp(a*u - b*v) * cis(a*v + b*u)
...
>>   exp(a*u - b*v) = exp(a*u) / exp(b*v)
>>                  = pow(a, hypot(c, d)) / exp(b*v)

Oops, that last line is wrong and should be:
   exp(a*u - b*v) = pow(hypot(c, d), a) / exp(b*v)

>I cheated and peaked at NetBSD's implementation, which is
>based on Moshier's cephes implementation.

The pseudocode didn't make sense to me (I couldn't see the 2nd
argument anywhere) so I had a peek at both NetBSD and cephes-2.8
and the code is identical in both.  I believe the pseudo code
should be:

cpow(z,w):
x = creal(w)
y = cimag(w)
r = cabs(z)
t = carg(z)

if y == 0
   if x == 0
      return 0
   else
      return pow(r,x)*(cos(t*x)+I*sin(t*x))
else
   return pow(r,x)*exp(-t*y)*(cos(t*x+y*log(r))+I*sin(t*x+y*log(r)))

Note that the final line looks the same as my final line (modulo
algebraic errors).  The rest is just special casing.

On 2012-Aug-07 21:58:39 -0500, Stephen Montgomery-Smith <stephen at missouri.edu> wrote:
>I wouldn't regard errors in a*u-b*v as catastrophic cancellation.  This 
>is because exp(0) = 1.  So if the error in computing a*u-b*v is approx 
>DBL_EPSILON, and a*u-b*v approx zero, even though the relative error in 
>computing a*u-b*v is going to large (perhaps even infinite), 
>nevertheless the error in exp(a*u-b*v) may still be bounded by 1 or 2 ulp.

OK.

>I would be pleased if cpow(x,y) made special provisions for when y is a 
>small integer, and so, for example, cpow(z,2) was computed as z*z = 
>(x+y)*(x-y) + 2x*y*I.

Thu square-and-multiply approach makes sense.  Where do you draw the
line on "small"?  At some point the rounding errors will exceed the
trig approach.

>Other than that, if your cpow produced cpow(-1,0.5) = I + 1e-16, I 
>wouldn't be shocked at all, and I would find this kind of error totally 
>acceptable.

I like the idea of also special-casing "simple" rational powers.  This
offers things like cpow(-1.,0.5) = I and cpow(-8.,1./3.) = -2

Thank you both for your input.

-- 
Peter Jeremy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-numerics/attachments/20120808/02b7571d/attachment.pgp


More information about the freebsd-numerics mailing list