From 47cccbdb85d841078dc2bdc2383d6a6241da31c3 Mon Sep 17 00:00:00 2001 From: queue-miscreant Date: Mon, 24 Feb 2025 03:06:14 -0600 Subject: [PATCH] extra extra revisions to polycount --- .../3/index/execute-results/html.json | 4 ++-- .../5/index/execute-results/html.json | 4 ++-- polycount/3/index.qmd | 18 +++++++++++++++--- polycount/4/index.qmd | 6 +++--- polycount/5/index.qmd | 6 ++++-- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/_freeze/polycount/3/index/execute-results/html.json b/_freeze/polycount/3/index/execute-results/html.json index cc45b74..c1c4cc4 100644 --- a/_freeze/polycount/3/index/execute-results/html.json +++ b/_freeze/polycount/3/index/execute-results/html.json @@ -1,8 +1,8 @@ { - "hash": "3ce9c87a34928281a8934daca818c9e4", + "hash": "db9082462bd0496a6f94d531a02b794b", "result": { "engine": "jupyter", - "markdown": "---\ntitle: \"Polynomial Counting 3: The third degree\"\nformat:\n html:\n html-math-method: katex\ndate: \"2021-02-06\"\ndate-modified: \"2025-02-08\"\njupyter: python3\ncategories:\n - algebra\n - phinary\n - binary\n - python\n---\n\n\n\nThis post assumes you have read the [first](../1) post, which introduces generalized positional counting, and the [second](../2), which restricts the focus and specifies the general aim.\n\nThus far, the systems have been based on quadratic polynomials and two-term linear recurrences,\n or more directly, carries of width two.\nNumbers larger than one introduce certain complications to carries.\nWith that in mind, let's go back to things closer to phinary and Fibonacci.\n\n\nTribonacci and Beyond\n---------------------\n\nThe *Tribonacci numbers* ([OEIS A000073](http://oeis.org/A000073)) come from elongating the Fibonacci recurrence to 3 terms.\nIn other words, this is the carry/recurrence $\\langle 1,1,1|$.\nThe Tribonacci numbers are seeded with two zeros followed by a single one; thus, the sequence begins $0, 0, 1, 1, 2, 4, 7, 13,\\dots$\nThe *Tribonacci constant* is the limiting ratio of these numbers (i.e., the positive real root of $x^3 - x^2 - x - 1$) with approximate value\n $T = 1.8393\\dots$\n\nThe number two bounds both this number and the terms in the recurrence, so its expansion can be deduced:\n\n$$\n\\textcolor{red}{2} = 1.\\textcolor{red}{111}_T = \\textcolor{blue}{1.11}1_T = \\textcolor{blue}{1}0.001_T\n$$\n\nNaturally, the string \"111\" will be illegal in both systems.\nThe Tribonacci expansions of the integers are as follows:\n\n:::: {.row .text-center width=\"60%\"}\n::: {#canonical-tribonacci-table .column}\n\n| *n* (Decimal) | *n* (base $T$) | *n* (Tribonacci) |\n|--------------:|:--------------:|------------------|\n| 0 | 0 | 0 |\n| 1 | 1 | 1 |\n| 2 | 10.001 | 10 |\n| 3 | 11.001 | 11 |\n| 4 | 100.100011 | 100 |\n| 5 | 101.100011 | 101 |\n| 6 | 110.101011 | 110 |\n| 7 | 1000.101011 | 1000 |\n| 8 | 1001.101011 | 1001 |\n| 9 | 1010.110100011 | 1010 |\n| 10 | 1100.010100011 | 1011 |\n\n:::\n::::\n\nSince \"111\" is a rarer string than \"11\", the integral base more closely resembles standard binary.\n\nExtensions of the Fibonacci numbers, which have an $n$-term recurrence\n (seeded with $n - 1$ zeroes followed by a one) are called \"n-nacci\" or \"n-bonacci\" numbers.\nIf we discard the seeding terms, then for larger and larger *n*, this sequence of sequences appears\n to approach the powers of two.\n\n$$\n\\begin{matrix}\n \\text{Fibonacci: } & & & 0,& 1,& 1,& 2,& 3,& 5,& 8\\dots \\\\\n \\text{Tribonacci: } & & 0,& 0,& 1,& 1,& 2,& 4,& 7,& 13\\dots \\\\\n \\text{Tetranacci: } & 0,& 0,& 0,& 1,& 1,& 2,& 4,& 8,& 15\\dots \\\\\n \\vdots \\\\\n \\text{Binary: } & (\\dots,& 0,& 0,& 1,)& 1,& 2,& 4,& 8,& 16\\dots\n\\end{matrix}\n$$\n\nIn the limit, the rightmost and leftmost \"1\"s in the carry $\\langle 1, 1, ..., 1, 1 |$ are\n infinitely far away from each other.\nThis is similar to binary, in which $2 = 1.1111\\dots_2$.\nThis argument is clearer if we directly manipulate the carry as a polynomial $p_n(x)$:\n\n$$\n\\begin{align*}\np_n &= x^n - x^{n-1} - … - x - 1 \\\\\n-p_n &= -x^n + x^{n-1} + … + x + 1 \\\\\nx^n - p_n &= x^{n-1} + … + x + 1 \\\\\nx - p_n x^{-n+1} &= 1 + x^{-1} + … x^{-n+2} + x^{-n+1} \\\\[8pt]\n\\text{Let } n &\\rightarrow \\infty \\\\\nx &= 1 + x^{-1} + x^{-2} + x^{-3} + …\n\\end{align*}\n$$\n\nSince both *φ* and $T$ are greater than 1, we can assume that $x > 1$, which causes the\n $x^{-n+1}$ term to vanish in the limit.\nUnfortunately, this means $p_n$ should diverge, invalidating the above argument.\n\nIgnoring this, the last line can be manipulated as a power series:\n\n$$\n\\begin{align*}\n\\frac{1}{1 - x} &= 1 + x + x^2 + x^3 + \\dots \\\\\n\\frac{1}{1 - (1/x)} &= 1 + x^{-1} + x^{-2} + x^{-3} + \\dots \\\\\nx &= \\frac{1}{1- (1/x)} \\\\\nx - 1 &= 1 \\\\\nx &= 2\n\\end{align*}\n$$\n\nWhich is to imply that, in a non-rigorous sense and by partially assuming the conclusion,\n that the $n$-nacci constants approach two.\n\n\nGolder than Gold\n----------------\n\nAll carries entirely made up of \"1\"s correspond to the $n$-nacci constants.\nWhile this would appear to exhaust every sequence without going to negative numbers,\n it ignores the potential of carries with a \"0\".\n\nStarting simple, Narayana's cows sequence ([OEIS A000930](http://oeis.org/A000930)) corresponds to\n the recurrence $\\langle 1,0,1|$.\nIt may be seeded with either three 1's, or in the same way as above, with a sequence of 0's followed by a 1.\nThe limiting ratio $\\psi \\approx 1.4656\\dots$ is called the supergolden ratio.\nThe introduction of \"0\"s turns out to have big implications, since the concatenation trick to devise\n the expansion of two no longer works.\nHowever, hope is not lost.\n\n$$\n\\begin{gather*}\n 1\\textcolor{red}{1}000_\\psi\n = 10\\textcolor{red}{101}_\\psi\n = \\textcolor{blue}{101}01_\\psi\n = \\textcolor{blue}{1}00001_\\psi \\\\\n \\textcolor{red}{2} = 1.\\textcolor{red}{101}_\\psi\n = \\textcolor{blue}{1.1}01_\\psi\n = \\textcolor{blue}{1}0.001\\textcolor{blue}{1}_\\psi\n = 10.00\\textcolor{purple}{11}_\\psi\n = 10.0\\textcolor{purple}{1}0000\\textcolor{purple}{1}_\\psi\n\\end{gather*}\n$$\n\nIncredibly, the carry contains not only an explicit rule for \"101\", but implicit rules \"2\" and \"11\".\nThis sort of makes sense: since $\\psi < \\varphi$, adjacent place values are \"too dense\",\n and therefore we can rewrite the string \"11\".\nOn the other hand, attempting to manipulate \"1001\" and \"10001\" results in circuiting back to the original string.\n\n$$\n\\begin{split}\n 100\\textcolor{red}{1}000000_\\psi\n &= 1000\\textcolor{red}{101}000_\\psi\n = 1000\\textcolor{orange}{1}01000_\\psi\n = 10000\\textcolor{orange}{1}1\\textcolor{orange}{1}00_\\psi \\\\\n &= 10000\\textcolor{blue}{11}100_\\psi\n = 1000\\textcolor{blue}{1}0010\\textcolor{blue}{1}_\\psi\n = 1000100\\textcolor{red}{101}_\\psi \\\\\n &= 100010\\textcolor{red}{1}000_\\psi\n = 1000\\textcolor{orange}{101}000_\\psi\n = 100\\textcolor{orange}1000000_\\psi \\\\ \\\\\n \\textcolor{red}{1}0001000_\\psi\n &= 0\\textcolor{red}{101}1000_\\psi\n = 010\\textcolor{blue}{11}000_\\psi\n = 01\\textcolor{blue}{1}0000\\textcolor{blue}{1}_\\psi \\\\\n &= 0\\textcolor{purple}{11}00001_\\psi\n = \\textcolor{purple}{1}0000\\textcolor{purple}{1}01_\\psi \\\\\n &= 10000\\textcolor{red}{101}_\\psi = 1000\\textcolor{red}{1}000_\\psi\n\\end{split}\n$$\n\nI call these strings of \"0\"s sandwiched between \"1\"s *spacings*.\nThe smallest spacing, with a width of zero, is the Fibonacci recurrence.\nIf we forbid both the width-1 and width-0 spacings from appearing in supergolden expansions,\n we obtain the following list:\n\n:::: {.row .text-center width=\"60%\"}\n::: {#canonical-supergolden-table .column}\n\n\n\n| *n* (Decimal) | *n* (base $\\psi$) |\n|--------------:|:-------------------:|\n| 0 | 0 |\n| 1 | 1 |\n| 2 | 10.0100001 |\n| 3 | *100.0110001* |\n| 3 | 100.1000100001 |\n| *4* | *110.0001100001* |\n| 4 | 1000.1000100001 |\n| *5* | *1010.0001100001* |\n| 5 | 10000.0010001 |\n| 6 | 10001.0010001 |\n| *7* | *10010.0110002* |\n| *7* | *10010.1000012* |\n| 7 | 100000.0001000001 |\n| 8 | 100001.0001000001 |\n| 9 | 100100.0000001001 |\n| 10 | 1000000.0000001001 |\n\n:::\n::::\n\nIn the above table, some intermediate steps are shown in red,\n but the last entry for each integer is canonical.\nNot only does the number of digits grow radically faster than in phinary (or even binary),\n but there are many more intermediate steps.\n\nFor space reasons, I do not show the integral dual.\nSlowly-growing sequences, which have largely uninteresting integral systems, dominate the rest of this post.\nTherefore, the remainder of this post will focus solely on fractional systems.\n\n\nRadiant Plastic\n---------------\n\nA similar degree 3 recurrence is $\\langle 0,1,1|$.\nIts root corresponds to the plastic ratio $\\rho \\approx 1.3247\\dots$.\nA number of sequences share this recurrence; when seeded with $0, 0, 1$ as before,\n the best match is the Padovan sequence ([OEIS A000931](http://oeis.org/A000931)),\n which begins with an additional one.\n\nSince $\\rho < \\psi < \\varphi$, we should expect that spacings of at least width two are illegal.\nThe system turns out to be even stricter than that: spacings up to and including width three are expandable.\n\n$$\n\\begin{array}{c|c}\n \\text{Width} & \\textcolor{red}{0} & \\textcolor{green}{1} & 2 & \\textcolor{blue}{3} \\\\ \\hline\n & 0\\textcolor{red}{011}_\\rho\n & 010\\textcolor{red}{1}000_\\rho\n & 0\\textcolor{red}{1}00\\textcolor{red}{1}00000_\\rho\n & 0\\textcolor{red}{1}0001_\\rho\n \\\\\n & \\textcolor{red}{1}000_\\rho\n & 0100\\textcolor{red}{011}_\\rho\n & 00\\textcolor{red}{011}\\textcolor{red}{011}00_\\rho\n & 00\\textcolor{red}{011}1_\\rho\n \\\\\n && 0\\textcolor{blue}{10001}1_\\rho\n & 000\\textcolor{blue}{11011}00_\\rho\n & 000\\textcolor{orange}{111}_\\rho\n \\\\\n && \\textcolor{blue}{1}000001_\\rho\n & 00\\textcolor{blue}{1}0101000_\\rho\n & 00\\textcolor{orange}{1}100_\\rho\n \\\\\n &&\n & 0010\\textcolor{green}{101}000_\\rho\n & 0\\textcolor{red}{011}00_\\rho\n \\\\\n &&\n & 001\\textcolor{green}{1000001}_\\rho\n & \\textcolor{red}{1}00000_\\rho\n \\\\\n &&\n & 0\\textcolor{red}{011}000001_\\rho\n \\\\\n &&\n & \\textcolor{red}{1}000000001_\\rho\n \\\\\\\\\n \\hline\n & s_0 = \\rho^2\n & s_1 = \\rho s_{5}\n & s_2 = \\rho s_{8}\n & s_3 = \\rho\n\\end{array}\n$$\n\nThe final line is shorthand for the spacing rules:\n\n- The zero-spacing is equal to a one in the place value two higher than it\n- The one-spacing is equal to an five-spacing which begins one place value higher than it\n- The two-spacing is equal to an eight-spacing which begins one place value higher than it\n- The three-spacing is equal to a one in the place value one higher than it\n\nWith these rules, we can write a canonical expansion expansion for 2:\n\n$$\n\\begin{align*}\n \\textcolor{red}{2}\n &= 1.\\textcolor{red}{011}\n = \\textcolor{blue}{1.011}\n = \\textcolor{blue}{1}\\overbrace{0.0100000}^{8 \\text{ digits}}\\textcolor{blue}{1} \\\\\n &= \\textcolor{purple}{10.01}000001\n = \\textcolor{purple}{1}00.000000\\textcolor{purple}{1}1 \\\\\n &= 100.00000\\textcolor{red}{011}\n = 100.0000\\textcolor{red}{1}\n\\end{align*}\n$$\n\nSince $\\rho < \\sqrt 2$, the largest place value in the expansion of two is $\\rho^2$, which\n distinguishes it from previous systems.\n\nSimilarly to how the width-two and width-three spacings are allowed in the supergolden ratio base,\n we realize that the width-four spacing cannot be expanded further in the plastic ratio base:\n\n$$\n\\begin{align*}\n \\textcolor{red}{1}0000\\textcolor{red}{1}000\n &= 0\\textcolor{red}{011}00\\textcolor{red}{011}\n = 001\\textcolor{blue}{10001}1\n = 00\\textcolor{blue}{2}000001 \\\\\n &= \\textcolor{blue}{1}000000\\textcolor{blue}{1}1\n = 100001000\n\\end{align*}\n$$\n\nWith these implicit rules derived for spacings of width smaller than three,\n the plastic expansions of the integers up to ten are as follows:\n\n:::: {.row .text-center width=\"70%\"}\n::: {#canonical-plastic-table .column}\n\n\n\n| *n* (Decimal) | *n* (base $\\rho$) |\n|--------------:|:----------------------------:|\n| 0 | 0 |\n| 1 | 1 |\n| 2 | 100.00001 |\n| *3* | *101.00001* |\n| *3* | *1000.00101* |\n| 3 | 1000.01000001 |\n| *4* | *10000.0101000000001* |\n| 4 | 10000.1000001000001 |\n| *5* | *10100.0000001000001* |\n| 5 | 100000.1000001000001 |\n| *6* | *100001.1000001000001* |\n| *6* | *100100.0000001000001* |\n| *6* | *1000000.0010001000001* |\n| 6 | 1000000.0100000000001 |\n| *7* | 1000001.0100000000001 |\n| 7 | 1000010.0000100000001 |\n| *8* | *1001000.0000100000001* |\n| *8* | *10000000.0100100000001* |\n| *8* | *10000000.1000000001001* |\n| 8 | 10000000.100000001000000001 |\n| 9 | 10000100.000000001000000001 |\n| 10 | 10001000.001000001000000001 |\n\n:::\n::::\n\nClearly, this base is incredibly sensitive.\nA number as small as 8 has a fractional part as small as $\\rho^{-18}$ in its expansion.\n\n\nSkipped Spacings\n----------------\n\nWhen discussing the expandable spacings in the supergolden and plastic bases, they jumped from\n width one to width three.\nDid we forgot width 2?\nThe strings \"1001\" and \"10001\" are associated to the carries\n $\\langle 1, 0, 0, 1|$ and $\\langle 1, 0, 0, 0, 1|$.\n\n| Spacing Width | Carry | Integral Sequence | Root |\n|---------------|--------------------------------------------|------------------------------------------|---------------------------|\n| 0 | $\\langle 1,1|$ | Fibonacci numbers, Lucas numbers | Golden Ratio, $\\varphi$ |\n| 1 | $\\langle 1,0,1|$ | Narayana's cows sequence | Supergolden Ratio, $\\psi$ |\n| 2 | $\\langle 1,0,0,1|$ | [OEIS A003269](https://oeis.org/A003269) | Unnamed $(\\upsilon?)$ |\n| 3 | $\\langle 1,0,0,0,1| \\simeq \\langle 0,1,1|$ | Padovan sequence, Perrin sequence | Plastic Ratio, $\\rho$ |\n\nI chose the symbol $\\upsilon$ since it came from the second half of the Greek alphabet,\n like the others.\n\nWhile the width-two spacing is a irreducible polynomial like its predecessors,\n the width-three one can be factored\n\n::: {#aae758ce .cell execution_count=2}\n``` {.python .cell-code}\nfrom sympy.abc import x\n\ndef spacing(width):\n return x**(width + 2) - x**(width + 1) - 1\n\nspacing(3).factor()\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=2}\n$\\displaystyle \\left(x^{2} - x + 1\\right) \\left(x^{3} - x - 1\\right)$\n:::\n:::\n\n\nThis also means that despite $\\rho$ and $\\psi$ being cubic roots,\n $\\upsilon$ is irreducibly a quartic root, despite being between them in terms of spacing width.\n\nThe right polynomial may be familiar from the previous post as $\\langle 1, -1 |$,\n which only has complex roots.\nIt happens to be the sixth cyclotomic polynomial ($\\Phi_6$), and allows the width-three spacing\n to be equivalent to the simpler plastic ratio carry.\n\nAs previously stated, the cyclotomic polynomials cause big trouble for carries.\nOther than factoring, there appears to be no way to derive $\\langle 0,1,1|$ from $\\langle 1,0,0,0,1|$.\nAt best, we can observe the following:\n\n$$\n\\begin{matrix}\n \\langle 1,0,0,0,1| && \\langle 0,1,1| \\\\ \\hline\n 11111 &\\iff& 11111 \\\\\n 101110 && 1000111 \\\\\n 1001100 &\\iff& 1001100 \\\\\n 10001000 && 1100000 \\\\\n 100000000 &\\iff& 100000000 \\\\\n\\end{matrix}\n$$\n\n\n### Chopped Circles\n\nThe appearance of a cyclotomic factor is not unique to the width-three spacing.\nEach of the smaller-width rules in the supergolden and plastic bases can be reexamined as polynomials.\nAfter converting and factoring, their cyclotomic factors become clear:\n\n$$\n\\begin{gather*}\n 11000_\\psi = 100001_\\psi \\\\\n 1\\bar{1}\\bar{1}001_\\psi = 0 \\\\\n \\psi^5 - \\psi^4 - \\psi^3 + 1 \\\\\n (\\psi - 1)(\\psi + 1)(\\psi^3 - \\psi^2 - 1) \\\\\n \\Phi_1 \\Phi_2 \\langle 1,0,1|\n \\\\ \\\\\n \\begin{gather*}\n 101000_\\rho = 1000001_\\rho &\n 100100000_\\rho = 1000000001_\\rho \\\\\n 1\\bar{1}0\\bar{1}001_\\rho = 0 &\n 1\\bar{1}00\\bar{1}00001_\\rho = 0 \\\\\n \\rho^6 - \\rho^5 - \\rho^3 + 1 &\n \\rho^9 - \\rho^8 - \\rho^5 + 1 \\\\\n (\\rho - 1)(\\rho^2 + 1)(\\rho^3 - \\rho - 1) &\n \\dots(\\rho^2 - \\rho + 1)(\\rho^3 - \\rho - 1) \\\\\n \\Phi_1 \\Phi_4 \\langle 0,1,1| &\n \\Phi_1 \\Phi_2 \\Phi_4 \\Phi_6 \\langle 0,1,1|\n \\end{gather*}\n\\end{gather*}\n$$\n\nThough I am uncertain without a proof, it seems that cyclotomic polynomials\n play a role in spacing out \"1\"s.\nThis is to say that spacings have a \"fundamental\" irreducible polynomial.\nBy multiplying certain cyclotomic polynomials by the fundamental, (all?) smaller spacings\n can produce spacings the size of the fundamental or less.\n\nNaturally, I attempted to write a program to compute lesser spacings from an implicit rule.\nGenerally, this entailed assembling all lesser spacings, then expanding the rightmost 1\n if unable to find any spacing, else replacing and continuing.\nUnfortunately, since it operates in lockstep, it gets stuck easily, and I had little success.\nMy Haskell code can be found [here](zero_spacing.hs).\n\n### Inherently Factorable Spacings\n\nThe width-three spacing is not fundamental, since it can be factored.\nWe can collect reducible spacings into a table:\n\n::: {#6f97736a .cell execution_count=3}\n``` {.python .cell-code}\nis_irreducible = lambda p: len(p.factor().as_ordered_factors()) == 1\ndisplay = lambda x: color(\"green\", \"Yes\") if x else color(\"red\", \"No\")\n\nMarkdown(tabulate(\n zip(*(\n [[\"*n*\", \"Irreducible?\"]]\n + [[ str(i), display(is_irreducible(spacing(i))) ] for i in range(20)]\n ))\n))\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=3}\n------------ ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- -------------------------------------\n*n* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19\nIrreducible? Yes Yes Yes No Yes Yes Yes Yes Yes No Yes Yes Yes Yes Yes No Yes Yes Yes Yes\n------------ ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- -------------------------------------\n:::\n:::\n\n\nIn the range given, this table appears to repeat every six terms.\nWe can examine each of these factors directly:\n\n$$\n\\begin{align*}\n x^5 - x^4 - 1 &= (x^2 - x + 1)\n (x^3 - x - 1) \\\\\n &= 1\\bar{1}1_x * 10\\bar{1}\\bar{1}_x \\\\\n x^{11} - x^{10} - 1 &= (x^2 - x + 1)\n (x^9 - x^7 - x^6 + x^4 + x^3 - x - 1) \\\\\n &= 1\\bar{1}1_x * 10\\bar{1}\\bar{1}0110\\bar{1}\\bar{1}_x \\\\\n x^{17} - x^{16} - 1 &= (x^2 - x + 1)\n (x^{15} - x^{13} - \\dots + x^4 + x^3 - x - 1) \\\\\n &= 1\\bar{1}1_x * 10\\bar{1}\\bar{1}0110\\bar{1}\\bar{1}0110\\bar{1}\\bar{1}_x \\\\\n 5, 11, 17, \\dots &= 6n + 5\n\\end{align*}\n$$\n\nEach of these polynomials has $\\Phi_6$ as a common factor.\nThe other factor appears to be a truncation of the repeating string \"$\\underline{0110\\bar{1}\\bar{1}}$\".\n^[Since I already use the overbar for negative digits, I gather repeating terms using an underline as a vinculum.]\nInterpreted as a power series, this is the reciprocal of $-\\Phi_6$ ([OEIS A010892](https://oeis.org/A010892)).\n\nAs the carry approaches infinite width, the $x$ terms go to 0 for $x < 1$.\nThis shows that like the $n$-nacci constants approach two, the spacing constants approach one.\n\n\nRepeating Expansions\n--------------------\n\nLet's not get too eager here and instead return to base $\\upsilon$.\nIt should be possible to expand the strings \"11\" and \"101\", since it is the fundamental spacing of width 2.\nHowever, we immediately run into an issue:\n\n$$\n\\begin{array}{c|c}\n \\text{Width} & \\textcolor{green}{0} & \\textcolor{blue}{1} & \\textcolor{red}{2} \\\\ \\hline\n & 01\\textcolor{red}{1}00000_\\upsilon\n & 010\\textcolor{red}{1}0000_\\upsilon\n & 0\\textcolor{red}{1001}_\\upsilon\n \\\\\n & 010\\textcolor{red}{1001}0_\\upsilon\n & 0100\\textcolor{red}{1001}_\\upsilon\n & \\textcolor{red}{1}0000_\\upsilon\n \\\\\n & 0\\textcolor{blue}{101}0010_\\upsilon\n & 0\\textcolor{orange}{1001}001_\\upsilon\n \\\\\n & \\textcolor{blue}{1}000001\\textcolor{blue}{1}_\\upsilon\n & \\textcolor{orange}{1}0000001_\\upsilon\n \\\\\n & 100000\\textcolor{green}{11}_\\upsilon \\\\\n & \\vdots \\\\ \\hline\n & s_0 = \\ ? & s_1 = \\rho s_6 & s_2 = \\rho\n\\end{array}\n$$\n\nThe width-0 expansion is recursive.\nIf we continue to apply its rule, we generate the string \"100001\" repeating.\nFortunately, each repeating unit is a width-four spacing, which is allowed by the carry.\n\nRepeating expansions imply a representation by geometric series:\n\n$$\n\\begin{gather*}\n 1.\\underbrace{\\underline{0\\dots1}}_{n}{}_x = 1 + x^{-n} + x^{-2n} + x^{-3n} + \\dots\n = \\frac{1}{1 - (1/x)^n} = \\frac{x^n}{x^n - 1}\n \\\\\n 10 = 1.\\underbrace{\\underline{0\\dots1}}_{n}{}_x ~\\iff~ x = \\frac{x^n}{x^n - 1} \\\\\n 1 = \\frac{x^{n-1}}{x^n - 1} \\\\ \\\\\n x^{n-1} = x^n - 1\n\\end{gather*}\n$$\n\nThe final expression is just the definition of a carry, so we can immediately write:\n\n$$\n\\begin{align*}\n 10_\\varphi &= 1.\\underline{01}_\\varphi & &\n \\text{Carry } \\langle 1,1| \\\\\n 10_\\psi &= 1.\\underline{001}_\\psi & &\n \\text{Carry } \\langle 1,0,1| \\\\\n 10_\\upsilon &= 1.\\underline{0001}_\\upsilon & &\n \\text{Carry } \\langle 1,0,0,1| \\\\\n 10_{\\rho} &= 1.\\underline{00001}_\\rho & &\n \\text{Carry } \\langle 1,0,0,0,1| = \\langle 0,1,1|\n\\end{align*}\n$$\n\nThis neatly ties repeating spacings in with carries.\n^[Recall that when we naively computed ten in base phi, we got \"10100.0100101010101010101\".\nAfter a certain point, this expansion alternates between 0 and 1. Assuming that this is true repetition\nand applying $10_\\varphi = 1.\\underline{01}_\\varphi$, one obtains \"10100.0101\", which is canonical. ]\n\nBut we didn't want \"10\" as a repeating expansion, we wanted \"11\".\nAttempting to justify with the same strategy:\n\n$$\n\\begin{align*}\n 0.11_\\upsilon &= 1.\\underline{00001}_\\upsilon & \\text{Carry } \\langle 1,0,0,1|\n \\\\\n \\frac{1}{x} + \\frac{1}{x^2} &= \\frac{x^n}{x^n - 1} \\\\\n x + 1 &= \\frac{x^{n+2}}{x^n - 1}\n \\\\[8pt]\n x^{n+1} + x^n - x - 1 &= x^{n+2} \\\\\n x^{n+2} - x^{n+1} - x^n + x + 1 &= 0 \\\\\n x^n(x^2 - x - 1) + x + 1 &= 0\n\\end{align*}\n$$\n\n::: {#83a45569 .cell execution_count=4}\n``` {.python .cell-code}\nrepeating_pair = lambda n: (x**n * (x**2 - x - 1) + x + 1).expand().factor()\n\nMarkdown(tabulate(\n zip(*(\n [[\"*n*\", \"Irreducible?\"]]\n + [[ str(i), display(is_irreducible(repeating_pair(i))) ] for i in range(1, 10)]\n ))\n))\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=4}\n------------ ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- -------------------------------------\n*n* 1 2 3 4 5 6 7 8 9\nIrreducible? Yes Yes Yes Yes No Yes Yes Yes Yes\n------------ ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- -------------------------------------\n:::\n:::\n\n\nFor $n$ = 5, the polynomial factors as the product of $\\langle 1, 0, 0, 1|$ and $\\langle 0, 1, 1|$.\nThe second factor should come as no surprise since we know directly that $0.11_\\rho = 10_\\rho$\n and we already evaluated $10_{\\rho} = 1.\\underline{00001}_\\rho$\n\nChecking more $n$, this polynomial actually seems to be the only reducible one for quite a while.\n\n::: {#3a22f178 .cell freeze='true' execution_count=5}\n``` {.python .cell-code}\nall(is_irreducible(repeating_pair(i)) for i in range(10, 100))\n```\n\n::: {.cell-output .cell-output-display execution_count=5}\n```\nTrue\n```\n:::\n:::\n\n\nThis bestows some level of intrigue upon the repeating expansion of \"11\".\nSince repeating expansions are required for base $\\upsilon$ I will elect to not show the expansion of the integers.\n\n\n### Weird Modulus Patterns\n\nThis can be generalized slightly to match any spacing with any repeating spacing:\n\n$$\n\\begin{gather*}\n 0.\\underbrace{10\\dots01}_m = 1.\\underbrace{\\underline{0\\dots01}}_n\n ~\\Leftrightarrow~\n \\frac{1}{x} + \\frac{1}{x^m} = \\frac{x^n}{x^n - 1}\n \\\\\n x^{m-1} + 1 = \\frac{x^{n+m}}{x^n - 1} \\\\\n \\\\\n x^{n+m-1} + x^n - x^{m-1} - 1 = x^{n+m}\\\\\n x^{n+m} - x^{n+m-1} - x^n + x^{m-1} + 1 = 0 \\\\\n (x^n)(x^m - x^{m-1} - 1) + x^{m-1} + 1 = 0 \\\\\n\\end{gather*}\n$$\n\nIf the polynomial has factors, then fractional systems where those factors are carries have\n repeating expansions of width $n$ for a spacing of width $m$.\nGraphing the tuples of reducible polynomials produces a strange pattern\n apparently arranged in lines (going from the lower left to the upper right):\n\n::: {#b7068ef6 .cell execution_count=6}\n``` {.python .cell-code}\ngeneral_repeats = lambda m, n: (x**n)*(x**m - x**(m-1) - 1) + x**(m-1) + 1\n\nplt.xticks(range(20))\nplt.yticks(range(20))\nplt.xlabel(\"$m - 1$\")\nplt.ylabel(\"$n - 1$\")\nplt.imshow([\n [ is_irreducible(general_repeats(m + 1, n + 1)) for m in range(20) ]\n for n in range(20)\n])\n```\n\n::: {.cell-output .cell-output-display}\n![](index_files/figure-html/cell-7-output-1.png){width=433 height=429}\n:::\n:::\n\n\nThe leftmost purple square is the exception, which corresponds to the earlier $(m, n) = (2, 5)$.\nEvery purple square here is a reducible polynomial, the first few of whose factors are:\n\n\n| $(m, n)$ | Sum | Polynomial Factors\n|----------|-----|-------------------\n| (2, 5) | 7 | $(x^3 - x - 1) (x^4 - x^3 - 1)$\n| (3, 11) | 14 | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{10} - x^8 - x^7 - x^6 - x^5 + x^3 + x^2 + x + 1)$\n| (7, 7) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{10} - x^8 - x^5 + x + 1)$\n| (13, 1) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{10} + x^7 - x^5 - x^2 + 1)$\n| (7, 17) | 24 | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{20} - x^{18} - x^{15} - x^{12} + x^{10} + x^7 - x^5 + x + 1)$\n| (13, 11) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{20} - x^{18} - x^{15} + x^{13} + x^{10} + \\dots + x + 1)$\n| (17, 7) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{20} - x^{18} - x^{15} + x^{13} + x^{12} + \\dots + x + 1)$\n| (17, 17) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{30} - x^{28} - x^{25} + x^{23} + x^{20} - x^{18} - \\dots + x + 1)$\n\nOnly the first entry has factor that is a carry associated to a spacing.\nEvery other entry appears to have $(x^4 - x^3 + x^2 - x + 1)$ as a common factor,\n which is the 10th cyclotomic polynomial.\n\nThese solutions also have sums which increment in tens, which correspond to the\n vertical and horizontal lines of purple squares in the image.\nBoth $m$ and $n$ solutions work in a similar way: the symmetric solution (7, 7)\n has similar solutions (7, 17), (17, 7), and (17, 17).\nThis pattern also holds up in the \"next\" terms (7, 27), (17, 27), (27, 27), (27, 17), and (27, 7).\nIt appears as though there is a congruence of $m + n\\ (\\text{mod } mn)$,\n where m and n come from the exception (2, 5).\nThis pattern is similar to the one in which one in every six spacings can be factored.\n\n\nClosing\n-------\n\nIn summary, the Fibonacci recurrence can be generalized in at least two two different ways.\nIntroducing \"0\"s into the carry is more touch-and-go than would otherwise seem,\n though they produce (with much effort) valid bases.\n\nThe [next post](../4) will explore a more distant cousin of the Fibonacci numbers,\n and other strange power series which arise from its discussion.\n\n", + "markdown": "---\ntitle: \"Polynomial Counting 3: The third degree\"\ndescription: |\n Interesting results on simple irrational counting systems involving only zero and one.\nformat:\n html:\n html-math-method: katex\ndate: \"2021-02-06\"\ndate-modified: \"2025-02-08\"\njupyter: python3\ncategories:\n - algebra\n - phinary\n - binary\n - python\ncode-fold: true\n---\n\n\n\n\n\nThis post assumes you have read the [first](../1) post, which introduces generalized positional counting,\n and the [second](../2), which restricts the focus and specifies the general aim.\n\nThus far, the systems have been based on quadratic polynomials and two-term linear recurrences,\n or more directly, carries of width two.\nNumbers larger than one introduce certain complications to carries.\nWith that in mind, let's go back to things closer to phinary and Fibonacci.\n\n\nTribonacci and Beyond\n---------------------\n\nThe *Tribonacci numbers* ([OEIS A000073](http://oeis.org/A000073)) come from elongating the\n Fibonacci recurrence to 3 terms.\nIn other words, this is the carry/recurrence $\\langle 1,1,1|$.\nThe Tribonacci numbers are seeded with two zeros followed by a single one;\n thus, the sequence begins $0, 0, 1, 1, 2, 4, 7, 13,\\dots$\nThe *Tribonacci constant* is the limiting ratio of these numbers\n (i.e., the positive real root of $x^3 - x^2 - x - 1$) with approximate value $T = 1.8393\\dots$\n\nThe number two bounds both this number and the terms in the recurrence, so its expansion can be deduced:\n\n$$\n\\textcolor{red}{2} = 1.\\textcolor{red}{111}_T = \\textcolor{blue}{1.11}1_T = \\textcolor{blue}{1}0.001_T\n$$\n\nNaturally, the string \"111\" will be illegal in both systems.\nThe Tribonacci expansions of the integers are as follows:\n\n:::: {.row .text-center width=\"60%\"}\n::: {#canonical-tribonacci-table .column}\n\n| *n* (Decimal) | *n* (base $T$) | *n* (Tribonacci) |\n|--------------:|:--------------:|------------------|\n| 0 | 0 | 0 |\n| 1 | 1 | 1 |\n| 2 | 10.001 | 10 |\n| 3 | 11.001 | 11 |\n| 4 | 100.100011 | 100 |\n| 5 | 101.100011 | 101 |\n| 6 | 110.101011 | 110 |\n| 7 | 1000.101011 | 1000 |\n| 8 | 1001.101011 | 1001 |\n| 9 | 1010.110100011 | 1010 |\n| 10 | 1100.010100011 | 1011 |\n\n:::\n::::\n\nSince \"111\" is a rarer string than \"11\", the integral base more closely resembles standard binary.\n\nExtensions of the Fibonacci numbers, which have an $n$-term recurrence\n (seeded with $n - 1$ zeroes followed by a one) are called \"n-nacci\" or \"n-bonacci\" numbers.\nIf we discard the seeding terms, then for larger and larger *n*, this sequence of sequences appears\n to approach the powers of two.\n\n$$\n\\begin{matrix}\n \\text{Fibonacci: } & & & 0,& 1,& 1,& 2,& 3,& 5,& 8\\dots \\\\\n \\text{Tribonacci: } & & 0,& 0,& 1,& 1,& 2,& 4,& 7,& 13\\dots \\\\\n \\text{Tetranacci: } & 0,& 0,& 0,& 1,& 1,& 2,& 4,& 8,& 15\\dots \\\\\n \\vdots \\\\\n \\text{Binary: } & (\\dots,& 0,& 0,& 1,)& 1,& 2,& 4,& 8,& 16\\dots\n\\end{matrix}\n$$\n\nIn the limit, the rightmost and leftmost \"1\"s in the carry $\\langle 1, 1, ..., 1, 1 |$ are\n infinitely far away from each other.\nThis is similar to binary, in which $2 = 1.1111\\dots_2$.\nThis argument is clearer if we directly manipulate the carry as a polynomial $p_n(x)$:\n\n$$\n\\begin{align*}\np_n &= x^n - x^{n-1} - … - x - 1 \\\\\n-p_n &= -x^n + x^{n-1} + … + x + 1 \\\\\nx^n - p_n &= x^{n-1} + … + x + 1 \\\\\nx - p_n x^{-n+1} &= 1 + x^{-1} + … x^{-n+2} + x^{-n+1} \\\\[8pt]\n\\text{Let } n &\\rightarrow \\infty \\\\\nx &= 1 + x^{-1} + x^{-2} + x^{-3} + …\n\\end{align*}\n$$\n\nSince both *φ* and $T$ are greater than 1, we can assume that $x > 1$, which causes the\n $x^{-n+1}$ term to vanish in the limit.\nUnfortunately, this means $p_n$ should diverge, invalidating the above argument.\n\nIgnoring this, the last line can be manipulated as a power series:\n\n$$\n\\begin{align*}\n\\frac{1}{1 - x} &= 1 + x + x^2 + x^3 + \\dots \\\\\n\\frac{1}{1 - (1/x)} &= 1 + x^{-1} + x^{-2} + x^{-3} + \\dots \\\\\nx &= \\frac{1}{1- (1/x)} \\\\\nx - 1 &= 1 \\\\\nx &= 2\n\\end{align*}\n$$\n\nWhich is to imply that, in a non-rigorous sense and by partially assuming the conclusion,\n that the $n$-nacci constants approach two.\n\n\nGolder than Gold\n----------------\n\nAll carries entirely made up of \"1\"s correspond to the $n$-nacci constants.\nWhile this would appear to exhaust every sequence without going to negative numbers,\n it ignores the potential of carries with a \"0\".\n\nStarting simple, Narayana's cows sequence ([OEIS A000930](http://oeis.org/A000930)) corresponds to\n the recurrence $\\langle 1,0,1|$.\nIt may be seeded with either three 1's, or in the same way as above, with a sequence of 0's followed by a 1.\nThe limiting ratio $\\psi \\approx 1.4656\\dots$ is called the supergolden ratio.\nThe introduction of \"0\"s turns out to have big implications, since the concatenation trick to devise\n the expansion of two no longer works.\nHowever, hope is not lost.\n\n$$\n\\begin{gather*}\n 1\\textcolor{red}{1}000_\\psi\n = 10\\textcolor{red}{101}_\\psi\n = \\textcolor{blue}{101}01_\\psi\n = \\textcolor{blue}{1}00001_\\psi \\\\\n \\textcolor{red}{2} = 1.\\textcolor{red}{101}_\\psi\n = \\textcolor{blue}{1.1}01_\\psi\n = \\textcolor{blue}{1}0.001\\textcolor{blue}{1}_\\psi\n = 10.00\\textcolor{purple}{11}_\\psi\n = 10.0\\textcolor{purple}{1}0000\\textcolor{purple}{1}_\\psi\n\\end{gather*}\n$$\n\nIncredibly, the carry contains not only an explicit rule for \"101\", but implicit rules \"2\" and \"11\".\nThis sort of makes sense: since $\\psi < \\varphi$, adjacent place values are \"too dense\",\n and therefore we can rewrite the string \"11\".\nOn the other hand, attempting to manipulate \"1001\" and \"10001\" results in circuiting back to the original string.\n\n$$\n\\begin{split}\n 100\\textcolor{red}{1}000000_\\psi\n &= 1000\\textcolor{red}{101}000_\\psi\n = 1000\\textcolor{orange}{1}01000_\\psi\n = 10000\\textcolor{orange}{1}1\\textcolor{orange}{1}00_\\psi \\\\\n &= 10000\\textcolor{blue}{11}100_\\psi\n = 1000\\textcolor{blue}{1}0010\\textcolor{blue}{1}_\\psi\n = 1000100\\textcolor{red}{101}_\\psi \\\\\n &= 100010\\textcolor{red}{1}000_\\psi\n = 1000\\textcolor{orange}{101}000_\\psi\n = 100\\textcolor{orange}1000000_\\psi \\\\ \\\\\n \\textcolor{red}{1}0001000_\\psi\n &= 0\\textcolor{red}{101}1000_\\psi\n = 010\\textcolor{blue}{11}000_\\psi\n = 01\\textcolor{blue}{1}0000\\textcolor{blue}{1}_\\psi \\\\\n &= 0\\textcolor{purple}{11}00001_\\psi\n = \\textcolor{purple}{1}0000\\textcolor{purple}{1}01_\\psi \\\\\n &= 10000\\textcolor{red}{101}_\\psi = 1000\\textcolor{red}{1}000_\\psi\n\\end{split}\n$$\n\nI call these strings of \"0\"s sandwiched between \"1\"s *spacings*.\nThe smallest spacing, with a width of zero, is the Fibonacci recurrence.\nIf we forbid both the width-1 and width-0 spacings from appearing in supergolden expansions,\n we obtain the following list:\n\n:::: {.row .text-center width=\"60%\"}\n::: {#canonical-supergolden-table .column}\n\n\n\n| *n* (Decimal) | *n* (base $\\psi$) |\n|--------------:|:-------------------:|\n| 0 | 0 |\n| 1 | 1 |\n| 2 | 10.0100001 |\n| 3 | *100.0110001* |\n| 3 | 100.1000100001 |\n| *4* | *110.0001100001* |\n| 4 | 1000.1000100001 |\n| *5* | *1010.0001100001* |\n| 5 | 10000.0010001 |\n| 6 | 10001.0010001 |\n| *7* | *10010.0110002* |\n| *7* | *10010.1000012* |\n| 7 | 100000.0001000001 |\n| 8 | 100001.0001000001 |\n| 9 | 100100.0000001001 |\n| 10 | 1000000.0000001001 |\n\n:::\n::::\n\nIn the above table, some intermediate steps are shown in red,\n but the last entry for each integer is canonical.\nNot only does the number of digits grow radically faster than in phinary (or even binary),\n but there are many more intermediate steps.\n\nFor space reasons, I do not show the integral dual.\nSlowly-growing sequences, which have largely uninteresting integral systems, dominate the rest of this post.\nTherefore, the remainder of this post will focus solely on fractional systems.\n\n\nRadiant Plastic\n---------------\n\nA similar degree 3 recurrence is $\\langle 0,1,1|$.\nIts root corresponds to the plastic ratio $\\rho \\approx 1.3247\\dots$.\nA number of sequences share this recurrence; when seeded with $0, 0, 1$ as before,\n the best match is the Padovan sequence ([OEIS A000931](http://oeis.org/A000931)),\n which begins with an additional one.\n\nSince $\\rho < \\psi < \\varphi$, we should expect that spacings of at least width two are illegal.\nThe system turns out to be even stricter than that: spacings up to and including width three are expandable.\n\n$$\n\\begin{array}{c|c}\n \\text{Width} & \\textcolor{red}{0} & \\textcolor{green}{1} & 2 & \\textcolor{blue}{3} \\\\ \\hline\n & 0\\textcolor{red}{011}_\\rho\n & 010\\textcolor{red}{1}000_\\rho\n & 0\\textcolor{red}{1}00\\textcolor{red}{1}00000_\\rho\n & 0\\textcolor{red}{1}0001_\\rho\n \\\\\n & \\textcolor{red}{1}000_\\rho\n & 0100\\textcolor{red}{011}_\\rho\n & 00\\textcolor{red}{011}\\textcolor{red}{011}00_\\rho\n & 00\\textcolor{red}{011}1_\\rho\n \\\\\n && 0\\textcolor{blue}{10001}1_\\rho\n & 000\\textcolor{blue}{11011}00_\\rho\n & 000\\textcolor{orange}{111}_\\rho\n \\\\\n && \\textcolor{blue}{1}000001_\\rho\n & 00\\textcolor{blue}{1}0101000_\\rho\n & 00\\textcolor{orange}{1}100_\\rho\n \\\\\n &&\n & 0010\\textcolor{green}{101}000_\\rho\n & 0\\textcolor{red}{011}00_\\rho\n \\\\\n &&\n & 001\\textcolor{green}{1000001}_\\rho\n & \\textcolor{red}{1}00000_\\rho\n \\\\\n &&\n & 0\\textcolor{red}{011}000001_\\rho\n \\\\\n &&\n & \\textcolor{red}{1}000000001_\\rho\n \\\\\\\\\n \\hline\n & s_0 = \\rho^2\n & s_1 = \\rho s_{5}\n & s_2 = \\rho s_{8}\n & s_3 = \\rho\n\\end{array}\n$$\n\nThe final line is shorthand for the spacing rules:\n\n- The zero-spacing is equal to a one in the place value two higher than it\n- The one-spacing is equal to an five-spacing which begins one place value higher than it\n- The two-spacing is equal to an eight-spacing which begins one place value higher than it\n- The three-spacing is equal to a one in the place value one higher than it\n\nWith these rules, we can write a canonical expansion expansion for 2:\n\n$$\n\\begin{align*}\n \\textcolor{red}{2}\n &= 1.\\textcolor{red}{011}\n = \\textcolor{blue}{1.011}\n = \\textcolor{blue}{1}\\overbrace{0.0100000}^{8 \\text{ digits}}\\textcolor{blue}{1} \\\\\n &= \\textcolor{purple}{10.01}000001\n = \\textcolor{purple}{1}00.000000\\textcolor{purple}{1}1 \\\\\n &= 100.00000\\textcolor{red}{011}\n = 100.0000\\textcolor{red}{1}\n\\end{align*}\n$$\n\nSince $\\rho < \\sqrt 2$, the largest place value in the expansion of two is $\\rho^2$, which\n distinguishes it from previous systems.\n\nSimilarly to how the width-two and width-three spacings are allowed in the supergolden ratio base,\n we realize that the width-four spacing cannot be expanded further in the plastic ratio base:\n\n$$\n\\begin{align*}\n \\textcolor{red}{1}0000\\textcolor{red}{1}000\n &= 0\\textcolor{red}{011}00\\textcolor{red}{011}\n = 001\\textcolor{blue}{10001}1\n = 00\\textcolor{blue}{2}000001 \\\\\n &= \\textcolor{blue}{1}000000\\textcolor{blue}{1}1\n = 100001000\n\\end{align*}\n$$\n\nWith these implicit rules derived for spacings of width smaller than three,\n the plastic expansions of the integers up to ten are as follows:\n\n:::: {.row .text-center width=\"70%\"}\n::: {#canonical-plastic-table .column}\n\n\n\n| *n* (Decimal) | *n* (base $\\rho$) |\n|--------------:|:----------------------------:|\n| 0 | 0 |\n| 1 | 1 |\n| 2 | 100.00001 |\n| *3* | *101.00001* |\n| *3* | *1000.00101* |\n| 3 | 1000.01000001 |\n| *4* | *10000.0101000000001* |\n| 4 | 10000.1000001000001 |\n| *5* | *10100.0000001000001* |\n| 5 | 100000.1000001000001 |\n| *6* | *100001.1000001000001* |\n| *6* | *100100.0000001000001* |\n| *6* | *1000000.0010001000001* |\n| 6 | 1000000.0100000000001 |\n| *7* | 1000001.0100000000001 |\n| 7 | 1000010.0000100000001 |\n| *8* | *1001000.0000100000001* |\n| *8* | *10000000.0100100000001* |\n| *8* | *10000000.1000000001001* |\n| 8 | 10000000.100000001000000001 |\n| 9 | 10000100.000000001000000001 |\n| 10 | 10001000.001000001000000001 |\n\n:::\n::::\n\nClearly, this base is incredibly sensitive.\nA number as small as 8 has a fractional part as small as $\\rho^{-18}$ in its expansion.\n\n\nSkipped Spacings\n----------------\n\nWhen discussing the expandable spacings in the supergolden and plastic bases, they jumped from\n width one to width three.\nDid we forgot width 2?\nThe strings \"1001\" and \"10001\" are associated to the carries\n $\\langle 1, 0, 0, 1|$ and $\\langle 1, 0, 0, 0, 1|$.\n\n| Spacing Width | Carry | Integral Sequence | Root |\n|---------------|--------------------------------------------|------------------------------------------|---------------------------|\n| 0 | $\\langle 1,1|$ | Fibonacci numbers, Lucas numbers | Golden Ratio, $\\varphi$ |\n| 1 | $\\langle 1,0,1|$ | Narayana's cows sequence | Supergolden Ratio, $\\psi$ |\n| 2 | $\\langle 1,0,0,1|$ | [OEIS A003269](https://oeis.org/A003269) | Unnamed $(\\upsilon?)$ |\n| 3 | $\\langle 1,0,0,0,1| \\simeq \\langle 0,1,1|$ | Padovan sequence, Perrin sequence | Plastic Ratio, $\\rho$ |\n\nI chose the symbol $\\upsilon$ since it came from the second half of the Greek alphabet,\n like the others.\n\nWhile the width-two spacing is a irreducible polynomial like its predecessors,\n the width-three one can be factored\n\n::: {#1d27f169 .cell execution_count=2}\n``` {.python .cell-code}\ndef spacing(width):\n return x**(width + 2) - x**(width + 1) - 1\n\nsympy.Eq(spacing(3), spacing(3).factor())\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=2}\n$\\displaystyle x^{5} - x^{4} - 1 = \\left(x^{2} - x + 1\\right) \\left(x^{3} - x - 1\\right)$\n:::\n:::\n\n\nThis also means that despite $\\rho$ and $\\psi$ being cubic roots,\n $\\upsilon$ is irreducibly a quartic root, despite being between them in terms of spacing width.\n\nThe right polynomial may be familiar from the previous post as $\\langle 1, -1 |$,\n which only has complex roots.\nIt happens to be the sixth cyclotomic polynomial ($\\Phi_6$), and allows the width-three spacing\n to be equivalent to the simpler plastic ratio carry.\n\nAs previously stated, the cyclotomic polynomials cause big trouble for carries.\nOther than factoring, there appears to be no way to derive $\\langle 0,1,1|$ from $\\langle 1,0,0,0,1|$.\nAt best, we can observe the following:\n\n$$\n\\begin{matrix}\n \\langle 1,0,0,0,1| && \\langle 0,1,1| \\\\ \\hline\n 11111 &\\iff& 11111 \\\\\n 101110 && 1000111 \\\\\n 1001100 &\\iff& 1001100 \\\\\n 10001000 && 1100000 \\\\\n 100000000 &\\iff& 100000000 \\\\\n\\end{matrix}\n$$\n\n\n### Chopped Circles\n\nThe appearance of a cyclotomic factor is not unique to the width-three spacing.\nEach of the smaller-width rules in the supergolden and plastic bases can be reexamined as polynomials.\nAfter converting and factoring, their cyclotomic factors become clear:\n\n$$\n\\begin{gather*}\n 11000_\\psi = 100001_\\psi \\\\\n 1\\bar{1}\\bar{1}001_\\psi = 0 \\\\\n \\psi^5 - \\psi^4 - \\psi^3 + 1 \\\\\n (\\psi - 1)(\\psi + 1)(\\psi^3 - \\psi^2 - 1) \\\\\n \\Phi_1 \\Phi_2 \\langle 1,0,1|\n \\\\ \\\\\n \\begin{gather*}\n 101000_\\rho = 1000001_\\rho &\n 100100000_\\rho = 1000000001_\\rho \\\\\n 1\\bar{1}0\\bar{1}001_\\rho = 0 &\n 1\\bar{1}00\\bar{1}00001_\\rho = 0 \\\\\n \\rho^6 - \\rho^5 - \\rho^3 + 1 &\n \\rho^9 - \\rho^8 - \\rho^5 + 1 \\\\\n (\\rho - 1)(\\rho^2 + 1)(\\rho^3 - \\rho - 1) &\n \\dots(\\rho^2 - \\rho + 1)(\\rho^3 - \\rho - 1) \\\\\n \\Phi_1 \\Phi_4 \\langle 0,1,1| &\n \\Phi_1 \\Phi_2 \\Phi_4 \\Phi_6 \\langle 0,1,1|\n \\end{gather*}\n\\end{gather*}\n$$\n\nThough I am uncertain without a proof, it seems that cyclotomic polynomials\n play a role in spacing out \"1\"s.\nThis is to say that spacings have a \"fundamental\" irreducible polynomial.\nBy multiplying certain cyclotomic polynomials by the fundamental, (all?) smaller spacings\n can produce spacings the size of the fundamental or less.\n\nNaturally, I attempted to write a program to compute lesser spacings from an implicit rule.\nGenerally, this entailed assembling all lesser spacings, then expanding the rightmost 1\n if unable to find any spacing, else replacing and continuing.\nUnfortunately, since it operates in lockstep, it gets stuck easily, and I had little success.\nMy Haskell code can be found [here](zero_spacing.hs).\n\n### Inherently Factorable Spacings\n\nThe width-three spacing is not fundamental, since it can be factored.\nWe can collect reducible spacings into a table:\n\n::: {#ad77d9de .cell execution_count=3}\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=3}\n------------ ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- -------------------------------------\n*n*-spacing 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19\nIrreducible? Yes Yes Yes No Yes Yes Yes Yes Yes No Yes Yes Yes Yes Yes No Yes Yes Yes Yes\n------------ ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- -------------------------------------\n:::\n:::\n\n\nIn the range given, this table appears to repeat every six terms.\nWe can examine each of these factors directly:\n\n$$\n\\begin{align*}\n x^5 - x^4 - 1 &= (x^2 - x + 1)\n (x^3 - x - 1) \\\\\n &= 1\\bar{1}1_x * 10\\bar{1}\\bar{1}_x \\\\\n x^{11} - x^{10} - 1 &= (x^2 - x + 1)\n (x^9 - x^7 - x^6 + x^4 + x^3 - x - 1) \\\\\n &= 1\\bar{1}1_x * 10\\bar{1}\\bar{1}0110\\bar{1}\\bar{1}_x \\\\\n x^{17} - x^{16} - 1 &= (x^2 - x + 1)\n (x^{15} - x^{13} - \\dots + x^4 + x^3 - x - 1) \\\\\n &= 1\\bar{1}1_x * 10\\bar{1}\\bar{1}0110\\bar{1}\\bar{1}0110\\bar{1}\\bar{1}_x \\\\\n 5, 11, 17, \\dots &= 6n + 5\n\\end{align*}\n$$\n\nEach of these polynomials has $\\Phi_6$ as a common factor.\nThe other factor appears to be a truncation of the repeating string \"$\\underline{0110\\bar{1}\\bar{1}}$\".\n^[Since I already use the overbar for negative digits, I gather repeating terms using an underline as a vinculum.]\nInterpreted as a power series, this is the reciprocal of $-\\Phi_6$ ([OEIS A010892](https://oeis.org/A010892)).\n\nAs the carry approaches infinite width, the $x$ terms go to 0 for $x < 1$.\nThis shows that like the $n$-nacci constants approach two, the spacing constants approach one.\n\n\nRepeating Expansions\n--------------------\n\nLet's not get too eager here and instead return to base $\\upsilon$.\nIt should be possible to expand the strings \"11\" and \"101\", since it is the fundamental spacing of width 2.\nHowever, we immediately run into an issue:\n\n$$\n\\begin{array}{c|c}\n \\text{Width} & \\textcolor{green}{0} & \\textcolor{blue}{1} & \\textcolor{red}{2} \\\\ \\hline\n & 01\\textcolor{red}{1}00000_\\upsilon\n & 010\\textcolor{red}{1}0000_\\upsilon\n & 0\\textcolor{red}{1001}_\\upsilon\n \\\\\n & 010\\textcolor{red}{1001}0_\\upsilon\n & 0100\\textcolor{red}{1001}_\\upsilon\n & \\textcolor{red}{1}0000_\\upsilon\n \\\\\n & 0\\textcolor{blue}{101}0010_\\upsilon\n & 0\\textcolor{orange}{1001}001_\\upsilon\n \\\\\n & \\textcolor{blue}{1}000001\\textcolor{blue}{1}_\\upsilon\n & \\textcolor{orange}{1}0000001_\\upsilon\n \\\\\n & 100000\\textcolor{green}{11}_\\upsilon \\\\\n & \\vdots \\\\ \\hline\n & s_0 = \\ ? & s_1 = \\rho s_6 & s_2 = \\rho\n\\end{array}\n$$\n\nThe width-0 expansion is recursive.\nIf we continue to apply its rule, we generate the string \"100001\" repeating.\nFortunately, each repeating unit is a width-four spacing, which is allowed by the carry.\n\nRepeating expansions imply a representation by geometric series:\n\n$$\n\\begin{gather*}\n 1.\\underbrace{\\underline{0\\dots1}}_{n}{}_x = 1 + x^{-n} + x^{-2n} + x^{-3n} + \\dots\n = \\frac{1}{1 - (1/x)^n} = \\frac{x^n}{x^n - 1}\n \\\\\n 10 = 1.\\underbrace{\\underline{0\\dots1}}_{n}{}_x ~\\iff~ x = \\frac{x^n}{x^n - 1} \\\\\n 1 = \\frac{x^{n-1}}{x^n - 1} \\\\ \\\\\n x^{n-1} = x^n - 1\n\\end{gather*}\n$$\n\nThe final expression is just the definition of a carry, so we can immediately write:\n\n$$\n\\begin{align*}\n 10_\\varphi &= 1.\\underline{01}_\\varphi & &\n \\text{Carry } \\langle 1,1| \\\\\n 10_\\psi &= 1.\\underline{001}_\\psi & &\n \\text{Carry } \\langle 1,0,1| \\\\\n 10_\\upsilon &= 1.\\underline{0001}_\\upsilon & &\n \\text{Carry } \\langle 1,0,0,1| \\\\\n 10_{\\rho} &= 1.\\underline{00001}_\\rho & &\n \\text{Carry } \\langle 1,0,0,0,1| = \\langle 0,1,1|\n\\end{align*}\n$$\n\nThis neatly ties repeating spacings in with carries.\n^[Recall that when we naively computed ten in base *φ*, we got \"10100.0100101010101010101\".\nAfter a certain point, this expansion alternates between 0 and 1. Assuming that this is true repetition\nand applying $10_\\varphi = 1.\\underline{01}_\\varphi$, one obtains \"10100.0101\", which is canonical. ]\n\nBut we didn't want \"10\" as a repeating expansion, we wanted \"11\".\nAttempting to justify with the same strategy:\n\n$$\n\\begin{align*}\n 0.11_\\upsilon &= 1.\\underline{00001}_\\upsilon & \\text{Carry } \\langle 1,0,0,1|\n \\\\\n \\frac{1}{x} + \\frac{1}{x^2} &= \\frac{x^n}{x^n - 1} \\\\\n x + 1 &= \\frac{x^{n+2}}{x^n - 1}\n \\\\[8pt]\n x^{n+1} + x^n - x - 1 &= x^{n+2} \\\\\n x^{n+2} - x^{n+1} - x^n + x + 1 &= 0 \\\\\n x^n(x^2 - x - 1) + x + 1 &= 0\n\\end{align*}\n$$\n\n::: {#cb467d1a .cell execution_count=4}\n``` {.python .cell-code}\nrepeating_pair = lambda n: (x**n * (x**2 - x - 1) + x + 1).expand().factor()\n\nMarkdown(tabulate(\n zip(*(\n [[\"*n*-repeat\", \"Irreducible?\"]]\n + [[ str(i), display(is_irreducible(repeating_pair(i))) ] for i in range(1, 10)]\n ))\n))\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=4}\n------------ ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- -------------------------------------\n*n*-repeat 1 2 3 4 5 6 7 8 9\nIrreducible? Yes Yes Yes Yes No Yes Yes Yes Yes\n------------ ------------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- ---------------------------------- ------------------------------------- ------------------------------------- ------------------------------------- -------------------------------------\n:::\n:::\n\n\nFor $n = 5$, the polynomial factors as the product of $\\langle 1, 0, 0, 1|$ and $\\langle 0, 1, 1|$.\nThe second factor should come as no surprise since we know directly that $0.11_\\rho = 10_\\rho$\n and we already evaluated $10_{\\rho} = 1.\\underline{00001}_\\rho$\n\nChecking more $n$, this polynomial actually seems to be the only reducible one for quite a while.\n\n::: {#841d895c .cell freeze='true' execution_count=5}\n``` {.python .cell-code code-fold=\"false\"}\nall(is_irreducible(repeating_pair(i)) for i in range(10, 100))\n```\n\n::: {.cell-output .cell-output-display execution_count=5}\n```\nTrue\n```\n:::\n:::\n\n\nThis bestows some level of intrigue upon the repeating expansion of \"11\".\nSince repeating expansions are required for base $\\upsilon$ I will elect to not show the expansion of the integers.\n\n\n### Weird Modulus Patterns\n\nThis can be generalized slightly to match any spacing with any repeating spacing:\n\n$$\n\\begin{gather*}\n 0.\\underbrace{10\\dots01}_m = 1.\\underbrace{\\underline{0\\dots01}}_n\n ~\\Leftrightarrow~\n \\frac{1}{x} + \\frac{1}{x^m} = \\frac{x^n}{x^n - 1}\n \\\\\n x^{m-1} + 1 = \\frac{x^{n+m}}{x^n - 1} \\\\\n \\\\\n x^{n+m-1} + x^n - x^{m-1} - 1 = x^{n+m}\\\\\n x^{n+m} - x^{n+m-1} - x^n + x^{m-1} + 1 = 0 \\\\\n (x^n)(x^m - x^{m-1} - 1) + x^{m-1} + 1 = 0 \\\\\n\\end{gather*}\n$$\n\nIf the polynomial has factors, then fractional systems where those factors are carries have\n repeating expansions of width $n$ for a spacing of width $m$.\nGraphing the tuples of reducible polynomials produces a strange pattern\n apparently arranged in lines (going from the lower left to the upper right):\n\n::: {#2797b56d .cell execution_count=6}\n``` {.python .cell-code}\ngeneral_repeats = lambda m, n: (x**n)*(x**m - x**(m-1) - 1) + x**(m-1) + 1\n\nplt.xticks(range(20))\nplt.yticks(range(20))\nplt.xlabel(\"$m - 1$\")\nplt.ylabel(\"$n - 1$\")\nplt.imshow([\n [ is_irreducible(general_repeats(m + 1, n + 1)) for m in range(20) ]\n for n in range(20)\n])\n```\n\n::: {.cell-output .cell-output-display}\n![](index_files/figure-html/cell-7-output-1.png){width=433 height=429}\n:::\n:::\n\n\nThe leftmost purple square is the exception, which corresponds to the earlier $(m, n) = (2, 5)$.\nEvery purple square here is a reducible polynomial, the first few of whose factors are:\n\n\n| $(m, n)$ | Sum | Polynomial Factors\n|----------|-----|-------------------\n| (2, 5) | 7 | $(x^3 - x - 1) (x^4 - x^3 - 1)$\n| (3, 11) | 14 | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{10} - x^8 - x^7 - x^6 - x^5 + x^3 + x^2 + x + 1)$\n| (7, 7) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{10} - x^8 - x^5 + x + 1)$\n| (13, 1) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{10} + x^7 - x^5 - x^2 + 1)$\n| (7, 17) | 24 | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{20} - x^{18} - x^{15} - x^{12} + x^{10} + x^7 - x^5 + x + 1)$\n| (13, 11) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{20} - x^{18} - x^{15} + x^{13} + x^{10} + \\dots + x + 1)$\n| (17, 7) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{20} - x^{18} - x^{15} + x^{13} + x^{12} + \\dots + x + 1)$\n| (17, 17) | | $(x^4 - x^3 + x^2 - x + 1)$
$(x^{30} - x^{28} - x^{25} + x^{23} + x^{20} - x^{18} - \\dots + x + 1)$\n\nOnly the first entry has factor that is a carry associated to a spacing.\nEvery other entry appears to have $(x^4 - x^3 + x^2 - x + 1)$ as a common factor,\n which is the 10th cyclotomic polynomial.\n\nThese solutions also have sums which increment in tens, which correspond to the\n vertical and horizontal lines of purple squares in the image.\nBoth $m$ and $n$ solutions work in a similar way: the symmetric solution (7, 7)\n has similar solutions (7, 17), (17, 7), and (17, 17).\nThis pattern also holds up in the \"next\" terms (7, 27), (17, 27), (27, 27), (27, 17), and (27, 7).\nIt appears as though there is a congruence of $m + n\\ (\\text{mod } mn)$,\n where m and n come from the exception (2, 5).\nThis pattern is similar to the one in which one in every six spacings can be factored.\n\n\nClosing\n-------\n\nIn summary, the Fibonacci recurrence can be generalized in at least two two different ways.\nIntroducing \"0\"s into the carry is more touch-and-go than would otherwise seem,\n though they produce (with much effort) valid bases.\n\nThe [next post](../4) will explore a more distant cousin of the Fibonacci numbers,\n and other strange power series which arise from its discussion.\n\n", "supporting": [ "index_files" ], diff --git a/_freeze/polycount/5/index/execute-results/html.json b/_freeze/polycount/5/index/execute-results/html.json index 3c4077a..3bfc780 100644 --- a/_freeze/polycount/5/index/execute-results/html.json +++ b/_freeze/polycount/5/index/execute-results/html.json @@ -1,8 +1,8 @@ { - "hash": "75ea07652b53798dee08142061175e2e", + "hash": "b5c0c433960dde69df644a132dc2e115", "result": { "engine": "jupyter", - "markdown": "---\ntitle: \"Polynomial Counting 5: Pentamerous multiplication\"\nformat:\n html:\n html-math-method: katex\ndate: \"2021-02-12\"\ndate-modified: \"2025-2-12\"\njupyter: python3\ncategories:\n - algebra\n - haskell\n---\n\n\n\n\nThis post assumes you have read [the first](../1), which introduces generalized polynomial counting.\n\nOne layer up from counting is arithmetic.\nWe've done a little arithmetic using irrational expansions in pursuit of counting, but maybe we should investigate it a bit.\n\n\nArithmetical Algorithms\n-----------------------\n\nAddition is a fairly simple process for positional systems: align the place values, add each term together,\n then apply the carry as many times as possible.\nWithout a carry rule, this can be approached formally by treating the place values as a sequence\n $b_n$ and gathering terms:\n\n$$\n\\begin{gather*}\n \\phantom{+~} \\overset{b_2}{1} \\overset{b_1}{2} \\overset{b_0}{3} &\n \\phantom{+~} 1b_2 + 2b_1 + 3b_0 \\\\\n \\underline{\n +\\\n \\smash{\n \\overset{\\phantom{b_0}}4\n \\overset{\\phantom{b_0}}5\n \\overset{\\phantom{b_0}}6\n }\n \\vphantom,\n } &\n \\underline{\n +\\\n 4b_2 + 5b_1 + 6b_0 \\vphantom,\n } \\\\\n \\phantom{+~}\n \\smash{\n \\overset{\\phantom{b_0}}5\n \\overset{\\phantom{b_0}}7\n \\overset{\\phantom{b_0}}9\n } &\n \\phantom{+~} 5b_2 + 7b_1 + 9b_0\n\\end{gather*}\n$$\n\nMultiplication is somewhat trickier.\nIts validity follows from the interpretation of an expansion as a polynomial.\nPolynomial multiplication itself is equivalent to\n [*discrete convolution*](https://en.wikipedia.org/wiki/Convolution#Discrete_convolution).\n\n$$\n\\begin{align*}\n &\\begin{matrix}\n \\phantom{\\cdot~}\n 111_x \\\\\n \\underline{\\cdot\\ \\phantom{1}21_x\\vphantom,} \\\\\n \\phantom{\\cdot \\ 0}\n 111_{\\phantom{x}} \\\\\n \\underline{\\phantom{\\cdot\\ } 2220_{\\phantom{x}} \\vphantom,} \\\\\n \\phantom{\\cdot\\ }\n 2331_{\\phantom{x}}\n \\end{matrix}\n &\\qquad&\n \\begin{gather*}\n (x^2 + x + 1)(2x + 1) \\\\ \\\\\n = \\phantom{2x^3 + } \\phantom{2}x^2 + \\phantom{2}x + 1 \\\\\n + \\phantom{.} 2x^3 + 2x^2 + 2x \\phantom{+ 1}\\\\\n = 2x^3 + 3x^2 + 3x + 1\n \\end{gather*}\n &\\qquad&\n \\begin{gather*}\n [1,1,1] * [2,1] \\\\\n \\begin{matrix}\n \\textcolor{blue}0 &\\textcolor{red}1 & \\textcolor{red}1 & \\textcolor{red}1 & \\textcolor{blue}0 &\\\\\n & & &1 & 2 & =~1\\\\\n & & 1 & 2 & &=~3\\\\\n & 1 & 2 & & &=~3\\\\\n 1 & 2 & & & & =~2\n \\end{matrix}\n \\end{gather*}\n\\end{align*}\n$$\n\nThe left equation shows familiar multiplication, the middle equation is the same product when expressed as polynomials,\n and the right equation shows this product obtained by convolution.\nNote that \\[2, 1\\], the second argument, is reversed when performing the convolution.\n\nWithout carrying, multiplication and addition are base-agnostic.\nWhen doing arithmetic in a particular base, we should obtain the same result even if we perform the same operations in another base.\n\n$$\n\\begin{array}{c}\n 18_{10} \\cdot 5_{10} = 10010_2 \\cdot 101_2\n \\\\ \\hline \\\\\n \\begin{gather*}\n &\n \\begin{matrix}\n \\phantom{\\cdot~}\n 18_{10} \\\\\n \\underline{\\cdot\\\n \\phantom{1}5_{10}\\vphantom,} \\\\\n \\phantom{\\cdot~}90_{10} \\\\ \\\\\n =~1011010_2\n \\end{matrix}\n &&\n \\begin{matrix}\n [1,0,0,1,0] * [1,0,1] \\\\ \\\\\n \\begin{matrix}\n \\textcolor{blue}0 & \\textcolor{blue}0 &\\textcolor{red}1 & \\textcolor{red}0 & \\textcolor{red}0\n & \\textcolor{red}1 & \\textcolor{red}0 & \\textcolor{blue}0 & \\textcolor{blue}0 &\\\\\n & & & & & &1 & 0 & 1 & =~0\\\\\n & & & & &1 & 0 & 1 & & =~1\\\\\n & & & &1 & 0 & 1 & & & =~0\\\\\n & & &1 & 0 & 1 & & & & =~1\\\\\n & &1 & 0 & 1 & & & & & =~1\\\\\n & 1 & 0 & 1 & & & & & & =~0\\\\\n 1 & 0 & 1 & & & & & & & =~1\\\\\n \\end{matrix}\n \\end{matrix}\n \\end{gather*}\n\\end{array}\n$$\n\nThis shows that regardless of whether we multiply eighteen and five together in base ten or two,\n we'll get the same string of digits if afterward everything is rendered in the same base.\nFortunately in this instance, we don't have to worry about any carries in the result.\n\n\nTwo Times Tables\n----------------\n\nThe strings \"10010\" and \"101\" do not contain adjacent \"1\"s, so they can also be interpreted as\n Zeckendorf expansions (of ten and four, respectively).\nThis destroys their correspondence to polynomials, so their product by convolution,\n as a Zeckendorf expansion (when returned to canonical form) is not the product of ten and four.\n\n$$\n\\begin{gather*}\n [1,0,0,1,0] * [1,0,1] = 1011010 \\\\\n 10\\textcolor{red}{11}010_{\\text{Zeck}}\n = 1\\textcolor{red}{1}00010_{\\text{Zeck}}\n = \\textcolor{blue}{11}00010_{\\text{Zeck}}\n = \\textcolor{blue}{1}0000010_{\\text{Zeck}} = 36_{10} \\\\\n \\text{Zeck}(10_{10}) * \\text{Zeck}(4_{10})\n = 36_{10} \\neq 40_{10} = 10_{10} \\cdot 4_{10}\n\\end{gather*}\n$$\n\nWe can express this operation for general integers *x* and *y* as\n\n$$\nx \\odot_\\text{Zeck} y = Unzeck(Zeck(x) * Zeck(y))\n$$\n\nwhere \"Zeck\" expands an integer into its Zeckendorf expansion and \"Unzeck\" signifies the process of\n re-interpreting the string as an integer.\nWe can do this because for every integer, a canonical expansion exists.\nFurther, since this operation is defined via convolution (which is commutative), it is also commutative.\n\n::: {#562ef349 .cell execution_count=2}\n``` {.python .cell-code}\nfrom itertools import count, chain, islice, takewhile\nimport numpy as np\n\ndef fibs():\n i = 1\n j = 1\n while True:\n yield i\n t = i + j\n j = i\n i = t\n\ndef zeck(n: int) -> list[int]:\n fibs_ = list(takewhile(lambda x: x <= n, fibs()))[::-1]\n ret = []\n\n for i in fibs_:\n digit, n = divmod(n, i)\n ret.append(digit)\n\n return ret or [0]\n\ndef unzeck(ns: list[int]) -> int:\n return sum(map(lambda x, y: x * y, reversed(ns), fibs()))\n\ndef zeck_times(x: int, y: int) -> int:\n return unzeck(np.convolve(zeck(x), zeck(y), \"full\"))\n```\n:::\n\n\nWe can then build a times table by experimentally multiplying.\nThe expansions for zero and one are invariably the strings \"0\" (or the empty string!) and \"1\".\nWhen a sequence has length one, convolution degenerates to term-by-term multiplication.\nThus, convolution by \"0\" produces a sequence of \"0\"s, and convolution by \"1\" produces the same sequence.\n\nIgnoring those rows, the table is:\n\n::: {#545985aa .cell execution_count=3}\n``` {.python .cell-code code-fold=\"true\"}\nfrom IPython.display import Markdown\nfrom tabulate import tabulate\n\nMarkdown(tabulate(\n [[zeck_times(i, j) for i in range(1, 10)] for j in range(2, 10)],\n headers=[\"$\\\\odot_\\\\text{Zeck}$\", *range(2, 10)]\n))\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=2}\n $\\odot_\\text{Zeck}$ 2 3 4 5 6 7 8 9\n--------------------- --- --- --- --- --- --- --- ---\n 2 3 5 7 8 10 11 13 15\n 3 5 8 11 13 16 18 21 24\n 4 7 11 15 18 22 25 29 33\n 5 8 13 18 21 26 29 34 39\n 6 10 16 22 26 32 36 42 48\n 7 11 18 25 29 36 40 47 54\n 8 13 21 29 34 42 47 55 63\n 9 15 24 33 39 48 54 63 72\n:::\n:::\n\n\nThis resembles a sequence in the OEIS ([A101646](https://oeis.org/A101646)), where it mentions the defining operation\n is sometimes called the \"arroba\" product.\n\n### Correcting for Errors\n\nThe difference between the actual product and the false product can be interpreted as an error endemic to Zeckendorf expansions.\nIf assigned to the symbol $\\oplus_\\text{Zeck}$, then the normal product can be recovered as\n $mn = m \\odot_\\text{Zeck} n + m \\oplus_\\text{Zeck} n$.\n\nWe can then tabulate these errors just like we did our \"products\":\n\n::: {#f5cffcdc .cell execution_count=4}\n``` {.python .cell-code code-fold=\"true\"}\nzeck_error = lambda x, y: x*y - zeck_times(x, y)\n\nMarkdown(tabulate(\n [[j] + [zeck_error(i, j) for i in range(2, 10)] for j in range(2, 10)],\n headers=[\"$\\\\oplus_\\\\text{Zeck}$\", *range(2, 10)]\n))\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=3}\n $\\oplus_\\text{Zeck}$ 2 3 4 5 6 7 8 9\n---------------------- --- --- --- --- --- --- --- ---\n 2 1 1 1 2 2 3 3 3\n 3 1 1 1 2 2 3 3 3\n 4 1 1 1 2 2 3 3 3\n 5 2 2 2 4 4 6 6 6\n 6 2 2 2 4 4 6 6 6\n 7 3 3 3 6 6 9 9 9\n 8 3 3 3 6 6 9 9 9\n 9 3 3 3 6 6 9 9 9\n:::\n:::\n\n\nNotice that the errors seem to be grouped together in rectangular blocks.\nBecause this operation is commutative, the shapes of the rectangles must agree along the main diagonal, where they are squares.\n\n### Fibonacci Runs\n\nThe shape of the rectangular blocks is somewhat odd.\nWe can assess the number of terms the series \"hangs\" before progressing by looking at the\n [*run lengths*](https://en.wikipedia.org/wiki/Run-length_encoding)).\n\n:::: {.row layout-ncol=\"1\"}\n::: {.row}\n\n::: {#b4a13686 .cell execution_count=5}\n``` {.python .cell-code code-fold=\"true\"}\nfrom IPython.display import Math\nfrom typing import Generator\n\ndef run_lengths(xs: Generator) -> Generator:\n last = next(xs)\n run_length = 1\n for i in xs:\n if i != last:\n yield run_length\n last = i\n run_length = 1\n else:\n run_length += 1\n\nshow_trunc_list = lambda xs, n: \"[\" + \", \".join(chain(islice(map(str, xs), n), (\"...\",))) + \"]\"\n\nMath(\n \"RL([i \\\\oplus 2]_{i}) =\"\n + f\"RL({show_trunc_list((zeck_error(i, 2) for i in count(0)), 10)}) =\"\n + show_trunc_list(run_lengths(zeck_error(i, 2) for i in count(0)), 10)\n)\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=4}\n$\\displaystyle RL([i \\oplus 2]_{i}) =RL([0, 0, 1, 1, 1, 2, 2, 3, 3, 3, ...]) =[2, 3, 2, 3, 3, 2, 3, 2, 3, 3, ...]$\n:::\n:::\n\n\n:::\n\n::: {.row}\n\n::: {#c073b4b3 .cell execution_count=6}\n``` {.python .cell-code code-fold=\"true\"}\nMath(\n \"RL([i \\\\oplus 5]_{i}) =\"\n + f\"RL({show_trunc_list((zeck_error(i, 5) for i in count(0)), 10)}) =\"\n + show_trunc_list(run_lengths(zeck_error(i, 2) for i in count(0)), 10)\n)\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=5}\n$\\displaystyle RL([i \\oplus 5]_{i}) =RL([0, 0, 2, 2, 2, 4, 4, 6, 6, 6, ...]) =[2, 3, 2, 3, 3, 2, 3, 2, 3, 3, ...]$\n:::\n:::\n\n\n:::\n\n::: {.row}\n\n::: {#a83206da .cell execution_count=7}\n``` {.python .cell-code code-fold=\"true\"}\nMath(\n \"RL([i \\\\oplus i]_{i}) =\"\n + f\"RL({show_trunc_list((zeck_error(i, i) for i in count(0)), 10)}) =\"\n + show_trunc_list(run_lengths(zeck_error(i, i) for i in count(0)), 10)\n)\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=6}\n$\\displaystyle RL([i \\oplus i]_{i}) =RL([0, 0, 1, 1, 1, 4, 4, 9, 9, 9, ...]) =[2, 3, 2, 3, 3, 2, 3, 2, 3, 3, ...]$\n:::\n:::\n\n\n:::\n::::\n\nThe initial two comes from the errors for $0 \\oplus i$ and $1 \\oplus i$.\nThese rows never have errors, so they can be ignored.\n\nSince the run lengths appear to only be occur in twos and threes, we don't lose any information by converting it\n into, say, ones and zeroes.\nArbitrarily mapping $3 \\mapsto 0,~ 2 \\mapsto 1$, the sequence becomes (truncated to 30 terms):\n\n$$\n0,1,0,0,1,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,...\n$$\n\nThis sequence matches the *Fibonacci word* ([OEIS A3849](http://oeis.org/A003849)).\nThe typical definition of this sequence follows from the a slight modification to that of\n the Fibonacci sequence: rather than starting with two 1s and adding, we start with\n \"0\" and \"1\" (as distinct strings), and concatenate.\n\nPerhaps this is unsurprising, since Zeckendorf expansions are literally strings in Fibonacci numbers.\nHowever, this shows that the errors can be interesting, since it is not obvious that this is the case\n from just looking at the multiplication table.\n\n\nVisualizing Tables\n------------------\n\nWhile it's great that we can build a table, just showing the numbers isn't the best we can do when it comes to visualization.\n\nFor inspiration, I remembered what WolframAlpha does when you ask it for operation tables in finite fields.\nRather than showing you the underlying field elements in a table, it renders\n [a grayscale image](https://www.wolframalpha.com/input?i=finite+field+of+order+25).\n\nI'd like produce something similar in color, but there's a slight problem: we don't have a finite number of elements.\nTo get around this, we'll have to take our tables mod an integer.\nIn the HSV color space, colors are cyclic just like the integers mod *n*.\nThis actually has an additional appealing feature: two colors with similar hues are \"near\" in a similar way to the underlying numbers.\nThen, the entry-to-color mapping can just be given as\n\n$$\nk \\mapsto HSV \\left({2\\pi k \\over n}, 100\\%, 100\\% \\right)\n$$\n\nIn this mapping, for $n = 2$, zero goes to red and one goes to cyan.\nThe following is a 100x100 image of the multiplication table of $\\oplus_\\text{Zeck}$ from 0 to 99.\n\n![](fibonacci_deficiency_mod_2.png)\n\n\n### Anima Moduli\n\nThis table can by animated by gathering various n into an animation and incrementing n every frame.\nBefore applying this technique to an error table, it'd be prudent to apply it to standard addition and multiplication tables first.\n\n::: {.row layout-ncol=\"2\"}\n![\n Addition\n](canonical_tables/canonical_addition.gif){.image-wide}\n\n![\n Multiplication\n](canonical_tables/canonical_multiplication.gif){.image-wide}\n:::\n\nBoth images appear to zoom in as the animation progresses.\nUnsurprisingly, addition produces diagonal stripes, along which the sum is the same.\nMultiplication produces a squarish pattern (with somewhat appealing moirés).\n\nTables for $\\odot_\\text{Zeck}$ and $\\oplus_\\text{Zeck}$ should resemble the table to the right,\n since their definition relies on it.\n\n::: {.row layout-ncol=\"2\"}\n![\n $\\odot_\\text{Zeck}$\n](series_tables/fibonacci_odot.gif){.image-wide}\n\n![\n $\\oplus_\\text{Zeck}$\n](series_tables/fibonacci_oplus.gif){.image-wide}\n:::\n\nIndeed, the zooming is present in both tables.\nAt later frames, both tables share the same \"square rainbow\" pattern, but the error table is closer.\nThough both tables appear to have a repeating pattern, the blocks in the error table are still\n irregularly shaped, as in the mod 2 case.\n\nThe error table also demonstrates (for a given modulus) how much the series differs from a geometric series.\nWe know there will always be an error since, while Fibonacci numbers grow on the order of\n $O(\\varphi^n)$, the ratio between place values is only *φ* in the limit.\n\n\nOther Error Tables\n------------------\n\nThese operations can can also be defined in terms of any other series expansion (i.e., integral system).\nRather than showing both of the multiplication and error tables, I will elect to show only the latter.\nThe error table is more fundamental since the table for $\\odot$ can be constructed from it and the normal multiplication table.\n\nThe error tables for some of the previously-discussed generalizations of the Fibonacci numbers are presented below.\n\n\n### Pell, Jacobsthal\n\n::: {.row layout-ncol=\"2\"}\n![\n Pell ([OEIS A000129](http://oeis.org/A000129))\n $\\langle 2,1|$\n](series_tables/pell_oplus.gif){.image-wide}\n\n![\n Jacobsthal ([OEIS A001045](http://oeis.org/A001045)),\n $\\langle 1,2|$\n](series_tables/jacobsthal_oplus.gif){.image-wide}\n:::\n\nOf the two tables, the Pell table looks more similar to the Fibonacci one.\nMeanwhile, the Jacobsthal table has frames which are significantly redder than the either surrounding it.\nThese occur on frames for which *n* is a power of 2, which is a root of the recurrence polynomial.\n\n\n### *n*-nacci\n\n::: {.row layout-ncol=\"2\"}\n![\n Tribonacci,\n $\\langle 1,1,1|$\n](series_tables/tribonacci_oplus.gif){.image-wide}\n\n![\n Tetranacci,\n $\\langle 1,1,1,1|$\n](series_tables/tetranacci_oplus.gif){.image-wide}\n:::\n\nCompared to the Fibonacci image, the size of the square pattern in the Tribonacci and Tetranacci images is larger.\nHigher orders of Fibonacci recurrences approach binary, so in the limit,\n the pattern disappears, as if the tiny red corner in the upper-left is all that remains.\n\n\n### Other\n\nOf course, integral systems are not limited to linear recurrences, and tables can also be produced\n that correspond to other integer sequences.\nFor example, the factorials produce distinct patterns at certain frames.\nThe Catalan numbers (which are their own recurrence) mod two seem to make a fractal carpet.\nTo prevent the page from getting bloated, these frames are presented in isolation.\n\n\n::: {.row layout-ncol=\"2\"}\n![\n Factorial Error (mod 8)\n](series_tables/factorial_oplus_mod_8.png){.image-wide}\n\n![\n Catalan Numbers Error (mod 2)\n](series_tables/catalan_oplus_mod_2.png){.image-wide}\n:::\n\n\nAdditional tables which I find interesting are:\n\n- [\n Triangular Numbers (recurrence $\\langle 3, \\bar{3}, 1|$)\n](series_tables/triangular_oplus.gif){target=\"_blank_\"}\n- [\n Square Numbers\n](series_tables/square_oplus.gif){target=\"_blank_\"}\n- [\n Padovan Numbers (recurrence $\\langle 0,1,1|$)\n](series_tables/padovan_oplus.gif){target=\"_blank_\"}\n- [\n $\\langle 1, 1, 2|$, based on the first 3 Catalan numbers\n](series_tables/recurrence_1_1_2_oplus.gif){target=\"_blank_\"}\n\n\nClosing\n-------\n\nEven if not particularly useful, I enjoy the emergent behavior apparent in the tables.\nEven for typical multiplication, this visualization technique shows regular patterns which appear to \"grow\".\nMeanwhile, the sequence products frequently produce a pattern that either repeats, or is composed of many similar elements.\n\nThe project that I used to render the images can be found [here](https://github.com/queue-miscreant/SeriesDeficient).\nI didn't put much thought into command line arguments, nor did I build in many features.\nAs an executable, it should be completely serviceable to generate error tables based on recurrence relations;\n the GHCi REPL can be used for more sophisticated sequences.\n\n\n### Bad Visualization\n\nMy first attempt to map integers to colors was to consider its prime factorization.\nThe largest number in the factorization was related to the hue, and the number of terms in the factorization\n was related to the saturation.\nResults were not great.\n\n![ ](fibonacci_old_bad.png)\n\n\n### Bad Filesizes\n\nWhile I rendered these animations as GIFs, I also attempted to convert some of them to MP4s in hopes of shrinking the filesize.\nHowever, this is a use case where the MP4 is larger than the GIF, at least without compromising on resolution.\nThis is a case when space-compression beats ill-suited time-compression.\n\n![Produced with ffmpeg defaults](gif_mp4_size_comparison.png)\n\n", + "markdown": "---\ntitle: \"Polynomial Counting 5: Pentamerous multiplication\"\ndescription: |\n Arithmetic in non-geometric integral systems and surprisingly regular errors therein.\nformat:\n html:\n html-math-method: katex\ndate: \"2021-02-12\"\ndate-modified: \"2025-02-12\"\njupyter: python3\ncategories:\n - algebra\n - python\n---\n\n\n\n\nThis post assumes you have read [the first](../1), which introduces generalized polynomial counting.\n\nOne layer up from counting is arithmetic.\nWe've done a little arithmetic using irrational expansions in pursuit of counting, but maybe we should investigate it a bit.\n\n\nArithmetical Algorithms\n-----------------------\n\nAddition is a fairly simple process for positional systems: align the place values, add each term together,\n then apply the carry as many times as possible.\nWithout a carry rule, this can be approached formally by treating the place values as a sequence\n $b_n$ and gathering terms:\n\n$$\n\\begin{gather*}\n \\phantom{+~} \\overset{b_2}{1} \\overset{b_1}{2} \\overset{b_0}{3} &\n \\phantom{+~} 1b_2 + 2b_1 + 3b_0 \\\\\n \\underline{\n +\\\n \\smash{\n \\overset{\\phantom{b_0}}4\n \\overset{\\phantom{b_0}}5\n \\overset{\\phantom{b_0}}6\n }\n \\vphantom,\n } &\n \\underline{\n +\\\n 4b_2 + 5b_1 + 6b_0 \\vphantom,\n } \\\\\n \\phantom{+~}\n \\smash{\n \\overset{\\phantom{b_0}}5\n \\overset{\\phantom{b_0}}7\n \\overset{\\phantom{b_0}}9\n } &\n \\phantom{+~} 5b_2 + 7b_1 + 9b_0\n\\end{gather*}\n$$\n\nMultiplication is somewhat trickier.\nIts validity follows from the interpretation of an expansion as a polynomial.\nPolynomial multiplication itself is equivalent to\n [*discrete convolution*](https://en.wikipedia.org/wiki/Convolution#Discrete_convolution).\n\n$$\n\\begin{align*}\n &\\begin{matrix}\n \\phantom{\\cdot~}\n 111_x \\\\\n \\underline{\\cdot\\ \\phantom{1}21_x\\vphantom,} \\\\\n \\phantom{\\cdot \\ 0}\n 111_{\\phantom{x}} \\\\\n \\underline{\\phantom{\\cdot\\ } 2220_{\\phantom{x}} \\vphantom,} \\\\\n \\phantom{\\cdot\\ }\n 2331_{\\phantom{x}}\n \\end{matrix}\n &\\qquad&\n \\begin{gather*}\n (x^2 + x + 1)(2x + 1) \\\\ \\\\\n = \\phantom{2x^3 + } \\phantom{2}x^2 + \\phantom{2}x + 1 \\\\\n + \\phantom{.} 2x^3 + 2x^2 + 2x \\phantom{+ 1}\\\\\n = 2x^3 + 3x^2 + 3x + 1\n \\end{gather*}\n &\\qquad&\n \\begin{gather*}\n [1,1,1] * [2,1] \\\\\n \\begin{matrix}\n \\textcolor{blue}0 &\\textcolor{red}1 & \\textcolor{red}1 & \\textcolor{red}1 & \\textcolor{blue}0 &\\\\\n & & &1 & 2 & =~1\\\\\n & & 1 & 2 & &=~3\\\\\n & 1 & 2 & & &=~3\\\\\n 1 & 2 & & & & =~2\n \\end{matrix}\n \\end{gather*}\n\\end{align*}\n$$\n\nThe left equation shows familiar multiplication, the middle equation is the same product when expressed as polynomials,\n and the right equation shows this product obtained by convolution.\nNote that \\[2, 1\\], the second argument, is reversed when performing the convolution.\n\nWithout carrying, multiplication and addition are base-agnostic.\nWhen doing arithmetic in a particular base, we should obtain the same result even if we perform the same operations in another base.\n\n$$\n\\begin{array}{c}\n 18_{10} \\cdot 5_{10} = 10010_2 \\cdot 101_2\n \\\\ \\hline \\\\\n \\begin{gather*}\n &\n \\begin{matrix}\n \\phantom{\\cdot~}\n 18_{10} \\\\\n \\underline{\\cdot\\\n \\phantom{1}5_{10}\\vphantom,} \\\\\n \\phantom{\\cdot~}90_{10} \\\\ \\\\\n =~1011010_2\n \\end{matrix}\n &&\n \\begin{matrix}\n [1,0,0,1,0] * [1,0,1] \\\\ \\\\\n \\begin{matrix}\n \\textcolor{blue}0 & \\textcolor{blue}0 &\\textcolor{red}1 & \\textcolor{red}0 & \\textcolor{red}0\n & \\textcolor{red}1 & \\textcolor{red}0 & \\textcolor{blue}0 & \\textcolor{blue}0 &\\\\\n & & & & & &1 & 0 & 1 & =~0\\\\\n & & & & &1 & 0 & 1 & & =~1\\\\\n & & & &1 & 0 & 1 & & & =~0\\\\\n & & &1 & 0 & 1 & & & & =~1\\\\\n & &1 & 0 & 1 & & & & & =~1\\\\\n & 1 & 0 & 1 & & & & & & =~0\\\\\n 1 & 0 & 1 & & & & & & & =~1\\\\\n \\end{matrix}\n \\end{matrix}\n \\end{gather*}\n\\end{array}\n$$\n\nThis shows that regardless of whether we multiply eighteen and five together in base ten or two,\n we'll get the same string of digits if afterward everything is rendered in the same base.\nFortunately in this instance, we don't have to worry about any carries in the result.\n\n\nTwo Times Tables\n----------------\n\nThe strings \"10010\" and \"101\" do not contain adjacent \"1\"s, so they can also be interpreted as\n Zeckendorf expansions (of ten and four, respectively).\nThis destroys their correspondence to polynomials, so their product by convolution,\n as a Zeckendorf expansion (when returned to canonical form) is not the product of ten and four.\n\n$$\n\\begin{gather*}\n [1,0,0,1,0] * [1,0,1] = 1011010 \\\\\n 10\\textcolor{red}{11}010_{\\text{Zeck}}\n = 1\\textcolor{red}{1}00010_{\\text{Zeck}}\n = \\textcolor{blue}{11}00010_{\\text{Zeck}}\n = \\textcolor{blue}{1}0000010_{\\text{Zeck}} = 36_{10} \\\\\n \\text{Zeck}(10_{10}) * \\text{Zeck}(4_{10})\n = 36_{10} \\neq 40_{10} = 10_{10} \\cdot 4_{10}\n\\end{gather*}\n$$\n\nWe can express this operation for general integers *x* and *y* as\n\n$$\nx \\odot_\\text{Zeck} y = \\text{Unzeck}(\\text{Zeck}(x) * \\text{Zeck}(y))\n$$\n\nwhere \"Zeck\" expands an integer into its Zeckendorf expansion and \"Unzeck\" signifies the process of\n re-interpreting the string as an integer.\nWe can do this because for every integer, a canonical expansion exists.\nFurther, since this operation is defined via convolution (which is commutative), it is also commutative.\n\n::: {#b8ef4db4 .cell execution_count=2}\n``` {.python .cell-code}\nfrom itertools import count, chain, islice, takewhile\nimport numpy as np\n\ndef fibs():\n i = 1\n j = 1\n while True:\n yield i\n t = i + j\n j = i\n i = t\n\ndef zeck(n: int) -> list[int]:\n fibs_ = list(takewhile(lambda x: x <= n, fibs()))[::-1]\n ret = []\n\n for i in fibs_:\n digit, n = divmod(n, i)\n ret.append(digit)\n\n return ret or [0]\n\ndef unzeck(ns: list[int]) -> int:\n return sum(map(lambda x, y: x * y, reversed(ns), fibs()))\n\ndef zeck_times(x: int, y: int) -> int:\n return unzeck(np.convolve(zeck(x), zeck(y), \"full\"))\n```\n:::\n\n\nWe can then build a times table by experimentally multiplying.\nThe expansions for zero and one are invariably the strings \"0\" (or the empty string!) and \"1\".\nWhen a sequence has length one, convolution degenerates to term-by-term multiplication.\nThus, convolution by \"0\" produces a sequence of \"0\"s, and convolution by \"1\" produces the same sequence.\n\nIgnoring those rows, the table is:\n\n::: {#d9950667 .cell execution_count=3}\n``` {.python .cell-code code-fold=\"true\"}\nfrom IPython.display import Markdown\nfrom tabulate import tabulate\n\nMarkdown(tabulate(\n [[zeck_times(i, j) for i in range(1, 10)] for j in range(2, 10)],\n headers=[\"$\\\\odot_\\\\text{Zeck}$\", *range(2, 10)]\n))\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=2}\n $\\odot_\\text{Zeck}$ 2 3 4 5 6 7 8 9\n--------------------- --- --- --- --- --- --- --- ---\n 2 3 5 7 8 10 11 13 15\n 3 5 8 11 13 16 18 21 24\n 4 7 11 15 18 22 25 29 33\n 5 8 13 18 21 26 29 34 39\n 6 10 16 22 26 32 36 42 48\n 7 11 18 25 29 36 40 47 54\n 8 13 21 29 34 42 47 55 63\n 9 15 24 33 39 48 54 63 72\n:::\n:::\n\n\nThis resembles a sequence in the OEIS ([A101646](https://oeis.org/A101646)), where it mentions the defining operation\n is sometimes called the \"arroba\" product.\n\n### Correcting for Errors\n\nThe difference between the actual product and the false product can be interpreted as an error endemic to Zeckendorf expansions.\nIf assigned to the symbol $\\oplus_\\text{Zeck}$, then the normal product can be recovered as\n $mn = m \\odot_\\text{Zeck} n + m \\oplus_\\text{Zeck} n$.\n\nWe can then tabulate these errors just like we did our \"products\":\n\n::: {#fd9df7ee .cell execution_count=4}\n``` {.python .cell-code code-fold=\"true\"}\nzeck_error = lambda x, y: x*y - zeck_times(x, y)\n\nMarkdown(tabulate(\n [[j] + [zeck_error(i, j) for i in range(2, 10)] for j in range(2, 10)],\n headers=[\"$\\\\oplus_\\\\text{Zeck}$\", *range(2, 10)]\n))\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=3}\n $\\oplus_\\text{Zeck}$ 2 3 4 5 6 7 8 9\n---------------------- --- --- --- --- --- --- --- ---\n 2 1 1 1 2 2 3 3 3\n 3 1 1 1 2 2 3 3 3\n 4 1 1 1 2 2 3 3 3\n 5 2 2 2 4 4 6 6 6\n 6 2 2 2 4 4 6 6 6\n 7 3 3 3 6 6 9 9 9\n 8 3 3 3 6 6 9 9 9\n 9 3 3 3 6 6 9 9 9\n:::\n:::\n\n\nNotice that the errors seem to be grouped together in rectangular blocks.\nBecause this operation is commutative, the shapes of the rectangles must agree along the main diagonal, where they are squares.\n\n### Fibonacci Runs\n\nThe shape of the rectangular blocks is somewhat odd.\nWe can assess the number of terms the series \"hangs\" before progressing by looking at the\n [*run lengths*](https://en.wikipedia.org/wiki/Run-length_encoding).\n\n:::: {.row layout-ncol=\"1\"}\n::: {.row}\n\n::: {#b1eeb2e4 .cell execution_count=5}\n``` {.python .cell-code code-fold=\"true\"}\nfrom IPython.display import Math\nfrom typing import Generator\n\ndef run_lengths(xs: Generator) -> Generator:\n last = next(xs)\n run_length = 1\n for i in xs:\n if i != last:\n yield run_length\n last = i\n run_length = 1\n else:\n run_length += 1\n\nshow_trunc_list = lambda xs, n: \"[\" + \", \".join(chain(islice(map(str, xs), n), (\"...\",))) + \"]\"\n\nMath(\n \"RL([i \\\\oplus 2]_{i}) =\"\n + f\"RL({show_trunc_list((zeck_error(i, 2) for i in count(0)), 10)}) =\"\n + show_trunc_list(run_lengths(zeck_error(i, 2) for i in count(0)), 10)\n)\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=4}\n$\\displaystyle RL([i \\oplus 2]_{i}) =RL([0, 0, 1, 1, 1, 2, 2, 3, 3, 3, ...]) =[2, 3, 2, 3, 3, 2, 3, 2, 3, 3, ...]$\n:::\n:::\n\n\n:::\n\n::: {.row}\n\n::: {#f187fea7 .cell execution_count=6}\n``` {.python .cell-code code-fold=\"true\"}\nMath(\n \"RL([i \\\\oplus 5]_{i}) =\"\n + f\"RL({show_trunc_list((zeck_error(i, 5) for i in count(0)), 10)}) =\"\n + show_trunc_list(run_lengths(zeck_error(i, 2) for i in count(0)), 10)\n)\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=5}\n$\\displaystyle RL([i \\oplus 5]_{i}) =RL([0, 0, 2, 2, 2, 4, 4, 6, 6, 6, ...]) =[2, 3, 2, 3, 3, 2, 3, 2, 3, 3, ...]$\n:::\n:::\n\n\n:::\n\n::: {.row}\n\n::: {#b1831819 .cell execution_count=7}\n``` {.python .cell-code code-fold=\"true\"}\nMath(\n \"RL([i \\\\oplus i]_{i}) =\"\n + f\"RL({show_trunc_list((zeck_error(i, i) for i in count(0)), 10)}) =\"\n + show_trunc_list(run_lengths(zeck_error(i, i) for i in count(0)), 10)\n)\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown execution_count=6}\n$\\displaystyle RL([i \\oplus i]_{i}) =RL([0, 0, 1, 1, 1, 4, 4, 9, 9, 9, ...]) =[2, 3, 2, 3, 3, 2, 3, 2, 3, 3, ...]$\n:::\n:::\n\n\n:::\n::::\n\nThe initial two comes from the errors for $0 \\oplus i$ and $1 \\oplus i$.\nThese rows never have errors, so they can be ignored.\n\nSince the run lengths appear to only be occur in twos and threes, we don't lose any information by converting it\n into, say, ones and zeroes.\nArbitrarily mapping $3 \\mapsto 0,~ 2 \\mapsto 1$, the sequence becomes (truncated to 30 terms):\n\n$$\n0,1,0,0,1,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,...\n$$\n\nThis sequence matches the *Fibonacci word* ([OEIS A3849](http://oeis.org/A003849)).\nThe typical definition of this sequence follows from the a slight modification to that of\n the Fibonacci sequence: rather than starting with two 1s and adding, we start with\n \"0\" and \"1\" (as distinct strings), and concatenate.\n\nPerhaps this is unsurprising, since Zeckendorf expansions are literally strings in Fibonacci numbers.\nHowever, this shows that the errors can be interesting, since it is not obvious that this is the case\n from just looking at the multiplication table.\n\n\nVisualizing Tables\n------------------\n\nWhile it's great that we can build a table, just showing the numbers isn't the best we can do when it comes to visualization.\n\nFor inspiration, I remembered what WolframAlpha does when you ask it for operation tables in finite fields.\nRather than showing you the underlying field elements in a table, it renders\n [a grayscale image](https://www.wolframalpha.com/input?i=finite+field+of+order+25).\n\nI'd like produce something similar in color, but there's a slight problem: we don't have a finite number of elements.\nTo get around this, we'll have to take our tables mod an integer.\nIn the HSV color space, colors are cyclic just like the integers mod *n*.\nThis actually has an additional appealing feature: two colors with similar hues are \"near\" in a similar way to the underlying numbers.\nThen, the entry-to-color mapping can just be given as\n\n$$\nk \\mapsto HSV \\left({2\\pi k \\over n}, 100\\%, 100\\% \\right)\n$$\n\nIn this mapping, for $n = 2$, zero goes to red and one goes to cyan.\nThe following is a 100x100 image of the multiplication table of $\\oplus_\\text{Zeck}$ from zero to ninety-nine.\n\n![\n  \n](fibonacci_deficiency_mod_2.png){.image-wide}\n\n\n### Anima Moduli\n\nThis table can by animated by gathering various n into an animation and incrementing n every frame.\nBefore applying this technique to an error table, it'd be prudent to apply it to standard addition and multiplication tables first.\n\n::: {.row layout-ncol=\"2\"}\n![\n Addition\n](canonical_tables/canonical_addition.gif){.image-wide}\n\n![\n Multiplication\n](canonical_tables/canonical_multiplication.gif){.image-wide}\n:::\n\nBoth images appear to zoom in as the animation progresses.\nUnsurprisingly, addition produces diagonal stripes, along which the sum is the same.\nMultiplication produces a squarish pattern (with somewhat appealing moirés).\n\nTables for $\\odot_\\text{Zeck}$ and $\\oplus_\\text{Zeck}$ should resemble the table to the right,\n since their definition relies on it.\n\n::: {.row layout-ncol=\"2\"}\n![\n $\\odot_\\text{Zeck}$\n](series_tables/fibonacci_odot.gif){.image-wide}\n\n![\n $\\oplus_\\text{Zeck}$\n](series_tables/fibonacci_oplus.gif){.image-wide}\n:::\n\nIndeed, the zooming is present in both tables.\nAt later frames, both tables share the same \"square rainbow\" pattern, but the error table is closer.\nThough both tables appear to have a repeating pattern, the blocks in the error table are still\n irregularly shaped, as in the mod 2 case.\n\nThe error table also demonstrates (for a given modulus) how much the series differs from a geometric series.\nWe know there will always be an error since, while Fibonacci numbers grow on the order of\n $O(\\varphi^n)$, the ratio between place values is only *φ* in the limit.\n\n\nOther Error Tables\n------------------\n\nThese operations can can also be defined in terms of any other series expansion (i.e., integral system).\nRather than showing both of the multiplication and error tables, I will elect to show only the latter.\nThe error table is more fundamental since the table for $\\odot$ can be constructed from it and the normal multiplication table.\n\nThe error tables for some of the previously-discussed generalizations of the Fibonacci numbers are presented below.\n\n\n### Pell, Jacobsthal\n\n::: {.row layout-ncol=\"2\"}\n![\n Pell ([OEIS A000129](http://oeis.org/A000129))\n $\\langle 2,1|$\n](series_tables/pell_oplus.gif){.image-wide}\n\n![\n Jacobsthal ([OEIS A001045](http://oeis.org/A001045)),\n $\\langle 1,2|$\n](series_tables/jacobsthal_oplus.gif){.image-wide}\n:::\n\nOf the two tables, the Pell table looks more similar to the Fibonacci one.\nMeanwhile, the Jacobsthal table has frames which are significantly redder than the either surrounding it.\nThese occur on frames for which *n* is a power of 2, which is a root of the recurrence polynomial.\n\n\n### *n*-nacci\n\n::: {.row layout-ncol=\"2\"}\n![\n Tribonacci,\n $\\langle 1,1,1|$\n](series_tables/tribonacci_oplus.gif){.image-wide}\n\n![\n Tetranacci,\n $\\langle 1,1,1,1|$\n](series_tables/tetranacci_oplus.gif){.image-wide}\n:::\n\nCompared to the Fibonacci image, the size of the square pattern in the Tribonacci and Tetranacci images is larger.\nHigher orders of Fibonacci recurrences approach binary, so in the limit,\n the pattern disappears, as if the tiny red corner in the upper-left is all that remains.\n\n\n### Other\n\nOf course, integral systems are not limited to linear recurrences, and tables can also be produced\n that correspond to other integer sequences.\nFor example, the factorials produce distinct patterns at certain frames.\nThe Catalan numbers (which are their own recurrence) mod two seem to make a fractal carpet.\nTo prevent the page from getting bloated, these frames are presented in isolation.\n\n\n::: {.row layout-ncol=\"2\"}\n![\n Factorial Error (mod 8)\n](series_tables/factorial_oplus_mod_8.png){.image-wide}\n\n![\n Catalan Numbers Error (mod 2)\n](series_tables/catalan_oplus_mod_2.png){.image-wide}\n:::\n\n\nAdditional tables which I find interesting are:\n\n- [\n Triangular Numbers (recurrence $\\langle 3, \\bar{3}, 1|$)\n](series_tables/triangular_oplus.gif){target=\"_blank_\"}\n- [\n Square Numbers\n](series_tables/square_oplus.gif){target=\"_blank_\"}\n- [\n Padovan Numbers (recurrence $\\langle 0,1,1|$)\n](series_tables/padovan_oplus.gif){target=\"_blank_\"}\n- [\n $\\langle 1, 1, 2|$, based on the first 3 Catalan numbers\n](series_tables/recurrence_1_1_2_oplus.gif){target=\"_blank_\"}\n\n\nClosing\n-------\n\nEven if not particularly useful, I enjoy the emergent behavior apparent in the tables.\nEven for typical multiplication, this visualization technique shows regular patterns which appear to \"grow\".\nMeanwhile, the sequence products frequently produce a pattern that either repeats, or is composed of many similar elements.\n\nThe project that I used to render the images can be found [here](https://github.com/queue-miscreant/SeriesDeficient).\nI didn't put much thought into command line arguments, nor did I build in many features.\nAs an executable, it should be completely serviceable to generate error tables based on recurrence relations;\n the GHCi REPL can be used for more sophisticated sequences.\n\n\n### Bad Visualization\n\nMy first attempt to map integers to colors was to consider its prime factorization.\nThe largest number in the factorization was related to the hue, and the number of terms in the factorization\n was related to the saturation.\nResults were not great.\n\n![ ](fibonacci_old_bad.png)\n\n\n### Bad Filesizes\n\nWhile I rendered these animations as GIFs, I also attempted to convert some of them to MP4s in hopes of shrinking the filesize.\nHowever, this is a use case where the MP4 is larger than the GIF, at least without compromising on resolution.\nThis is a case when space-compression beats ill-suited time-compression.\n\n![Produced with ffmpeg defaults](gif_mp4_size_comparison.png)\n\n", "supporting": [ "index_files" ], diff --git a/polycount/3/index.qmd b/polycount/3/index.qmd index 375ae72..aeed4ab 100644 --- a/polycount/3/index.qmd +++ b/polycount/3/index.qmd @@ -13,10 +13,22 @@ categories: - phinary - binary - python -execute: - code-fold: true +code-fold: true --- + + ```{python} #| echo: false @@ -581,7 +593,7 @@ $$ $$ This neatly ties repeating spacings in with carries. -^[Recall that when we naively computed ten in base phi, we got "10100.0100101010101010101". +^[Recall that when we naively computed ten in base *φ*, we got "10100.0100101010101010101". After a certain point, this expansion alternates between 0 and 1. Assuming that this is true repetition and applying $10_\varphi = 1.\underline{01}_\varphi$, one obtains "10100.0101", which is canonical. ] diff --git a/polycount/4/index.qmd b/polycount/4/index.qmd index eabcdc2..4a3c5a2 100644 --- a/polycount/4/index.qmd +++ b/polycount/4/index.qmd @@ -446,7 +446,7 @@ Unfortunately, this is not the case. All of the expansions above are identically four, and manipulating the digits directly would just give a different number. -Instead, we could try representing "4" in a more direct manner +Instead, we could try representing "4" in a more direct manner. There are a few other options available. - Add the nonrepeating part of the mixed balanced expansion of 4 with the @@ -615,7 +615,7 @@ plt.title("DFT of $4_{\\kappa}$ after mapping $\\bar{1}$ to $1$") plt.plot(abs(np.fft.fft([abs(i) for i in cendree_adic_4[:256]]))[:129]) ``` -If you look closely, you'll notice that this plot is a mirror of the other. +If you look closely, you can notice that this plot is a mirror of the other. ### Longer Truncations @@ -677,7 +677,7 @@ The [next post](../5) will return to integral sequences, and the patterns produc Recall that $3 = 10.02_{\kappa}$ and $4 = 11.02_{\kappa}$. - We can add two expansion together to produce a new valid expansion. + We can add two expansions together to produce a new valid expansion. Hence, :::: {.row layout-ncol="2"} diff --git a/polycount/5/index.qmd b/polycount/5/index.qmd index 414ea4d..be5af00 100644 --- a/polycount/5/index.qmd +++ b/polycount/5/index.qmd @@ -266,7 +266,7 @@ Because this operation is commutative, the shapes of the rectangles must agree a The shape of the rectangular blocks is somewhat odd. We can assess the number of terms the series "hangs" before progressing by looking at the - [*run lengths*](https://en.wikipedia.org/wiki/Run-length_encoding)). + [*run lengths*](https://en.wikipedia.org/wiki/Run-length_encoding). :::: {.row layout-ncol="1"} ::: {.row} @@ -365,7 +365,9 @@ $$ In this mapping, for $n = 2$, zero goes to red and one goes to cyan. The following is a 100x100 image of the multiplication table of $\oplus_\text{Zeck}$ from zero to ninety-nine. -![](fibonacci_deficiency_mod_2.png){.image-wide} +![ +   +](fibonacci_deficiency_mod_2.png){.image-wide} ### Anima Moduli