mostly finish making polycount.cell1 renderable
This commit is contained in:
parent
9838e0d5cf
commit
5cb572e3e1
1
polycount/cell1/.gitignore
vendored
Normal file
1
polycount/cell1/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.mp4
|
||||||
96
polycount/cell1/carry2d/expansion.py
Normal file
96
polycount/cell1/carry2d/expansion.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
from sympy.abc import x, y
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from .carry import Carry
|
||||||
|
|
||||||
|
|
||||||
|
def add(
|
||||||
|
expansion: np.ndarray, carry: Carry, val: int = 1, center: tuple[int, int] = (0, 0)
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Add `val` to a position in an `expansion` designated the `center`, then apply `carry`.
|
||||||
|
"""
|
||||||
|
expansion[center] += val
|
||||||
|
carry.apply(expansion)
|
||||||
|
return expansion
|
||||||
|
|
||||||
|
|
||||||
|
def times(expansion: np.ndarray, carry: Carry, val: int):
|
||||||
|
"""
|
||||||
|
Multiply all digits in an `expansion` by `val`, then apply `carry`.
|
||||||
|
"""
|
||||||
|
expansion *= val
|
||||||
|
carry.apply(expansion)
|
||||||
|
return expansion
|
||||||
|
|
||||||
|
|
||||||
|
def poly_from_array(
|
||||||
|
array: np.ndarray, center: tuple[int, int] = (0, 0), x_var=x, y_var=y
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Convert a numpy array to a polynomial in two variables.
|
||||||
|
Note that indices are row-major in Numpy, so center is in the form (y, x).
|
||||||
|
"""
|
||||||
|
ret = 0
|
||||||
|
for i, row in enumerate(array):
|
||||||
|
for j, val in enumerate(row):
|
||||||
|
ret += val * (x_var ** (i - center[1]) * y_var ** (j - center[0]))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def _first_nonzero(arr: np.ndarray, axis: int):
|
||||||
|
"""
|
||||||
|
Find the index of the first nonzero entry of `arr` along `axis`.
|
||||||
|
Modified from https://stackoverflow.com/questions/47269390
|
||||||
|
"""
|
||||||
|
mask = arr != 0
|
||||||
|
return min(
|
||||||
|
np.where(mask.any(axis=axis), mask.argmax(axis=axis), arr.shape[axis] + 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def latex_polynumber(
|
||||||
|
arr: np.ndarray, center: tuple[int, int] | None = None, show_zero: bool = False
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Convert a 2D Numpy array into a LaTeX array representing a polynomial in two variables.
|
||||||
|
Vertical lines and `\\hline`s are placed to indicate the transition between negative
|
||||||
|
and nonnegative powers, similar to a typical fractional separator (decimal point).
|
||||||
|
|
||||||
|
By default, this assumes the constant term is in position (0, 0) of the array.
|
||||||
|
It may be alternatively supplied by `center`, which designates `arr[center]` as the constant term.
|
||||||
|
Note that indices are row-major in Numpy, so `center` is in the form (y, x).
|
||||||
|
|
||||||
|
`show_zero` defaults to False, which causes entries in `arr` which are 0 to not be drawn.
|
||||||
|
When true, all 0 entries will be drawn.
|
||||||
|
"""
|
||||||
|
upper_left = _first_nonzero(arr, 0), _first_nonzero(arr, 1)
|
||||||
|
lower_right = (
|
||||||
|
len(arr) - _first_nonzero(np.flip(arr, 0), 0) - 1,
|
||||||
|
len(arr[1]) - _first_nonzero(np.flip(arr, 1), 1) - 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
center_left, center_top = center or (0, 0)
|
||||||
|
if center is not None:
|
||||||
|
# this does not need offset, since we iterate over this range
|
||||||
|
center_top = center[0]
|
||||||
|
# but this does for the array environment argument
|
||||||
|
center_left = center[1] - upper_left[1]
|
||||||
|
|
||||||
|
num_columns = lower_right[1] - upper_left[1]
|
||||||
|
column_layout = ("c" * center_left) + "|" + ("c" * (num_columns - center_left))
|
||||||
|
|
||||||
|
# build array output
|
||||||
|
ret = "\\begin{array}{" + column_layout + "}"
|
||||||
|
for i in range(upper_left[0], lower_right[0] + 1):
|
||||||
|
if i == center_top:
|
||||||
|
ret += " \\hline "
|
||||||
|
ret += " & ".join(
|
||||||
|
[
|
||||||
|
str(arr[i, j] if arr[i, j] != 0 or show_zero else "")
|
||||||
|
for j in range(upper_left[1], lower_right[1] + 1)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
# next row
|
||||||
|
ret += " \\\\ "
|
||||||
|
return ret + "\\end{array}"
|
||||||
@ -1,20 +1,21 @@
|
|||||||
---
|
---
|
||||||
title: "Counting in 2D: Lines, Leaves, and Sand"
|
title: "Counting in 2D: Lines, Leaves, and Sand"
|
||||||
|
draft: true
|
||||||
format:
|
format:
|
||||||
html:
|
html:
|
||||||
html-math-method: katex
|
html-math-method: katex
|
||||||
date: "2021-02-23"
|
date: "2021-02-23"
|
||||||
date-modified: "2025-2-14"
|
date-modified: "2025-2-20"
|
||||||
jupyter: python3
|
jupyter: python3
|
||||||
categories:
|
categories:
|
||||||
- algebra
|
- algebra
|
||||||
- python
|
- python
|
||||||
execute:
|
execute:
|
||||||
eval: false
|
echo: false
|
||||||
---
|
---
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| echo: false
|
from pathlib import Path
|
||||||
|
|
||||||
import sympy
|
import sympy
|
||||||
from sympy.abc import x, y
|
from sympy.abc import x, y
|
||||||
@ -40,7 +41,8 @@ from carry2d.expansion import (
|
|||||||
|
|
||||||
|
|
||||||
Previously, I've written about positional systems and so-called "[polynomial counting](../1)".
|
Previously, I've written about positional systems and so-called "[polynomial counting](../1)".
|
||||||
Basically, this generalizes familiar integer bases like two and ten into less familiar irrational ones like the golden ratio.
|
Basically, this generalizes familiar integer bases like two and ten into less familiar irrational ones
|
||||||
|
like the golden ratio.
|
||||||
However, all systems I presented have something in common: they all use polynomials of a single variable.
|
However, all systems I presented have something in common: they all use polynomials of a single variable.
|
||||||
Does it make sense to count in two variables?
|
Does it make sense to count in two variables?
|
||||||
|
|
||||||
@ -259,21 +261,23 @@ An additional property of this system is that the number of "1"s that appear in
|
|||||||
These two properties make it a sort of hybrid between unary and binary, bridging their
|
These two properties make it a sort of hybrid between unary and binary, bridging their
|
||||||
binary expansion and its [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight).
|
binary expansion and its [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight).
|
||||||
|
|
||||||
This notation is very heavy, but fortunately lends itself well visualization.
|
This notation is very heavy, but fortunately lends itself well to visualization.
|
||||||
Each integer's expansion is more or less an image, so we can arrange each as frames in a video:
|
Each integer's expansion is more or less an image, so we can arrange each as frames in a video:
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| code-fold: true
|
if not Path("./count_xy2.mp4").exists():
|
||||||
|
animate_carry_count(
|
||||||
|
carry = Carry([
|
||||||
|
[-2, 1],
|
||||||
|
[ 1, 0]
|
||||||
|
]),
|
||||||
|
frames=list(range(1024))
|
||||||
|
).save(
|
||||||
|
"./count_xy2.mp4",
|
||||||
|
fps=60
|
||||||
|
)
|
||||||
|
|
||||||
animate_carry_count(
|
Video("./count_xy2.mp4")
|
||||||
carry = Carry([
|
|
||||||
[-2, 1],
|
|
||||||
[ 1, 0]
|
|
||||||
]),
|
|
||||||
frames=list(range(200))
|
|
||||||
).save("count_xy2.mp4")
|
|
||||||
|
|
||||||
Video("count_xy2.mp4")
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Starting at the expansion of twelve, the furthest extent is not in the first column or row.
|
Starting at the expansion of twelve, the furthest extent is not in the first column or row.
|
||||||
@ -289,32 +293,45 @@ Fortunately, this is a simple enough system that we can scalar-multiply base exp
|
|||||||
Ascending the powers of *n* in this manner for the carries where *n* = 3 and 4:
|
Ascending the powers of *n* in this manner for the carries where *n* = 3 and 4:
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| code-fold: true
|
|
||||||
#| layout-ncol: 2
|
#| layout-ncol: 2
|
||||||
|
|
||||||
animate_carry_count(
|
# Run the animations until we overflow in the standard 100x100 range
|
||||||
carry = Carry([
|
if not Path("./count_xy3.mp4").exists():
|
||||||
[-3, 1],
|
try:
|
||||||
[ 1, 0]
|
animate_carry_count(
|
||||||
]),
|
carry = Carry([
|
||||||
operation="multiply",
|
[-3, 1],
|
||||||
op_val=3,
|
[ 1, 0]
|
||||||
frames=list(range(200))
|
]),
|
||||||
).save("count_xy3.mp4")
|
operation="multiply",
|
||||||
|
op_val=3,
|
||||||
|
frames=list(range(200))
|
||||||
|
).save("count_xy3.mp4")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
animate_carry_count(
|
if not Path("./count_xy4.mp4").exists():
|
||||||
carry = Carry([
|
try:
|
||||||
[-4, 1],
|
animate_carry_count(
|
||||||
[ 1, 0]
|
carry = Carry([
|
||||||
]),
|
[-4, 1],
|
||||||
operation="multiply",
|
[ 1, 0]
|
||||||
op_val=4,
|
]),
|
||||||
frames=list(range(200)),
|
operation="multiply",
|
||||||
).save("count_xy4.mp4")
|
op_val=4,
|
||||||
|
frames=list(range(200)),
|
||||||
|
).save("count_xy4.mp4")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
display(
|
display(
|
||||||
Video("count_xy3.mp4"),
|
Video("./count_xy3.mp4"),
|
||||||
Video("count_xy4.mp4")
|
Video("./count_xy4.mp4")
|
||||||
|
)
|
||||||
|
|
||||||
|
display_latex(
|
||||||
|
Latex("$$x + y = 3$$"),
|
||||||
|
Latex("$$x + y = 4$$"),
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -342,10 +359,9 @@ Taking *x* or *y* to higher powers will dilate expansions along that axis.
|
|||||||
|
|
||||||
The carry is not the only curve which exists in a system, as each integer is also a polynomial unto itself.
|
The carry is not the only curve which exists in a system, as each integer is also a polynomial unto itself.
|
||||||
Adding a constant term will not change anything unless it causes carries to occur.
|
Adding a constant term will not change anything unless it causes carries to occur.
|
||||||
Starting at the carry digit, some of the curves made by the carry $x + y = 2$ are shown below.
|
Starting at the carry digit, some of the *incremented curves* made by the carry $x + y = 2$ are shown below.
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| code-fold: true
|
|
||||||
#| layout: [[3, 3], [2, 2, 2]]
|
#| layout: [[3, 3], [2, 2, 2]]
|
||||||
|
|
||||||
expansion = np.zeros((50, 50), dtype=np.int64)
|
expansion = np.zeros((50, 50), dtype=np.int64)
|
||||||
@ -386,12 +402,11 @@ This curve happens to intersect with the *x* and *y* axes, which we can interpre
|
|||||||
For dibinary, these are the aforementioned "typical binary expansions".
|
For dibinary, these are the aforementioned "typical binary expansions".
|
||||||
We can also evaluate the polynomial at $(x, y) = (1, 1)$, a point on the carry curve,
|
We can also evaluate the polynomial at $(x, y) = (1, 1)$, a point on the carry curve,
|
||||||
to compute its digital root, which is also equal to the integer it represents.
|
to compute its digital root, which is also equal to the integer it represents.
|
||||||
|
|
||||||
This underlies a key difference from the 1D case.
|
This underlies a key difference from the 1D case.
|
||||||
|
1D systems are special because the carry can be equated with a base (or bases), which
|
||||||
|
is a discrete, zero-dimensional point (one dimension less) on a number line.
|
||||||
In higher dimensions, there is no proper "base" we can plug in to "test" that an expansion
|
In higher dimensions, there is no proper "base" we can plug in to "test" that an expansion
|
||||||
is valid like we can with the golden ratio in phinary.
|
is valid like we can with the golden ratio in phinary.
|
||||||
1D systems are special in this regard: the carry can be equated with a base (or bases), which
|
|
||||||
is a discrete zero-dimensional point on a number line.
|
|
||||||
|
|
||||||
|
|
||||||
Casting the Line
|
Casting the Line
|
||||||
@ -449,8 +464,6 @@ The expansion in the *y* column looks trivially correct, since $y^2 = 9$ when $x
|
|||||||
We can check the base of the expansion of nine ("2100") by factoring a polynomial:
|
We can check the base of the expansion of nine ("2100") by factoring a polynomial:
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| code-fold: true
|
|
||||||
|
|
||||||
nine_x2y3 = 2*x**3 + x**2 - 9
|
nine_x2y3 = 2*x**3 + x**2 - 9
|
||||||
|
|
||||||
display_latex(
|
display_latex(
|
||||||
@ -469,32 +482,38 @@ This transposes the carry (and hence the expansion).
|
|||||||
For good measure, let's see what it looks like when we count in the $n = 3$ and $n = 4$ cases.
|
For good measure, let's see what it looks like when we count in the $n = 3$ and $n = 4$ cases.
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| code-fold: true
|
|
||||||
#| layout-ncol: 2
|
#| layout-ncol: 2
|
||||||
|
|
||||||
animate_carry_count(
|
if not Path("./count_x2y3.mp4").exists():
|
||||||
carry = Carry([
|
animate_carry_count(
|
||||||
[-3, 2],
|
carry = Carry([
|
||||||
[ 1, 0]
|
[-3, 2],
|
||||||
]),
|
[ 1, 0]
|
||||||
operation="add",
|
]),
|
||||||
op_val=3,
|
operation="add",
|
||||||
frames=list(range(200))
|
op_val=3,
|
||||||
).save("count_x2y3.mp4")
|
frames=list(range(200))
|
||||||
|
).save("./count_x2y3.mp4")
|
||||||
|
|
||||||
animate_carry_count(
|
if not Path("./count_x3y4.mp4").exists():
|
||||||
carry = Carry([
|
animate_carry_count(
|
||||||
[-4, 3],
|
carry = Carry([
|
||||||
[ 1, 0]
|
[-4, 3],
|
||||||
]),
|
[ 1, 0]
|
||||||
operation="add",
|
]),
|
||||||
op_val=4,
|
operation="add",
|
||||||
frames=list(range(200)),
|
op_val=4,
|
||||||
).save("count_x3y4.mp4")
|
frames=list(range(200)),
|
||||||
|
).save("./count_x3y4.mp4")
|
||||||
|
|
||||||
display(
|
display(
|
||||||
Video("count_x2y3.mp4"),
|
Video("./count_x2y3.mp4"),
|
||||||
Video("count_x3y4.mp4")
|
Video("./count_x3y4.mp4"),
|
||||||
|
)
|
||||||
|
|
||||||
|
display_latex(
|
||||||
|
Latex("$$2x + y = 3$$"),
|
||||||
|
Latex("$$3x + y = 4$$"),
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -512,12 +531,11 @@ The binary alphabet is the smallest possible, so the minimal shrinkage is in dib
|
|||||||
|
|
||||||
### Incremented Curves
|
### Incremented Curves
|
||||||
|
|
||||||
Below are the incremented curves for $n = 3$.
|
Below are some incremented curves for $n = 3$.
|
||||||
These curves show an interesting phenomenon: an extra line is present in in the expansion of six.
|
These curves show an interesting phenomenon: an extra line is present in in the expansion of six.
|
||||||
This line turns into a spike at twelve, then at fifteen, it seems to grow to encompass the point at infinity.
|
This line turns into a spike at twelve, then at fifteen, it seems to grow to encompass the point at infinity.
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| code-fold: true
|
|
||||||
#| layout-ncol: 2
|
#| layout-ncol: 2
|
||||||
|
|
||||||
x2y3 = Carry([
|
x2y3 = Carry([
|
||||||
@ -525,17 +543,15 @@ x2y3 = Carry([
|
|||||||
[ 1, 0]
|
[ 1, 0]
|
||||||
])
|
])
|
||||||
|
|
||||||
expansion = np.zeros((50, 50), dtype=np.int64)
|
|
||||||
last_i = 0
|
|
||||||
for i in [3, 6, 12, 15]:
|
for i in [3, 6, 12, 15]:
|
||||||
carry_add(expansion, x2y3, i - last_i)
|
expansion = np.zeros((50, 50), dtype=np.int64)
|
||||||
|
carry_add(expansion, x2y3, i)
|
||||||
plot_implicit(
|
plot_implicit(
|
||||||
poly_from_array(expansion) - i,
|
poly_from_array(expansion) - i,
|
||||||
(x, -10, 10),
|
(x, -10, 10),
|
||||||
(y, -10, 10),
|
(y, -10, 10),
|
||||||
title=f"{i}",
|
title=f"{i}",
|
||||||
)
|
)
|
||||||
last_i = i
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -543,77 +559,13 @@ Leaves in the Mirror
|
|||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Algebraic curves are not my forte.
|
Algebraic curves are not my forte.
|
||||||
However, I believe it would be a good idea to briefly examine some classical examples.
|
Still, we can very briefly look at some classical examples from the perspective of carries.
|
||||||
|
|
||||||
All Fermat curves $x^n + y^n = 1$ are not suitable as carries, since their digital root is unbounded.
|
|
||||||
Scaling up the curve, as by $x^n + y^n = 2$ will just degenerate back to the previous examples with lines,
|
|
||||||
but spaced out by zeros between entries.
|
|
||||||
|
|
||||||
The [folium of Descartes](https://en.wikipedia.org/wiki/Folium_of_Descartes) is another
|
|
||||||
classical curve that played a role in the development of calculus, described by the equation:
|
|
||||||
|
|
||||||
$$
|
|
||||||
\begin{gather*}
|
|
||||||
x^3 + y^3 - 3axy = 0
|
|
||||||
\\ \\
|
|
||||||
\begin{array}{|c} \hline
|
|
||||||
0 & 0 & 0 & 1 \\
|
|
||||||
0 & -3a \\
|
|
||||||
0 & \\
|
|
||||||
1
|
|
||||||
\end{array}
|
|
||||||
\end{gather*}
|
|
||||||
$$
|
|
||||||
|
|
||||||
The position of the 3*a* term may be confusing.
|
|
||||||
As the negative coefficient, we must place it atop the digit we are carrying, meaning that
|
|
||||||
expansions will propagate toward negative powers of *x* and *y* as well as positive.
|
|
||||||
While the shape of the curve is different from an ordinary line, the coefficients are arranged
|
|
||||||
too similarly; for $a = 2/3$ (so the curve passes through the point (1, 1)) incrementing appears as:
|
|
||||||
|
|
||||||
```{python}
|
|
||||||
#| echo: false
|
|
||||||
#| layout-ncol: 2
|
|
||||||
|
|
||||||
folium = Carry([
|
|
||||||
[ 0, 0, 0, 1],
|
|
||||||
[ 0,-2, 0, 0],
|
|
||||||
[ 0, 0, 0, 0],
|
|
||||||
[ 1, 0, 0, 0],
|
|
||||||
])
|
|
||||||
dims = (50, 50)
|
|
||||||
center = (dims[0] // 2, dims[1] // 2)
|
|
||||||
two_folium = carry_add(np.zeros(dims, dtype=np.int64), folium, 2, center=center)
|
|
||||||
four_folium = carry_add(np.zeros(dims, dtype=np.int64), folium, 4, center=center)
|
|
||||||
|
|
||||||
display_latex(
|
|
||||||
Latex(
|
|
||||||
r"\begin{gather*}"
|
|
||||||
+ "2: &"
|
|
||||||
+ latex_polynumber(two_folium, center=center, show_zero=True) + r"\\"
|
|
||||||
+ r"\\ \\ 4: &"
|
|
||||||
+ latex_polynumber(four_folium, center=center, show_zero=True) + r"\\"
|
|
||||||
+ r"\end{gather*}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
animate_carry_count(
|
|
||||||
carry=folium,
|
|
||||||
operation="add",
|
|
||||||
op_val=4,
|
|
||||||
frames=list(range(200)),
|
|
||||||
).save("count_folium.mp4")
|
|
||||||
|
|
||||||
display(Video("count_folium.mp4"))
|
|
||||||
```
|
|
||||||
|
|
||||||
Clearly, this also tends back toward dibinary, but with the yellow digits spaced out more.
|
|
||||||
|
|
||||||
|
|
||||||
### Discounting Curves
|
### Quadratic Curves
|
||||||
|
|
||||||
The interpretation of the carry as a curve is secondary, so I'd like to disqualify
|
Unfortunately, the most common quadratic curves are largely uninteresting.
|
||||||
some archetypal quadratic objects.
|
Briefly, here are some comments about some the simplest cases:
|
||||||
|
|
||||||
- Unit circle ($x^2 + y^2 - 1 = 0$) and hyperbola ($\pm x^2 \mp y^2 - 1 = 0$)
|
- Unit circle ($x^2 + y^2 - 1 = 0$) and hyperbola ($\pm x^2 \mp y^2 - 1 = 0$)
|
||||||
- The sum of coefficients is positive, which means that expansions are unbounded.
|
- The sum of coefficients is positive, which means that expansions are unbounded.
|
||||||
@ -632,11 +584,81 @@ Other polynomials in *x* and *y* may produce rotations or dilations of these cur
|
|||||||
What truly matters is that one cell affects relatively close cells in a certain way.
|
What truly matters is that one cell affects relatively close cells in a certain way.
|
||||||
|
|
||||||
|
|
||||||
|
### Higher-Order Curves
|
||||||
|
|
||||||
|
All unit Fermat curves $x^n + y^n = 1$ are not suitable as carries, since their digital root is unbounded.
|
||||||
|
Scaling up the curve, for example to $x^n + y^n = 2$, will just degenerate back to the previous
|
||||||
|
examples with lines, but spaced out by zeros between entries.
|
||||||
|
|
||||||
|
The [folium of Descartes](https://en.wikipedia.org/wiki/Folium_of_Descartes) is another
|
||||||
|
classical curve that played a role in the development of calculus, described by the equation:
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{gather*}
|
||||||
|
x^3 + y^3 - 3axy = 0
|
||||||
|
\\ \\
|
||||||
|
\begin{array}{|c} \hline
|
||||||
|
0 & 0 & 0 & 1 \\
|
||||||
|
0 & -3a \\
|
||||||
|
0 & \\
|
||||||
|
1
|
||||||
|
\end{array}
|
||||||
|
\end{gather*}
|
||||||
|
$$
|
||||||
|
|
||||||
|
As written above, the position of the 3*a* term may be confusing.
|
||||||
|
As the negative term in an explicit carry, we must place it atop the digit we are carrying,
|
||||||
|
meaning that expansions will propagate toward negative powers of *x* and *y* as well as positive.
|
||||||
|
While the shape of the curve is different from an ordinary line, the coefficients are arranged
|
||||||
|
too similarly; for $a = 2/3$ (so the curve passes through the point $(1, 1)$) incrementing appears as:
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
#| layout-ncol: 2
|
||||||
|
|
||||||
|
folium_carry = Carry([
|
||||||
|
[ 0, 0, 0, 1],
|
||||||
|
[ 0,-2, 0, 0],
|
||||||
|
[ 0, 0, 0, 0],
|
||||||
|
[ 1, 0, 0, 0],
|
||||||
|
])
|
||||||
|
folium_dims = (50, 50)
|
||||||
|
folium_center = (folium_dims[0] // 2, folium_dims[1] // 2)
|
||||||
|
folium_two = carry_add(np.zeros(folium_dims, dtype=np.int64), folium_carry, 2, center=folium_center)
|
||||||
|
folium_four = carry_add(np.zeros(folium_dims, dtype=np.int64), folium_carry, 4, center=folium_center)
|
||||||
|
|
||||||
|
display_latex(
|
||||||
|
Latex(
|
||||||
|
r"\begin{gather*}"
|
||||||
|
+ "2: &"
|
||||||
|
+ latex_polynumber(folium_two, center=folium_center, show_zero=True) + r"\\"
|
||||||
|
+ r"\\ \\ 4: &"
|
||||||
|
+ latex_polynumber(folium_four, center=folium_center, show_zero=True) + r"\\"
|
||||||
|
+ r"\end{gather*}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not Path("./count_folium.mp4").exists():
|
||||||
|
try:
|
||||||
|
animate_carry_count(
|
||||||
|
carry=folium_carry,
|
||||||
|
operation="add",
|
||||||
|
op_val=4,
|
||||||
|
frames=list(range(200)),
|
||||||
|
).save("./count_folium.mp4")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
display(Video("./count_folium.mp4"))
|
||||||
|
```
|
||||||
|
|
||||||
|
Clearly, this also tends back toward dibinary, but with the yellow digits spaced out more.
|
||||||
|
|
||||||
|
|
||||||
Laplace's Sandstorm
|
Laplace's Sandstorm
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
As stated previously, polynomials naturally multiply by convolution.
|
As stated previously, polynomials naturally multiply by convolution.
|
||||||
In this context, a form which frequently arises is an approximation of the 2D Laplacian.
|
In the context of this operation, the discrete 2D Laplacian is frequently used
|
||||||
While commonly presented as a matrix, it has very little to do with the machinery of
|
While commonly presented as a matrix, it has very little to do with the machinery of
|
||||||
linear algebra which normally empowers matrices.
|
linear algebra which normally empowers matrices.
|
||||||
|
|
||||||
@ -659,8 +681,6 @@ $$
|
|||||||
$$
|
$$
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| echo: false
|
|
||||||
|
|
||||||
plot_implicit(x + y + x*y**2 + y*x**2 - 4*x*y, (x, -10, 10), (y, -10, 10))
|
plot_implicit(x + y + x*y**2 + y*x**2 - 4*x*y, (x, -10, 10), (y, -10, 10))
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
@ -718,21 +738,21 @@ As a cellular automaton, it is rather popular as a coding challenge
|
|||||||
These videos discuss toppling the initial value, but do not point out the analogy to polynomial expansions.
|
These videos discuss toppling the initial value, but do not point out the analogy to polynomial expansions.
|
||||||
|
|
||||||
```{python}
|
```{python}
|
||||||
#| code-fold: true
|
|
||||||
#| layout-ncol: 2
|
#| layout-ncol: 2
|
||||||
|
|
||||||
animate_carry_count(
|
if not Path("./count_x2y3.mp4").exists():
|
||||||
carry = Carry([
|
animate_carry_count(
|
||||||
[ 0, 1, 0],
|
carry = Carry([
|
||||||
[ 1,-4, 1],
|
[ 0, 1, 0],
|
||||||
[ 0, 1, 0],
|
[ 1,-4, 1],
|
||||||
]),
|
[ 0, 1, 0],
|
||||||
operation="add",
|
]),
|
||||||
op_val=4,
|
operation="add",
|
||||||
frames=list(range(200)),
|
op_val=4,
|
||||||
).save("count_laplace.mp4")
|
frames=list(range(200)),
|
||||||
|
).save("./count_laplace.mp4")
|
||||||
|
|
||||||
Video("count_laplace.mp4")
|
Video("./count_laplace.mp4")
|
||||||
```
|
```
|
||||||
|
|
||||||
The shapes produced by this pattern are well-known, with larger numbers appearing as fractals.
|
The shapes produced by this pattern are well-known, with larger numbers appearing as fractals.
|
||||||
|
|||||||
5
polycount/cell1/todo.txt
Normal file
5
polycount/cell1/todo.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
mp4s saved do not get copied or linked over to the rendering folder
|
||||||
|
|
||||||
|
center figures
|
||||||
|
|
||||||
|
make sure to object-fit: scale
|
||||||
Loading…
x
Reference in New Issue
Block a user