Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Aug 2012 19:24:45 +1000
From:      Peter Jeremy <peter@rulingia.com>
To:        freebsd-numerics@freebsd.org
Subject:   Re: cpow(3) implementations.
Message-ID:  <20120808092445.GB65056@server.rulingia.com>
In-Reply-To: <5021D5DF.7010709@missouri.edu>
References:  <20120808000357.GA11128@server.rulingia.com> <5021D5DF.7010709@missouri.edu>

next in thread | previous in thread | raw e-mail | index | archive | help

--5vNYLRcllDrimb99
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

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

Oops, that last line is wrong and should be:
   exp(a*u - b*v) =3D 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 =3D creal(w)
y =3D cimag(w)
r =3D cabs(z)
t =3D carg(z)

if y =3D=3D 0
   if x =3D=3D 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@missouri.e=
du> wrote:
>I wouldn't regard errors in a*u-b*v as catastrophic cancellation.  This=20
>is because exp(0) =3D 1.  So if the error in computing a*u-b*v is approx=
=20
>DBL_EPSILON, and a*u-b*v approx zero, even though the relative error in=20
>computing a*u-b*v is going to large (perhaps even infinite),=20
>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=20
>small integer, and so, for example, cpow(z,2) was computed as z*z =3D=20
>(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) =3D I + 1e-16, I=20
>wouldn't be shocked at all, and I would find this kind of error totally=20
>acceptable.

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

Thank you both for your input.

--=20
Peter Jeremy

--5vNYLRcllDrimb99
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)

iEYEARECAAYFAlAiMF0ACgkQ/opHv/APuIebdACfeAT7FOE2T0hKyq4Pe9cAkvuc
xUsAn3rJsudDpsacUnPZbDIAN6wT6/IX
=J5iy
-----END PGP SIGNATURE-----

--5vNYLRcllDrimb99--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120808092445.GB65056>