[Python-ideas] Fwd: Trigonometry in degrees
Richard at Damon-Family.org
Fri Jun 15 09:33:44 EDT 2018
On 6/13/18 7:21 AM, Stephan Houben wrote:
> Op wo 13 jun. 2018 13:12 schreef Richard Damon
> <Richard at damon-family.org <mailto:Richard at damon-family.org>>:
> My first comment is that special casing values like this can lead to
> some very undesirable properties when you use the function for
> analysis. Suddenly your sind is no longer continuous (sind(x) is no
> longer the limit of sind(x+d) as d goes to 0).
> The deviations introduced by the special casing are on the order of
> one ulp.
> At that level of detail the sin wasn't continuous to begin with.
I would say the change isn't one ulp, changing a non-zero number to zero
is not one ulp (unless maybe you are on the verge of underflow). It may
be one ulp of 'full scale', but we aren't near the full scale point. It
might be the right answer for a less than one ulp change in the INPUT,
but if we thought that way we wouldn't have minded the non-zero result
in the first place. The fundamental motivation is that for 'nice angles'
we want the 'nice result' when possible, but the issue is that most of
the 'nice angles' in radians are not representable exactly, so it isn't
surprising that we don't get the nice results out.
One property that we like to preserve in functional calculation is that
the following pseudo code
dp = x + delta
derivative = ( f(xp) - f(x) ) / (xp - x)
(or variations where you subtract delta or work at x+delta and x-delta)
should approximate well the derivative of the function, (which for sin
in radians should be cos), and that this improves as delta gets very
small until we hit the rounding error in the computation of f(x). (Note,
I don't divide by delta, but xp-x to remove the round off error in
computing xp which isn't the fault of the function f). Changing a point
because it is the closest to the nice number will cause this calculation
to spike due to the single point perturbation). Yes, this calculation
may start to 'blow up' f(xp) - f(x) is very small compared to f(x) and
we start to measure the round off error in the computation of the
function, near a zero of the function, (which if we are root finding is
common) we can do quite well.
> As I stated in my initial comment on this, if you are going to
> create a
> sind function with the idea that you want 'nice' angles to return
> 'exact' results, then what you need to do is have the degree based
> routines do the angle reduction in degrees, and only when you have a
> small enough angle, either use the radians version on the small
> angle or
> directly include an expansion in degrees.
> Yes that is what my code does.
> It reduces degrees to [0,90].
> Angle reduction would be based on the identity that sin(x+y) =
> sin(x) *
> cos(y) + cos(x) * sin(y) and cos(x+y) = cos(x)*cos(y) - sin(x) *
> If you want to find sin(z) for an arbitrary value z, you can reduce it
> to and x+y where x is some multiple of say 15 degrees, and y is in the
> range -7.5 to 7.5 degrees. You can have stored exact values of sin/cos
> of the 15 degree increments (and only really need them between 0
> and 90)
> and then compute the sin and cos of the y value.
> This is not how sine functions are calculated. They are calculated by
> reducing angle to some interval, then evaluating a polynomial which
> approximates the true sine within that interval.
And that is what my method did (as others have said). Virtual all
methods of computing sin and cos use the angle addition formula (and
even quadrant reduction is using it for the special case of using one of
the angles where sin/cos are valued in-1, 0, 1). The methods that least
use it that I know of reduces the angle to a quadrant (or octant) and
then selects one a number of expansions good for a limited range, or
table interpolation (but even that sort of uses it with the
approximation of sin(x) ~ x and cos(x) ~ 1 for very small x)
More information about the Python-ideas