README.md
14.3 kB · markdown
carry-free-mobius
- The design Mobius
nu_Fof the two-digit designF = {0,1}is base-free: it is the pushforward of one functionnu*on the monoidM*of products of0/1polynomials inZ[x], and the base enters only as the order in whichnu*is summed. M*is the multiplicative monoid generated by the nonzero0/1polynomials,S*is that generating set, andnu*is the Dirichlet inverse of1_(S*)onZ[x], which is a unique factorisation domain; evaluationP -> P(base)is a bijectionS* -> S_Fand a monoid homomorphism with finite fibres at everybase >= 2, since an element ofM*has nonnegative coefficients soP(base) = ncaps every coefficient bynanddeg Pbylog_base n, and thereforenu_F(n) = sum_(P in M*, P(base) = n) nu*(P)at every integern.M*is not divisor-closed,1 + x^2 + x^4 = (1 + x + x^2)(1 - x + x^2)with the second factor outside it, sonu*and its convolution live on the ambient monoidAof nonzero polynomials ofZ[x]up to units, wherenu*vanishes offM*by induction.Asplits asN x RwithRthe classes of nonzero constant term, which is divisor-closed inA; a0/1polynomial isx^j bwithba0/1polynomial of constant term 1, sox^k blies inS*exactly whenblies inS*_odd, at everyk >= 0, and1_(S*)is the outer product of the all-ones function onNwith1_(S*_odd)onR. Dirichlet inversion factors with the splitting and the inverse of the all-ones function onNis1 - t, sonu*(x^k b) = 0at everyk >= 2andnu*(x b) = -nu*(b)for everybinR.- Every element of
M*of degreedhas its coefficient ofx^iat mostbinomial(d, i), because a product of0/1polynomials of degreesd_1 + ... + d_r = dis dominated coefficientwise byprod_k (1 + x + ... + x^(d_k))and each factor by(1 + x)^(d_k), so the product is under(1 + x)^d; the maximum coefficient at degreedis therefore exactlybinomial(d, floor(d/2))and(1 + x)^dattains it, which retires the crude cap2^(level-1)the carry bound is stated against. lemma: the carry bound. The maximum coefficient overM*at degree belowlevelagainst the exact capbinomial(level-1, floor((level-1)/2))and the crude cap2^(level-1)the study was first stated against; the carry-free windowbase_set(level), least base with everyPof degree belowlevelunderbase^level, against its closed form(base+1)^(level-1) < base^level; the order windowbase_ord(level), least base with evaluation increasing on all ofM*to degreelevel, and the overtaking pair that breaks each; the pushforward checked term for term against the design Mobius of mrly-pairing verbinverse, with the base 2 full digit set as the control wherenu_F = mu; and the first departing level of the base ladder against the window.sequence: the base-free ladder ofnu*, its running maxima and itsM(base^level)by level, the census ofM*by degree and its partial sums, the maximum coefficient at the deepest degree against the packing width, and an OEIS grep against a local dump named by the environment variableOEIS_STRIPPED.exponent: the growth RATE of the base-free running maximum against the design's mass rate2, the ratiomax/2^level, the per-level step, the exponentlog_2(max)/level, the same ratio split by the residue class oflevelmod2, and geometric mean steps over the last4,6and8levels.pin: the Rust ladder to level18, printed level by level and diffed term for term against the Python running maxima,M(base^level), monoid census and maximum coefficients.exponentin Rust is the verbladder: the same table one line per level as it lands, to whatever level the memory budget reaches, then the residue split, the geometric mean step over windows4to20with the hull those windows span, each of the windows4,6and8read at the last four depths, the first level of the final rising run ofmax/2^level, and the working set.- Domain: the Python holds
M*to degree17, which is2423801elements cumulative, for the ladder and the exponent,M*to degree14for the bound table, and the design Mobius to3^16,4^12,5^11,6^9and7^8; the Rust reaches degree22, where the count ofM*at that degree alone is78798610and43676862of those have nonzero constant term. It stores the degrees0to21, which is35121748elements, and streams the top degree without storing it.
RUN
uv run python research/lab/rs/carry-free-mobius/carry_free.py lemmauv run python research/lab/rs/carry-free-mobius/carry_free.py sequenceuv run python research/lab/rs/carry-free-mobius/carry_free.py exponentbash scripts/cargo.sh cargo run --release -p carry-free-mobius -- pinfrommrlyprod/bash scripts/cargo.sh cargo run --release -p carry-free-mobius -- ladder 22 2.5frommrlyprod/, where the first argument is the top degree and the second the working-set budget in GBbash scripts/cargo.sh cargo test -p carry-free-mobiuspins the Rust ladder to the Python numbers at every level to18- the mobius page prints the same
laddercommand in its own house form,CARGO_BUILD_JOBS=4 cargo run --release -p carry-free-mobius -- ladder 22 2.5, which is one recipe under two wrappers, the build lock being the only difference - The Python
lemmaruns in ten seconds,sequenceandexponentin seventeen each; peak resident memory is0.60GB inlemmaand0.58GB in the other two. - The Rust
pinruns in one second andladder 22 2.5in99seconds; theheldMBcolumn of the table is the working set the generator accounts for itself,26MB at level18and2069MB at level23, and the peak resident memory of the process, measured outside it, is2.41GB inladder 22 2.5; the ladder asserts the Python numbers at every level to18before it prints a deeper one, and stops at the first level whose working set passes the budget, printing that cut. - A
0/1polynomial is a bitmask, so every element ofM*is a packed integer and multiplication of polynomials is multiplication of integers; the Python packs one coefficient to thirty-two bits, which is safe because the coefficient at degree below18never passes2^17, and the Rust packs the coefficient ofx^iat degreedinto as many bits asbinomial(d, i)has, which is the proved cap for that coefficient and no lane can carry:312bits hold a degree-22element against736for a thirty-two bit packing, and the generator prints the coefficient it actually reaches at every degree besidebinomial(d, floor(d/2)). - The packed integer is
P(2^32)in the Python and a mixed-width positional value in the Rust; both order elements by degree and then lexicographically from the leading coefficient down, which is the base-free order, and in both the divisibility of packed integers is polynomial divisibility. - The Rust builds one degree at a time and never stores the top degree: a level is filled bucket by bucket in the two leading coefficients of the target, which are read off the source and the generator before the product is formed, so the buckets arrive already in the base-free order and the running maximum crosses them without a sort of the whole level.
WITNESSES
- the pushforward is exact term for term with
0mismatches at base 2 ton <= 2^15, base 3 ton <= 3^10, base 4 ton <= 4^8and base 5 ton <= 5^7, where108978elements ofM*collapse onto32768integers at base 2 and76210values collide, and104values collide at base 3; the base 2 line is the full digit set, wherenu_F = mu, so the classical Mobius function is the pushforward ofnu*atbase 2 - the degree-graded sums of
nu*are1, -2, 0, 0, ..., so the graded partial sum over degree belowlevelreads1atlevel 1and-1after; the column both generators print isM(base^level), that partial sum plusnu*(x^level), which is the design Mertens atn <= base^levelinclusive and reads0at level1and-1at every level2to23, matchingsum_(n <= base^level) nu_F(n) = -1inside a base's carry-free window - the running maxima of
nu*read1, 1, 2, 3, 4, 7, 15, 23, 45, 86, 162, 331, 741, 1665, 3173, 7508, 17753, 36147, 79645, 182432, 427806, 858703, 2026147at levels1..23, the first eighteen matching the Python term for term, and the first twelve are absent from the local dump whenOEIS_STRIPPEDnames one - the census of
M*by degree reads1, 2, 5, 11, 27, 61, 144, 331, 776, 1788, 4147, 9544, 22000, 50420, 115407, 263062, 598540, 1357535, 3072441, 6935695, 15624802, 35121748, 78798610at degrees0..22, its subsequence with nonzero constant term reads1, 1, 3, 6, 16, 34, 83, 187, 445, 1012, 2359, 5397, 12456, 28420, 64987, 147655, 335478, 758995, 1714906, 3863254, 8689107, 19496946, 43676862, the first is the partial sum of the second term for term, and both are absent from the same dump on the same condition - the maximum coefficient over
M*at degreedreads1, 1, 2, 3, 6, 10, 20, 35, 70, 126, 252, 462, 924, 1716, 3432, 6435, 12870, 24310, 48620, 92378, 184756, 352716, 705432atd = 0..22, which isbinomial(d, floor(d/2)), A001405, term for term, and no coefficient ofx^iat any degree passesbinomial(d, i), the two facts the packing rests on - the maximum of
P(base)overM*at degree belowlevelis exactly(base+1)^(level-1), attained by(1+x)^(level-1), because a0/1polynomial of degreedhasP(base) <= 1 + base + ... + base^d <= (1+base)^dand degrees add over a product; so the carry-free windowbase_set(level)is the least base with(base+1)^(level-1) < base^levelfor everylevel, and it reads3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7atlevel 3..14where the generator enumerates it directly - the order window
base_ord(level)reads3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8atlevel 3..14and is strictly larger thanbase_setatlevel 12andlevel 14, where the first inversion is between two elements of the same degree,(1+x^2)^6 = 2565726409beforex^11 + x^12 = 2539579392at base 6 and(1+x^2)^7 = 781250000000beforex^13 + x^14 = 775112083256at base 7 - the carry-free windows are
4,7,9,12and15at bases3, 4, 5, 6, 7andM(base^level)departs from-1at exactly5,8and10at the three bases where the departure is reachable, one level past the window at each, while bases 6 and 7 hold-1to the depth measured - the first overtaking pair is
(1+x)^4 = 256over3^5 = 243at base 3,(1+x)^7 = 78125over4^8 = 65536at base 4 and(1+x)^9 = 10077696over5^10 = 9765625at base 5 - the running maximum is a blunter statistic than
M(base^level)and survives past the window: it departs at level9at base 3, at level11at base 4 and nowhere to level11at base 5, so1, 1, 2, 3, 4, 7, 15, 23, 45, 86is shared by base 4 and base 5 although base 4 leaves the carry-free window at level8 nu*vanishes at every polynomial divisible byx^2andnu*(x b) = -nu*(b)on the classes of nonzero constant term: the Rust holds onlyM*_odd, assembles every level from that layer and its single shift, and reproduces the Python full-monoid ladder term for term at every level to18, which is the check- on the classes of nonzero constant term,
nu*is invariant under the reciprocalb -> x^(deg b) b(1/x), which is degree-preserving, multiplicative and involutive there, so it is a monoid automorphism ofRcarryingS*_oddonto itself by reversing the bitmask; it is not an invariance on all ofZ[x], since the reciprocal drops thexpower andnu*(x) = -1againstnu*(1) = 1: the Rust reverses every stored element and looks it up in its own layer,0mismatches over the35121747elements ofM*_oddof degree1to21 - the base-free running maximum stays under the design mass at every level measured:
max/2^levelbottoms at0.079102atlevel 11, falls for the last time atlevel 15, and rises at every step from there to0.241536atlevel 23; what runs ahead of the mass is the RATE, and the estimate of that rate is not stable in the window. At depth23the geometric mean step reads2.245836,2.202419,2.242075and2.206405over the last4,6,8and10levels but2.194975,2.149760,2.092480,2.074545and1.996559over the last12,14,16,18and20, a hull of[1.996559, 2.245836]that straddles the mass rate2. The long windows are the ones that fall, and they average in the levels belowlevel 15where the ratio was still falling: the20level window at depth23opens atlevel 3. At the short windows every reading from depth20to depth23sits above2.18and above its own depth-18value,2.220211, 2.215612, 2.207713, 2.245836at window4against2.158562,2.187499, 2.264450, 2.203196, 2.202419at window6against2.186288, and2.201198, 2.214005, 2.182999, 2.242075at window8against2.127878, with no monotone trend inside that span. The measuredlog_2(max)/levelclimbs0.697557, 0.733333, 0.764379, 0.775442, 0.804638, 0.830340, 0.841199, 0.856910, 0.873850, 0.890790, 0.895991, 0.910883atlevel 12..23and has not settled - the step sits under
base^(Re rho) = 2.207512at base 3{0,1}, which is a bracket and not a comparison of one object with itself: base 3 leaves the base-free ladder at level9, reading38against45, so past level8the two orders differ - the wall is memory, not time: level
24needs the degree-22layer resident as a source,1.9GB beyond the2069MB the level-23run accounts for, and every source layer is read as at most four monotone streams over the level's buckets, so streaming the layers is the route past it
PAGES
- mobius THE EXPONENT, TAGGED HONESTLY - the base-free reading of the two-digit column, its
M(base^level), its running maxima and the rate of that maximum against the mass rate2.
SOURCES
- A001405 -
binomial(n, floor(n/2)), matched term for term against the local dump throughn = 17as the exact maximum coefficient of a product of0/1polynomials of total degreen. - mrly-pairing - the design Mobius
nu_Fthis study transports, its boxed zero ofzeta_Fat base 3{0,1}, and the transport theorem that turns a zero right ofalphainto a lower bound on the growth ofsum nu_F.