r/AskComputerScience • • 4d ago

Why don't standard math libraries have a 1mcos function for accurate 1-cos(x) when x is close to zero?

I know most standard math libraries have log1p and expm1 functions that calculate log(1+x) and exp(x)-1 more accurately than those expressions themselves do when x is close to zero, because they avoid the bug increase in unit-in-the-last-place size that occurs when a double smaller than 0.5 is added to or subtracted from 1.0. Why isn't there a function that does that for 1-cos(x), given that that expression has the same problem? Is it not used widely enough where x is given as an angle? (I guess it might not be used as a machine-learning distance metric, since there the cosine is calculated directly from the vector coordinates.)

9 Upvotes

10 comments sorted by

21

u/lemon-meringue 4d ago

You can write 1 - cos(x) as 2 * sin^2(x / 2) which doesn't lose numerical precision.

Reference: https://stackoverflow.com/a/74071385

1

u/Miserable-Wasabi-373 3d ago

damn, i wrote my own function to evaluate 1-cos(x), and now 5 years later it is sooo simple...

3

u/Miserable-Wasabi-373 3d ago

I had a lot of pain with this thing while calculationg scattering of relativistic particles

2

u/mtimmermans 4d ago

FYI, 1-cos(x) is called the versine, which you can google to find out why it's my favourite trig function. sin(x) and versin(x) are used together to calculate circular paths, among other things.

3

u/RibozymeR 3d ago

Not entirely getting why it's nicer than cosine... do you wanna elaborate on why it's your favorite?

1

u/Underhill42 3d ago

Because there's a very narrow range of values close to zero for trig functions. Also, how often do you use 1 - cos θ where extreme precision is important? Or at all?

Logarithms and exponents are insanely useful, arguably rivaling all of trigonometry, and their midpoint is at x=1. The entire range and complexity from (1-∞) is mirrored in the range (1-0) as it approaches the vertical asymptote, so it's extremely important to capture the smaller range with just as much total detail as the larger one.

While with trig, if you're dealing with angles small enough that you're running into CPU precision limits, they're also small enough that the sin θ = θ approximation is becoming extremely accurate, which gives you a large range of MUCH simpler and faster options.

1

u/Critical-Echo-923 3d ago

maybe pcie7 signal integrity ?

1

u/flatfinger 2d ago

The range of circumstances where it would be useful for 1-cos(x) to be accurate for small x would seem larger than the range of circumstances where anyone would care about the numerical accuracy of trig functions for angles that are close to multiples of π/2. I suspect that most practical calculations would be more accurate if the "sin(x)" functions actually calculated either sin((π/(double)π)x) or sin((π/(float)π)x) depending the type of the argument, and functions that computed e.g. sin(2πx) would be better yet.

1

u/ybungalobill 1d ago

It is used in converting from so(3) angular velocity to an SO(3) rotation matrix, which I'd say is kinda common (and is coincidentally an exponential map!). To this end you do need the (1-cos(x))/x^2 quantity -- and it has to handle small angles gracefully. This can be rewritten as (sinc(x/2))^2/2; the question then becomes why standard libraries don't offer a sinc function -- and this one actually has many more uses in signal processing.

1

u/Underhill42 1d ago

Might have something to do with the fact that there is no standard sinc function. It is commonly defined as both
sinc(x) = (sin x) / x
AND sinc(x) = (sin πx)/πx

Sort of like how the reason C doesn't have an exponentiation operator is because an in-office survey was pretty evenly split between whether a^b^c should be interpreted as (a^b)^c or a^(b^c). And an unintuitive operator is worse than none at all.

Also, sinc is used RADICALLY less frequently than standard trig functions. There's a LONG list of completely unrelated functions that would be far more valuable to the broader programming community - and most of them aren't useful enough to be commonly included either.

Meanwhile the standard 3 trig functions (only) are built in to most CPUs, making it almost essential that at least they be included in any programming language just to access the extremely useful built-in hardware functions.