research/lab/rs/roulette-nodes

1 directory and 2 files in research/lab/rs/roulette-nodes.

Roulette Nodes

  • Counts the nodes of a design's roulette: a wheel of radius r rolls inside or outside a circle of radius R with R/r = a/b in lowest terms, a pencil at seat p in wheel radii draws a trochoid, and a node is a crossing of one curve with itself or of two curves with each other.
  • The counter is mrlylab::roulette::nodes over mrlynum::spirograph::trace: every pair of polyline segments is tested for a proper crossing by orientation signs on a grid of buckets, each pair judged in the one bucket the two bounding boxes first share, so no crossing is counted twice and no pair is missed.
  • The orientation sign is mrlylab::roulette::side, exact whenever the two differences it is handed are exact, whatever the size of their products: the determinant is taken by the fused multiply-add identity of Kahan, whose error is at most twice the rounding unit times the determinant itself, so it can neither flip a sign nor invent one. The differences of two f32 endpoints are exact in f64 while the picture's coordinates keep their exponents within 29 of one another, as these pictures do.
  • Three numbers come back and they are not the same number. total adds the crossings, and a node where n branches meet contributes n(n - 1)/2 of them; points counts the distinct nodes; branches adds n over the nodes, which is the edge count of the picture as a plane graph. The three agree as total = points and branches = 2 points exactly when crowded is zero.
  • Coincident pencils are dropped before counting by mrlylab::roulette::spread: on a circle the seats fall into classes under the rotation group of order gcd(b, 4), and on a line or a polygon every distinct seat draws its own curve, two seats of one radius on a line drawing translates of one shape and never one curve.
  • Crossings within 4e-4 of the picture's longer side cluster into one node; every cell with a crowded node is printed, and reprinted at a tenth of that tolerance to separate an alignment from a near miss.
  • Every count is three sample counts alike, the last two doubled, to five doublings; a cell that never settles is printed with its count.
  • The census sweeps both tracks, every a/b in lowest terms with a <= 20 and b <= 10, four designs of one, two, four and eight pencils, and seven reaches, and prints every cell that breaks a law.
  • Two instruments stand against the counter and share no code with it: the torus reduction, which counts the roots of one real equation in one variable and multiplies by a, and a flood, which rasters the curves as walls and counts the faces they cut the plane into.

THE REDUCTION

  • Over b orbits the centre turns once for u in [0, 2 pi), and the pencil at seat p draws z(u) = A e^(i b u) + r p e^(-i M u) inside and A e^(i b u) + r p e^(i M u) outside, with A the centre path radius and M = a - b inside, M = a + b outside, so A = r M / b in both cases.
  • Two pencils meet where z_p(u) = z_q(v); with s = u + v and d = u - v and e^(i b u) - e^(i b v) = 2i e^(i b s/2) sin(b d/2) the equation becomes 2i A e^(i a s/2) sin(b d/2) = -r(p e^(i M d/2) - q e^(-i M d/2)) inside, where b + M = a, and the same with e^(-i a s/2) outside, where b - M = -a.
  • Taking moduli kills s and leaves one equation in d alone, 2 A abs(sin(b d/2)) = r abs(p e^(i M d/2) - q e^(-i M d/2)); for every solution d the phase then fixes a s / 2 modulo 2 pi, giving exactly a values of s in [0, 4 pi).
  • So with x = d/2 and N the number of x in [0, 2 pi) solving that equation, two distinct curves meet at a N / 2 parameter pairs and one curve meets itself at a (N - 2) / 4, the two dropped solutions x = 0 and x = pi being the diagonal u = v.
  • Two thresholds fall out of it: A b > r abs(p) M is abs(p) < 1, the loop threshold, and A > r abs(p) is abs(p) b < M, the seat inside the centre path. With 0 < abs(p) for the centre seat they make one window, 0 < abs(p) < min(1, M/b), which is three hypotheses and not one: the loop threshold binds whenever a > 2b and outside every track, the seat threshold whenever a < 2b inside.
  • The seat at the wheel's centre, abs(p) = 0, is outside every statement below: it draws the centre circle b times over, so its own crossing count is 0 and not a(b - 1), and its 2ab parameter pairs with another curve sit at 2a points, each hit once a lap.

