Skip to content

Read the trigonometric table around the whole circle (#743) - #747

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
fix/trig-table-half-turn
Aug 5, 2026
Merged

Read the trigonometric table around the whole circle (#743)#747
Rafael-SOWNet merged 1 commit into
masterfrom
fix/trig-table-half-turn

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Collaborator

Closes #743.

What was wrong

Every angle in the table of exact trigonometric values is written 2pi/n, so the table names only the angles that divide the turn evenly — and nothing at all between 2pi/5 and 2pi/3, which is most of the second quadrant and the whole lower half of the circle. Each lookup then tried a couple of identities to reach the rest, and they reach some of it and not the neighbouring rest:

sin(2pi/3)  ->  sqrt(3)/2         the table has the entry
sin(4pi/3)  ->  -sqrt(3)/2        reached by the doubled-angle identity
sin(5pi/3)  ->  sin(5/3 * pi)     the same value again, and not reached

This is how #743 was reported: the roots of unity are handed back in a + bi form, so one of the six roots of x^6 = 1 came back carrying an unevaluated sine — its own conjugate, spelled differently, two lines above it.

What the fix does

1. The half turn. sin(x) = -sin(x - pi), and the same for the cosine; the tangent's period is half a circle, so it takes no sign back. Applied once around the lookups rather than inside them, so it cannot turn back on itself and loop.

2. Table entries are read before a value is built out of the doubled angle. Both routes are exact, but the doubled-angle one builds a nested radical where the table has a flat one — cos(6pi/5) came back as -sqrt((1 + (sqrt(5) - 1)/4) / 2) for a number the table names as -(sqrt(5) + 1)/4 — so the roots of x^5 = 1 were written both ways at once. Reading the table first makes each root come out the way its conjugate does.

was is
sin(5/3 * pi) sin(5/3 * pi) -sqrt(3)/2
cos(4/5 * pi) cos(4/5 * pi) -(1 + sqrt(5))/4
sin(8/5 * pi) sin(8/5 * pi) -sqrt(10 + 2*sqrt(5))/4
tan(5/3 * pi) tan(5/3 * pi) -sqrt(3)
x^6 - 1 = 0 { …, 1/2 + i * sin(5/3 * pi) } all six exact
x^5 - 1 = 0 carried cos(4/5*pi) and sin(8/5*pi) all five exact, conjugates matching

Measured

The risk in widening a lookup table is that it starts answering angles it does not know, so the check is a sweep rather than the reported cases: every k/n * pi of the first turn for eighteen denominators, 1158 calls in all, each resolved value checked against the numeric value of the call it replaced.

That sweep is the regression test, along with the reported angles, the roots of unity, and the angles the table always answered.

🤖 Generated with Claude Code

Every angle in the table of exact values is written `2pi/n`, so it names only
the angles that divide the turn evenly -- and nothing at all between `2pi/5`
and `2pi/3`, which is most of the second quadrant and the whole lower half.
Each lookup then tried a couple of identities to reach the rest, and they reach
some of it and not the neighbouring rest:

    sin(2pi/3)  ->  sqrt(3)/2        the table has the entry
    sin(4pi/3)  ->  -sqrt(3)/2       reached by the doubled-angle identity
    sin(5pi/3)  ->  sin(5/3 * pi)    the same value again, and not reached

What was missing is the half turn: `sin(x) = -sin(x - pi)`, and the same for
the cosine, while the tangent's period *is* half a circle so it takes no sign
back. Applied once around the lookups rather than inside them, so it cannot
turn back on itself and loop.

The table entries are also read before a value is built out of the doubled
angle, which was not the previous order and is what makes the output
consistent. Both routes are exact; the doubled-angle one builds a nested
radical where the table has a flat one, so `cos(6pi/5)` came back as
`-sqrt((1 + (sqrt(5) - 1)/4) / 2)` for a number the table names as
`-(sqrt(5) + 1)/4`, and the roots of `x^5 = 1` were written both ways at once.

This is how #743 was reported: the roots of unity are handed back in a + bi
form, and one of six came back carrying a sine.

    x^6 - 1 = 0
      was  { 1, 1/2 + i*sqrt(3)/2, ..., 1/2 + i * sin(5/3 * pi) }
      now  { 1, 1/2 + i*sqrt(3)/2, ..., 1/2 + i * -1/2*sqrt(3) }

    x^5 - 1 = 0  had cos(4/5*pi) and sin(8/5*pi) in it; both are now exact,
                 and each root is now written the way its conjugate is.

Measured by sweeping every `k/n * pi` of the first turn for eighteen
denominators -- 1158 calls -- and checking each resolved value against the
numeric value of the call it replaced. 581 resolved before and 690 after, with
no disagreement in either run: what was missing was missing rather than wrong,
and the 109 newly exact values are right.

Suite 4979 -> 4991 passed / 0 failed, F# 130/130, corpus 112/117 with 0 wrong
and every verdict and answer byte-identical. rootcheck is 595/596 on this
branch, its one incomplete case being #744, which is a separate defect in the
solver and is fixed in PR #745 rather than here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Rafael-SOWNet
Rafael-SOWNet merged commit 0cf8aee into master Aug 5, 2026
24 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the fix/trig-table-half-turn branch August 5, 2026 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Roots of unity of order 5 and 6 come back with an unevaluated sin/cos in them

1 participant