Complex arg-trig functions
Stephen Montgomery-Smith
stephen at missouri.edu
Tue Sep 18 04:02:21 UTC 2012
On 09/17/2012 05:50 PM, Stephen Montgomery-Smith wrote:
>> cacos*() and casin*() should benefit even more from an up-front raising
>> of inexact, since do_hard_work() has 7 magic statements to raise inexact
>> where sum_squares has only 1.
>
> Where is the code that raises inexact up-front?
I don't see why having code upfront will make it much more efficient.
Out of these 7 magic statements, at most two of them will be called.
But I could put something like
if ((x == 0 && y == 0) || (x == 0 && y == 1) || (int)(1+tiny) == 1) {
........
at the beginning of do_hard_work and catanh.
>> ... I now understand what the threshold should be. You have
>> filtered out ax == 1. This makes 1 - ax*ax at least ~2*EPSILON, so
>> ay*ay can be dropped if ay is less than sqrt(2*EPSILON*EPSILON) *
>> 2**-GUARD_DIGITS = EPSILON * 2**-5 say. SQRT_MIN is way smaller
>> than that, so FOUR_SQRT_MIN works too. We should use a larger
>> threshold for efficiency, or avoid the special case for ax == 1.
>> Testing shows that this analysis is off by a factor of about
>> sqrt(EPSILON), since a threshold of EPSILON * 2**7 is optimal.
>> The optimization made no difference to speed; it is just an
>> optimization for understanding. Maybe the special case for ax == 1
>> can be avoided, or folded together with the same special case for
>> evaluation of the real part. This special case is similar to the
>> one in clog(), but easier.
OK, I think I made changes more or less according to your suggestions.
In the case A < A_crossover, a threshold like
DBL_EPSILON*DBL_EPSILON/128 is required. I think the one you set is too
large. It is important that sqrt(x) + x/2 is sqrt(x). (Again I don't
think your tests would pick this up, because you need to do a lot of
tests where y is close to or equal to 1.)
More information about the freebsd-numerics
mailing list