THE PROOF

  • One curve crosses itself a(b - 1) times when 0 < abs(p) and both thresholds hold. Set C = r abs(p). For p = q the reduction reads A abs(sin(b x)) = C abs(sin(M x)), that is A sin(b x) = -+ C sin(M x), the zeros of the imaginary parts of F = A e^(i b x) - C e^(i M x) and G = A e^(i b x) + C e^(i M x).
  • arg F turns at the rate (A^2 b + C^2 M - A C (b + M) cos((b - M) x)) / abs(F)^2, which is positive for every x if and only if (A - C)(A b - C M) > 0, and the same rate with the sign of the cosine reversed governs G. That product is positive on two components; below both thresholds is the one where A > C, and it is the component that matters, since on the other, abs(p) > 1 with the seat outside the centre path, the argument climbs by 2 pi M and each branch takes 2M zeros, not 2b.
  • Below both thresholds arg F climbs by 2 pi b over a period, so Im F has exactly 2b zeros, and Im G likewise; with C > 0 the two share a zero only where sin(b x) = 0 = sin(M x), which since gcd(b, M) = gcd(a, b) = 1 means x = 0 or x = pi. At C = 0 the two branches are the same function and share all 2b, which is the centre seat and its count of nothing.
  • Hence N = 4b - 2 and the self count is a (N - 2) / 4 = a(b - 1).
  • Two distinct curves of one radius cross 2ab times when 0 < abs(p) = abs(q) and both thresholds hold. The right side is 2 r abs(p) abs(sin(M x + f)) with 2f the angle between the seats, the turning rate is unchanged because a phase only shifts the cosine, each branch again has exactly 2b zeros, and the two share none unless sin(b x) = 0 = sin(M x + f), so N = 4b and the count is a N / 2 = 2ab.
  • Two distinct curves of different radii, both with 0 < abs(p), cross 2ab times under a sufficient bound. The equation squares to 4 A^2 sin^2(b x) = r^2(abs(p) - abs(q))^2 + 4 r^2 abs(p) abs(q) sin^2(M x + f), whose right side rho never vanishes and obeys abs(rho') <= 2 r sqrt(abs(p) abs(q)) M, so 2A sin(b x) - rho can only turn where abs(cos(b x)) <= k = r sqrt(abs(p) abs(q)) M / (A b); if 2 A sqrt(1 - k^2) > r(abs(p) + abs(q)) it is positive there, hence strictly monotone on both flanks of each of the b humps, giving two zeros a hump, N = 4b, and again 2ab.
  • That bound is sufficient and far from necessary: inside 7/3 the two design at abs(p) = 0.950 and 0.672 reads 1.604 against 1.622 and so fails it, while the count is 42, which is 2ab.
  • A whole design. With k distinct curves, every seat obeying the hypotheses above, the roulette carries 2ab C(k, 2) + k a(b - 1) crossings, and as many distinct nodes when no three branches meet, which the multiplicity bucket is there to check.

THE REGIONS

  • At a generic reach the roulette is a connected 4-regular plane graph on its nodes, so Euler cuts the plane into points + 2 regions, the unbounded one among them; connected because every two curves cross, 2ab > 0, and 4-regular because every node is a transversal double point.
  • With a crowded node the graph is not 4-regular and the count is branches - points + 2, which is the same number where nothing is crowded.
  • The flood confirms both at 1600 and at 2400 pixels: inside 3/1 one seat 2, 5/2 7, 7/3 16 at abs(p) = 0.5 and at 0.9, 3/1 two seats 8, 5/2 two seats 32, and the alignment cell inside 7/3 at seat 0.527, where 1288 crossings sit at 1148 nodes carrying 2352 branches, 1206.
  • At k = 1 and b = 1 there is no node at all and the 2 regions are Jordan's, not Euler's.
  • Past the seat threshold the flood tracks the counted crossings and never the law: inside 7/4 two seats at abs(p) = 0.900 and 0.636 count 84 crossings and flood 86 regions, where the law would say 98 and 100.

THE CREST

  • Past the seat threshold the curve is not the one the proof describes, and the count falls in steps, each step the loss of one hump of R(x) = abs(sin(b x)) / abs(sin(M x)) under the level C/A.
  • The steps are exactly the local maxima of R, so the self law holds up to the crest, the least local maximum of R, which is never below 1 because R reaches 1 at the midpoint of any two consecutive zeros of sin(b x), abs(sin(b x)) = 1 there and abs(sin(M x)) <= 1.
  • Below the crest the count is a(b - 1); at the top of the band, as C/A climbs to b/M, it is a(a - b); between them it is a multiple of a that never rises.
  • The pair law is not so patient: one seat past the seat threshold is enough to lose it, inside 7/4 at seats 0.900 and 0.636 reading 42 against 2ab = 56 while both self counts hold at 21 and the crest, 1.333, is not yet reached.
  • At exactly C/A = 1 the curve runs through the centre and a branches meet there, so the counts printed at that one reach, 25 at 7/5 and 31 at 7/6, are neither the law nor a multiple of a; no census cell sits on it.
  • Inside a track with a >= 2b, and outside every track, the seat threshold is past the loop threshold and the crest never bites.

RUN

  • CARGO_BUILD_JOBS=4 cargo run --release -p roulette-nodes
  • About two minutes; prints only, writes nothing.
  • The verbs scratch, law, gap, torus, centre and regions run one section each.

WITNESSES

  • The law: 5553 cells and 4455175 crossings over both tracks, a <= 20, b <= 10, four designs and seven reaches, with 143 aligned cells printed, 576 near misses, 26 cells needing a further doubling and none left unsettled.
  • Two cells disagree, both by a few crossings on a pair at a near tangency, both reading the law at their base sample count and losing crossings under refinement: inside 20/3 carpet at seat 0.250, four pairs at 116 against 120, settled 3664 against 3680; outside 10/9 carpet at seat 0.400, two pairs at 178 against 180, settled 5676 against 5680. The torus reads 3680 and 5680, at two million roots and at eight million.
  • The self law by ratio, one pencil inside at abs(p) = 0.5: 3/1 and 4/1 and 5/1 and 7/1 at 0, 5/2 at 5, 7/2 at 7, 7/3 at 14, 8/3 at 16, 11/4 at 33, against a(b - 1).
  • The pair law: the carpet's eight fills inside a/1 at tile reach 0.30, seat 0.20, give 168, 224, 280, 336, 392 for a = 3..7, against 2ab C(8, 2) = 56a, with no self crossing.
  • The whole law: the carpet's eight fills inside 7/3 give 1176 + 112 = 1288 at every tile reach from 0.2 to 1.2, seat 0.13 to 0.80, against 2ab C(8, 2) + 8 a(b - 1).
  • Two curves inside 7/4 at tile reach 0.90, seats 0.600 and 0.424, give 56 crossings and 21 self crossings each, against 2ab = 56 and a(b - 1) = 21.
  • The alignment: the carpet inside 7/3 at tile reach 0.79, seats 0.527 and 0.373, carries 28 crowded nodes each holding 6 crossings, which is four branches through one point, and none at 0.78 or 0.80; the census cell nearest it, seat 0.950, crowds 28 nodes at three branches.
  • The centre seat: inside 5/2 a seat at 0.5 beside a seat at the wheel's centre reads 20 crossings against 2ab = 20, but they sit at 2a = 10 points and the flood reads 17 regions against the law's 27; the centre curve's own polyline self count is meaningless, 5999 at 6000 samples and 2999 at 3000.
  • The crest: 213 cells over 31 ratios, every count a multiple of a, no rung rising, every cell reading a(b - 1) below the crest and less above it, and all 31 ladders ending at a(a - b).
  • The crest bites: inside 7/6 the self count is 35 at seat 0.158, 21 at 0.175 and 7 at 0.9, while a(b - 1) = 35; inside 7/5 it is 28 at 0.42 and 14 at 0.44; the crest is 1 at 4/3 and 6/5 and 1.089 at 5/4, and where a = 2b - 1 the two ends agree and the ladder is flat.
  • The torus against the polyline: twelve named cells, eleven agreeing, the twelfth the outside 1/10 carpet cell at seat 0.100 where the polyline reads 172 against the torus and the law at 156.
  • The crate tests two_curves_on_one_orbit_cross_twice_the_ratio_whatever_their_seats, a_curve_below_the_threshold_crosses_itself_a_times_b_less_one, an_alignment_reach_crowds_the_nodes_and_the_points_fall_short and the_coincident_pencils_collapse_to_one_pencil_a_curve.