revisions for 4.appendix
This commit is contained in:
parent
e5946df6ec
commit
fd57fa066e
@ -1,90 +1,169 @@
|
|||||||
---
|
---
|
||||||
title: "Polynomial Counting 4, Addendum"
|
title: "Polynomial Counting 4, Addendum"
|
||||||
description: |
|
description: |
|
||||||
Complex embeddings of irrational -adic expansions.
|
Additional notes on irrational -adic expansions, including complex embeddings thereof.
|
||||||
format:
|
format:
|
||||||
html:
|
html:
|
||||||
html-math-method: katex
|
html-math-method: katex
|
||||||
date: "2021-02-09"
|
date: "2025-03-03"
|
||||||
date-modified: "2025-02-12"
|
|
||||||
categories:
|
categories:
|
||||||
- algebra
|
- algebra
|
||||||
- haskell
|
- haskell
|
||||||
- interactive
|
- interactive
|
||||||
execute:
|
|
||||||
eval: false
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
-- | echo: false
|
||||||
|
|
||||||
After converting my original [Two 2's post](../), I found myself much more pleased after making the
|
import IHaskell.Display
|
||||||
diagrams it more reproducible.
|
```
|
||||||
|
|
||||||
|
After converting my original [Two 2's post](../), I grew pleased with making its diagrams
|
||||||
|
and content more reproducible.
|
||||||
However, I noticed some things which required further examination.
|
However, I noticed some things which required further examination.
|
||||||
|
|
||||||
|
First, let's write out a double-width carry function more concretely in Haskell.
|
||||||
|
|
||||||
Balanced vs. Binary *κ*-adics
|
```{haskell}
|
||||||
-----------------------------
|
-- | echo: true
|
||||||
|
|
||||||
|
-- Widened carry of a particular repeated amount
|
||||||
|
-- i.e., for carry2 2, the carry is 22 = 100
|
||||||
|
carry2 b = carry2' []
|
||||||
|
where carry2' zs (x:y:z:xs)
|
||||||
|
| q == 0 = carry2' (x:zs) (y:z:xs) -- try carrying at a higher place value
|
||||||
|
| otherwise = foldl (flip (:)) ys zs -- carry here
|
||||||
|
where ys = r : y-x+r : z+q : xs
|
||||||
|
(q, r) = x `quotRem` b
|
||||||
|
```
|
||||||
|
|
||||||
In the parent post, it was discussed that the integer four has a non-repeating expansion
|
In the parent post, it was discussed that the integer four has a non-repeating expansion
|
||||||
when expressed as an *κ*-adic integer.
|
when expressed as an *κ*-adic integer.
|
||||||
It followed in multiple ways from the repeating expansion of the integer two in the balanced ternary alphabet.
|
Let's put this to the test by writing out each step for producing expansions of two and four.
|
||||||
A more unusual consequence of this is that despite the initial choice of alphabet,
|
We'll also test these expansions by evaluating them at an approximation of $\kappa = \sqrt 3 + 1$.
|
||||||
[negative numerals could be cleared](../#all-positive)
|
We should roughly get two and four at each step.
|
||||||
from the expansion by using an extra-greedy borrow.
|
|
||||||
|
|
||||||
There is only one significant difference in how the two are implemented: the choice of integer division function.
|
|
||||||
In Haskell, there exists both `quotRem` and `divMod`, with the two disagreeing on negative remainders:
|
|
||||||
|
|
||||||
::: {.row layout-ncol="2"}
|
|
||||||
```{haskell}
|
|
||||||
quotRem (-27) 5
|
|
||||||
```
|
|
||||||
|
|
||||||
```{haskell}
|
```{haskell}
|
||||||
divMod (-27) 5
|
|
||||||
```
|
|
||||||
:::
|
|
||||||
|
|
||||||
We can factor our choice out of our two digit-wide carry function by passing it as an argument:
|
|
||||||
|
|
||||||
```{haskell}
|
|
||||||
-- Widened carry of a particular repeated amount
|
|
||||||
-- i.e., for carry qr 2, the carry is 22 = 100
|
|
||||||
carry2 qr b = carry2' []
|
|
||||||
where carry2' zs (x:y:z:xs)
|
|
||||||
| q == 0 = carry' (x:zs) (y:z:xs) -- try carrying at a higher place value
|
|
||||||
| otherwise = foldl (flip (:)) ys zs -- carry here
|
|
||||||
where ys = r : y-x+r : z+q : xs
|
|
||||||
(q, r) = x `qr` b
|
|
||||||
```
|
|
||||||
|
|
||||||
Finally, let's show the iterates of applying this function to "4".
|
|
||||||
We happen to know the root for $\langle 2, 2|$ is $\sqrt 3 + 1$, so using an approximation,
|
|
||||||
we can check that we get a roughly constant value by evaluating at each step.
|
|
||||||
|
|
||||||
```{haskell}
|
|
||||||
-- | layout-ncol: 2
|
|
||||||
-- | code-fold: true
|
-- | code-fold: true
|
||||||
|
-- | layout-ncol: 2
|
||||||
|
|
||||||
import IHaskell.Display
|
-- Directly expand the integer `n`, using the `carry` showing each step for `count` steps
|
||||||
|
expandSteps count carry n = take count $ iterate carry $ n:replicate count 0
|
||||||
|
|
||||||
-- Horner evaluation on polynomials of ascending powers
|
-- Horner evaluation on polynomials of ascending powers
|
||||||
hornerEval x = foldr (\c a -> a * x + c) 0
|
hornerEval x = foldr (\c a -> a * x + c) 0
|
||||||
-- Pair a polynomial with its evaluation at x
|
-- Pair a polynomial with its evaluation at x
|
||||||
pairEval x = (,) <*> hornerEval x . map fromIntegral
|
pairEval x = (,) <*> hornerEval x . map fromIntegral
|
||||||
|
|
||||||
-- Directly expand the integer `n`, using the `carry` showing each step for `count` steps
|
adicTwoSteps = map (pairEval (sqrt 3 + 1)) $ expandSteps 10 (carry2 2) 2
|
||||||
expandSteps count carry n = take count $ iterate carry $ n:replicate count 0
|
adicFourSteps = map (pairEval (sqrt 3 + 1)) $ expandSteps 10 (carry2 2) 4
|
||||||
|
|
||||||
cendree4QuotRem10Steps = map (pairEval (sqrt 3 + 1)) $ expandSteps 10 (carry2 quotRem 2) 4
|
markdown "Iteratively carrying \"2\""
|
||||||
cendree4DivMod10Steps = map (pairEval (sqrt 3 + 1)) $ expandSteps 10 (carry2 divMod 2) 4
|
markdown "Iteratively carrying \"4\""
|
||||||
|
|
||||||
|
putStrLn . unlines . map show $ adicTwoSteps
|
||||||
|
putStrLn . unlines . map show $ adicFourSteps
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that when an list is displayed in this post, it should be interpreted as an expansion
|
||||||
|
in increasing powers.
|
||||||
|
|
||||||
|
|
||||||
|
Expansions of *κ*-adics
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
In the original post, we ignored expansions other than the chaotic expansions of four.
|
||||||
|
Consider that we can use *two different* expansions for three, since we are using a balanced alphabet:
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
-- | code-fold: true
|
||||||
|
-- | layout-ncol: 2
|
||||||
|
|
||||||
|
markdown "Increment two:"
|
||||||
|
markdown "Decrement three:"
|
||||||
|
|
||||||
|
adicThree = (1:) $ tail $ fst $ last adicTwoSteps
|
||||||
|
print adicThree
|
||||||
|
|
||||||
|
adicThree' = ((-1):) $ tail $ fst $ last adicFourSteps
|
||||||
|
print adicThree'
|
||||||
|
```
|
||||||
|
|
||||||
|
For convenience (and correctness), we'll retain the carry heads rather than truncating them.
|
||||||
|
|
||||||
|
How can we be sure that both of these are expansions of three?
|
||||||
|
Easy. Just negate every term of one of them, then add them together to see if they cancel.
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
maybeZero = take 10 $ iterate (carry2 2) $ zipWith (+) adicThree (map negate adicThree')
|
||||||
|
putStrLn . unlines . map show $ maybeZero
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see, eventually we completely clear the number and just get list of zeros.
|
||||||
|
|
||||||
|
Which of these expansions is more valid?
|
||||||
|
I would argue that we should prefer expansions obtained by incrementing, since the natural numbers
|
||||||
|
are built in the same way.
|
||||||
|
This is flimsy, though. By doing this, negative one will never appear in the one's place.
|
||||||
|
|
||||||
|
It's also worth pointing out that we only have this choice at odd numbers.
|
||||||
|
At even numbers, the one's place is always zero.
|
||||||
|
It's easy to see why this is the case -- if there's a "2" in the one's place, it can be carried,
|
||||||
|
just like in binary.
|
||||||
|
|
||||||
|
|
||||||
|
Balanced vs. Binary *κ*-adics
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
A more unusual consequence of the carry is that despite the initial choice of alphabet,
|
||||||
|
[negative numerals can be cleared](../#all-positive)
|
||||||
|
from the expansion by using an extra-greedy borrow.
|
||||||
|
|
||||||
|
There is only one significant difference in how the two are implemented:
|
||||||
|
the choice of integer division function.
|
||||||
|
In Haskell, there exists both `quotRem` and `divMod`, with the two disagreeing on negative remainders.
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
-- | code-fold: true
|
||||||
|
-- | layout-ncol: 2
|
||||||
|
|
||||||
markdown "`quotRem`"
|
markdown "`quotRem`"
|
||||||
markdown "`divMod`"
|
markdown "`divMod`"
|
||||||
putStrLn . unlines . map show $ cendreeQuotRem10Steps
|
|
||||||
putStrLn . unlines . map show $ cendreeDivMod10Steps
|
print $ quotRem (-27) 5
|
||||||
|
print $ divMod (-27) 5
|
||||||
```
|
```
|
||||||
|
|
||||||
And fortunately, regardless of which function we pick, the iterates are all roughly four.
|
We can factor our choice out of our two digit-wide carry function by passing it as an argument:
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
-- | echo: true
|
||||||
|
|
||||||
|
carry2QR qr b = carry2QR' []
|
||||||
|
where carry2QR' zs (x:y:z:xs)
|
||||||
|
| q == 0 = carry2QR' (x:zs) (y:z:xs) -- try carrying at a higher place value
|
||||||
|
| otherwise = foldl (flip (:)) ys zs -- carry here
|
||||||
|
where ys = r : y-x+r : z+q : xs
|
||||||
|
(q, r) = x `qr` b
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, let's compare the iterates of the two options by applying them to "4":
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
-- | code-fold: true
|
||||||
|
-- | layout-ncol: 2
|
||||||
|
|
||||||
|
cendree4QuotRem10Steps = map (pairEval (sqrt 3 + 1)) $ expandSteps 10 (carry2QR quotRem 2) 4
|
||||||
|
cendree4DivMod10Steps = map (pairEval (sqrt 3 + 1)) $ expandSteps 10 (carry2QR divMod 2) 4
|
||||||
|
|
||||||
|
markdown "`quotRem`"
|
||||||
|
markdown "`divMod`"
|
||||||
|
|
||||||
|
putStrLn . unlines . map show $ cendree4QuotRem10Steps
|
||||||
|
putStrLn . unlines . map show $ cendree4DivMod10Steps
|
||||||
|
```
|
||||||
|
|
||||||
|
Fortunately, regardless of which function we pick, the evaluation roughly gives four at each step.
|
||||||
Note that since `quotRem` allows negative remainders, implementing the carry with it causes
|
Note that since `quotRem` allows negative remainders, implementing the carry with it causes
|
||||||
negative numbers to show up in our expansions.
|
negative numbers to show up in our expansions.
|
||||||
Conversely, negative numbers *cannot* show up if we use `divMod`.
|
Conversely, negative numbers *cannot* show up if we use `divMod`.
|
||||||
@ -92,7 +171,7 @@ Conversely, negative numbers *cannot* show up if we use `divMod`.
|
|||||||
|
|
||||||
### Chaos before Four
|
### Chaos before Four
|
||||||
|
|
||||||
Recall the series for two in the *κ*-adics:
|
Recall again the series for two in the *κ*-adics:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
2 = ...1\bar{1}1\bar{1}1\bar{1}100_{\kappa}
|
2 = ...1\bar{1}1\bar{1}1\bar{1}100_{\kappa}
|
||||||
@ -102,14 +181,16 @@ Since the `divMod` implementation clears negative numbers from expansions, we ca
|
|||||||
The result is another chaotic series:
|
The result is another chaotic series:
|
||||||
|
|
||||||
```{haskell}
|
```{haskell}
|
||||||
cendree2DivModCycleExpansion = take 11 $ iterate (carry2 divMod 2) $ take 15 $ 0:0:cycle [1,-1]
|
cendree2DivModCycleExpansion = take 11 $
|
||||||
|
iterate (carry2QR divMod 2) $ take 15 $ 0:0:cycle [1,-1]
|
||||||
putStrLn . unlines . map show $ cendree2DivModCycleExpansion
|
putStrLn . unlines . map show $ cendree2DivModCycleExpansion
|
||||||
```
|
```
|
||||||
|
|
||||||
We get the same series if we expand 2 directly (which we can also use to check its validity):
|
We get the same series if we expand 2 directly (which we can also use to check its validity):
|
||||||
|
|
||||||
```{haskell}
|
```{haskell}
|
||||||
cendree2DivMod15Steps = map (pairEval (sqrt 3 + 1)) $ expandSteps 15 (carry2 divMod 2) 2
|
cendree2DivMod15Steps = map (pairEval (sqrt 3 + 1)) $
|
||||||
|
expandSteps 15 (carry2QR divMod 2) 2
|
||||||
putStrLn . unlines . map show $ cendree2DivMod15Steps
|
putStrLn . unlines . map show $ cendree2DivMod15Steps
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -117,7 +198,8 @@ We can *also* use this to get a series for negative one, a number which has a te
|
|||||||
in the balanced alphabet.
|
in the balanced alphabet.
|
||||||
|
|
||||||
```{haskell}
|
```{haskell}
|
||||||
cendreeNeg1DivMod15Steps = map (pairEval (sqrt 3 + 1)) $ expandSteps 15 (carry2 divMod 2) (-1)
|
cendreeNeg1DivMod15Steps = map (pairEval (sqrt 3 + 1)) $
|
||||||
|
expandSteps 15 (carry2QR divMod 2) (-1)
|
||||||
putStrLn . unlines . map show $ cendreeNeg1DivMod15Steps
|
putStrLn . unlines . map show $ cendreeNeg1DivMod15Steps
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -126,8 +208,9 @@ If we take the last iterate of this, increment the zeroth place value, and apply
|
|||||||
we find that everything clears properly.
|
we find that everything clears properly.
|
||||||
|
|
||||||
```{haskell}
|
```{haskell}
|
||||||
cendree0FromNeg1DivMod = (\(x:xs) -> (x + 1):xs) $ snd $ last cendreeNeg1DivMod15Steps
|
cendree0FromNeg1DivMod = (\(x:xs) -> (x + 1):xs) $ fst $ last cendreeNeg1DivMod15Steps
|
||||||
cendree0IncrementSteps = map (pairEval (sqrt 3 + 1)) $ take 15 $ iterate (carry2 divMod 2) cendree0FromNeg1DivMod
|
cendree0IncrementSteps = map (pairEval (sqrt 3 + 1)) $ take 15 $
|
||||||
|
iterate (carry2QR divMod 2) cendree0FromNeg1DivMod
|
||||||
|
|
||||||
putStrLn . unlines . map show $ cendree0IncrementSteps
|
putStrLn . unlines . map show $ cendree0IncrementSteps
|
||||||
```
|
```
|
||||||
@ -158,14 +241,17 @@ You should definitely see [this page](/interactive/adic/) for more information,
|
|||||||
|
|
||||||
First, notice that with $b = 2$ and $p = 2$, switching between the "b-adic" option
|
First, notice that with $b = 2$ and $p = 2$, switching between the "b-adic" option
|
||||||
and the "*κ*-adic" option appears cause some points to appear and disappear.
|
and the "*κ*-adic" option appears cause some points to appear and disappear.
|
||||||
This is easiest to see when $c \approx 0.5$.
|
It is easiest to see this when $c \approx 0.5$.
|
||||||
|
This corresponds with the intuition that these are subsets of the 2- and 3-adics.
|
||||||
|
|
||||||
Next, notice that when plotting the *κ*-adics, some self-similarity different from the 2- and 3-adics
|
Next, notice that when plotting the *κ*-adics, there is some self-similarity different
|
||||||
can be observed for $c \approx 0.75$.
|
from the 2- and 3-adics.
|
||||||
There appear to be four clusters of points, with the topmost and rightmost appearing to be
|
To see this, try setting $c \approx 0.75$.
|
||||||
similar to one another.
|
There appear to be four clusters, with the topmost and rightmost appearing to be similar to one another.
|
||||||
Within these two clusters, the rightmost portion of them appears to be the same shape
|
Within these two clusters, the rightmost portion of them appears to be the same shape
|
||||||
as the larger figure.
|
as the larger figure.
|
||||||
|
If you try switching between the *κ*-adic options, you can even see the smaller
|
||||||
|
and larger shapes changing in the same way as one another.
|
||||||
|
|
||||||
This is actually great news -- if you switch between the *κ*-adics and the "random binary" option,
|
This is actually great news -- if you switch between the *κ*-adics and the "random binary" option,
|
||||||
you can see that the latter option tends to the same pattern as the 2-adics.
|
you can see that the latter option tends to the same pattern as the 2-adics.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user