Skip to content

2x is not a '99%' approximation for 1/(1-x) - 1/(1+x) around 0 #742

@dmcooke

Description

@dmcooke

On the web interface, try the expression '1/(1-x) - 1/(1+x)' for a range [0, 0.5] (I'll call this f(x)). Herbie will find some alternatives, including '2*x', which it claims is '99%' accurate. While it's a good approximation near 0, it's worse over most of the range. The same problem occurs for a range bracketing 0, such as [-0.5, 0.5].

E.g., f(0.5) = 1.3333, and 2*0.5=1, for a relative error of ~30%.

It appears that the very small floating-point numbers are drastically over-represented in the sample, making Herbie care much more about fitting to [1e-308, 1e-10], than to [1e-10, 0.5]. In that regime a low-order Taylor expansion is pretty much always going to win.

I can see how this may be ok for large ranges, eg. [2, 1e308]: a lot more fp values are in [1e10, 1e308] than [2, 1e10], but the range is also much wider. The reciprocal situation is rather different: [1e-308, 1e-10] is literally miniscule.

AFAICT, Herbie isn't attempting to divide the range up like it does for large ranges. E.g. if x<1e-6 then 2*x else f(x) would be a good approximation. (Herbie will divide if I restrict the interval to [1e-9, 0.5], for example.)

Suggestions:

  1. If the interval contains 0, Herbie should probably include a warning that the accuracy may be ... inaccurate.
  2. Perform a second accuracy calculation with points sampled uniformly from the interval (that is, choosing a value in the subinterval [x, x+δ] is as probable as the subinterval [y, y+δ]).

Since I spent some time on this, here's some miscellaneous results:

  • Herbie misses f(x) = '2/(1/x - x)', which is an excellent form to use everywhere.
  • Using sollya, I find the degree-2 Chebyshev approximation of f(x) over [0,0.5] is
    (approximately) '1.216286577e-2 + x*(1.570175987 + x*2.058023534)', with a maximum error of 2.23e-2.
    This can be done with two calls to fma.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions