refactor diagram files
This commit is contained in:
parent
f1b2215363
commit
b28f7fd65f
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ _site/
|
|||||||
/.quarto/
|
/.quarto/
|
||||||
index_files/
|
index_files/
|
||||||
.jupyter_cache/
|
.jupyter_cache/
|
||||||
|
__pycache__/
|
||||||
|
|||||||
@ -1,65 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
class Carry:
|
|
||||||
def __init__(self, arr):
|
|
||||||
if not isinstance(arr, np.ndarray):
|
|
||||||
arr = np.array(arr)
|
|
||||||
overflow = None
|
|
||||||
over_pos = None
|
|
||||||
coeff_sum = 0
|
|
||||||
#find largest carry
|
|
||||||
for i, row in enumerate(arr):
|
|
||||||
for j, val in enumerate(row):
|
|
||||||
coeff_sum += val
|
|
||||||
if val > 0:
|
|
||||||
if overflow is not None:
|
|
||||||
raise ValueError("array supplied has more than one overflow digit")
|
|
||||||
overflow = val
|
|
||||||
over_pos = (i, j)
|
|
||||||
|
|
||||||
if coeff_sum < 0:
|
|
||||||
raise ValueError("sum of coefficients too small")
|
|
||||||
|
|
||||||
self._arr = arr
|
|
||||||
self.over_pos = over_pos
|
|
||||||
self.overflow = overflow
|
|
||||||
|
|
||||||
def _update(self, base, update_tuples, zerowall):
|
|
||||||
#dim_x, dim_y = base.shape
|
|
||||||
pos_x, pos_y = self.over_pos
|
|
||||||
for (x,y) in update_tuples:
|
|
||||||
idx = base[(x,y)]
|
|
||||||
dec = (idx // self.overflow) # - 1
|
|
||||||
|
|
||||||
wall = zerowall.copy()
|
|
||||||
sh_x, sh_y = self._arr.shape
|
|
||||||
x -= pos_x
|
|
||||||
y -= pos_y
|
|
||||||
|
|
||||||
wall[x:x + sh_x, y:y + sh_y] = dec * self._arr
|
|
||||||
base -= wall
|
|
||||||
|
|
||||||
def update(self, base):
|
|
||||||
zerowall = np.zeros(base.shape, dtype=base.dtype)
|
|
||||||
while True:
|
|
||||||
update_tuples = list(zip(*np.where(base >= self.overflow)))
|
|
||||||
if not update_tuples:
|
|
||||||
break
|
|
||||||
self._update(base, update_tuples, zerowall)
|
|
||||||
|
|
||||||
def times(self, base, val, center=(0,0)):
|
|
||||||
#perform multiplication using the carry
|
|
||||||
base[center] *= val
|
|
||||||
self.update(base)
|
|
||||||
return base
|
|
||||||
|
|
||||||
def add(self, base, val=1, center=(0,0)):
|
|
||||||
base[center] += val
|
|
||||||
self.update(base)
|
|
||||||
return base
|
|
||||||
|
|
||||||
laplace = Carry(np.array([[0,-1,0],[-1,4,-1],[0,-1,0]]))
|
|
||||||
|
|
||||||
#test = np.zeros((100, 100))
|
|
||||||
#test[50,50] = 4
|
|
||||||
0
polycount/cell1/carry2d/__init__.py
Normal file
0
polycount/cell1/carry2d/__init__.py
Normal file
83
polycount/cell1/carry2d/anim.py
Normal file
83
polycount/cell1/carry2d/anim.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
from functools import partial
|
||||||
|
from typing import Callable, Literal
|
||||||
|
|
||||||
|
from matplotlib import animation, pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from .carry import Carry
|
||||||
|
|
||||||
|
writer = animation.writers["ffmpeg"](fps=15, metadata={"artist": "Me"})
|
||||||
|
|
||||||
|
|
||||||
|
def times(base: np.ndarray, carry: Carry, val):
|
||||||
|
base *= val
|
||||||
|
carry.apply(base)
|
||||||
|
return base
|
||||||
|
|
||||||
|
|
||||||
|
def add(base: np.ndarray, carry: Carry, val=1, center=(0, 0)):
|
||||||
|
base[center] += val
|
||||||
|
carry.apply(base)
|
||||||
|
return base
|
||||||
|
|
||||||
|
|
||||||
|
def animate(
|
||||||
|
fig, frames: list[int] | None, **kwargs
|
||||||
|
) -> Callable[..., animation.FuncAnimation]:
|
||||||
|
# Why isn't this how the function is exposed by default?
|
||||||
|
return lambda func: animation.FuncAnimation(fig, func, frames, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def animate_carry_count(
|
||||||
|
carry: Carry,
|
||||||
|
dims: int = 100,
|
||||||
|
operation: Literal["add", "multiply"] = "add",
|
||||||
|
op_val=1,
|
||||||
|
center: tuple[int, int] | None = None,
|
||||||
|
# Animation parameters
|
||||||
|
frames: list[int] | None = None,
|
||||||
|
interval=200,
|
||||||
|
) -> animation.FuncAnimation:
|
||||||
|
if center is None:
|
||||||
|
if carry.over_pos != (0, 0):
|
||||||
|
center = (dims // 2, dims // 2)
|
||||||
|
else:
|
||||||
|
center = (0, 0)
|
||||||
|
|
||||||
|
if operation == "add":
|
||||||
|
next_func = partial(add, carry=carry, val=op_val, center=center)
|
||||||
|
elif operation == "multiply":
|
||||||
|
if op_val == 1:
|
||||||
|
raise ValueError(f"too small value {op_val} for repeated multiplication")
|
||||||
|
next_func = partial(times, carry=carry, val=op_val)
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Cannot use {repr(operation)} for animation")
|
||||||
|
|
||||||
|
expansion = np.zeros((dims, dims))
|
||||||
|
expansion[center] = 1
|
||||||
|
title = [1]
|
||||||
|
|
||||||
|
fig = plt.gcf()
|
||||||
|
|
||||||
|
image = plt.imshow(
|
||||||
|
expansion,
|
||||||
|
extent=[-center[0], dims - center[0], dims - center[1], -center[1]], # type: ignore
|
||||||
|
)
|
||||||
|
def init():
|
||||||
|
plt.title(f"{title[0]}")
|
||||||
|
image.set_clim(0, carry.overflow - 1)
|
||||||
|
fig.tight_layout()
|
||||||
|
|
||||||
|
@animate(fig, frames, interval=interval, init_func=init)
|
||||||
|
def ret(_):
|
||||||
|
plt.title(f"{title[0]}")
|
||||||
|
image.set_data(expansion)
|
||||||
|
fig.tight_layout()
|
||||||
|
|
||||||
|
next_func(expansion)
|
||||||
|
if operation == "add":
|
||||||
|
title[0] += op_val
|
||||||
|
else:
|
||||||
|
title[0] *= op_val
|
||||||
|
|
||||||
|
return ret
|
||||||
81
polycount/cell1/carry2d/carry.py
Normal file
81
polycount/cell1/carry2d/carry.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
from typing import Sequence
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_carry(arr: np.ndarray) -> tuple[int, tuple[int, int]]:
|
||||||
|
"""
|
||||||
|
Ensure that `arr` is interpretable as an explicit carry rule.
|
||||||
|
See `Carry` for more information.
|
||||||
|
"""
|
||||||
|
overflow = None
|
||||||
|
over_pos = None
|
||||||
|
coeff_sum = 0
|
||||||
|
# find largest digit for carry
|
||||||
|
for i, row in enumerate(arr):
|
||||||
|
for j, val in enumerate(row):
|
||||||
|
coeff_sum += val
|
||||||
|
if val < 0:
|
||||||
|
if overflow is not None:
|
||||||
|
raise ValueError("Array supplied has more than one overflow digit")
|
||||||
|
overflow = -val
|
||||||
|
over_pos = (i, j)
|
||||||
|
|
||||||
|
if coeff_sum < 0:
|
||||||
|
raise ValueError("Sum of coefficients too small")
|
||||||
|
|
||||||
|
if overflow is None or over_pos is None:
|
||||||
|
raise ValueError("No dominating term supplied")
|
||||||
|
|
||||||
|
return overflow, over_pos
|
||||||
|
|
||||||
|
|
||||||
|
class Carry:
|
||||||
|
"""
|
||||||
|
Two-dimensional carry rule.
|
||||||
|
|
||||||
|
This is an (integer) Numpy array which is greedily "applied" to another (integer) Numpy array to
|
||||||
|
rid it of integers.
|
||||||
|
Only "explicit" carries are allowed -- these are carries that are all negative except for a
|
||||||
|
single positive term, such that the sum of all terms is non-negative.
|
||||||
|
|
||||||
|
For example, the Laplacian kernel, as a carry rule is:
|
||||||
|
`laplace = Carry([[0,1,0],[1,-4,1],[0,1,0]])`
|
||||||
|
|
||||||
|
Interpreted as a carry rule, this spreads integers above 4 into their neighboring cells.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, arr: np.ndarray | Sequence):
|
||||||
|
if not isinstance(arr, np.ndarray):
|
||||||
|
arr = np.array(arr)
|
||||||
|
overflow, over_pos = _validate_carry(arr)
|
||||||
|
|
||||||
|
self._arr: np.ndarray = arr
|
||||||
|
self.over_pos: tuple[int, int] = over_pos
|
||||||
|
self.overflow: int = overflow
|
||||||
|
|
||||||
|
def _apply(
|
||||||
|
self,
|
||||||
|
base: np.ndarray,
|
||||||
|
update_tuples: list[tuple[int, int]],
|
||||||
|
zerowall: np.ndarray,
|
||||||
|
):
|
||||||
|
"""Apply the carry at the locations in `base` specified by `update_tuples`."""
|
||||||
|
pos_x, pos_y = self.over_pos
|
||||||
|
for x, y in update_tuples:
|
||||||
|
idx = base[(x, y)]
|
||||||
|
dec = idx // self.overflow # - 1
|
||||||
|
|
||||||
|
wall = zerowall.copy()
|
||||||
|
sh_x, sh_y = self._arr.shape
|
||||||
|
x -= pos_x
|
||||||
|
y -= pos_y
|
||||||
|
|
||||||
|
wall[x : x + sh_x, y : y + sh_y] = dec * self._arr
|
||||||
|
base += wall
|
||||||
|
|
||||||
|
def apply(self, base: np.ndarray) -> np.ndarray:
|
||||||
|
"""Update an expansion `base` according to this carry."""
|
||||||
|
zerowall = np.zeros(base.shape, dtype=base.dtype)
|
||||||
|
while update_tuples := list(zip(*np.where(base >= self.overflow))):
|
||||||
|
self._apply(base, update_tuples, zerowall)
|
||||||
|
return base
|
||||||
88
polycount/cell1/carry2d/curve.py
Normal file
88
polycount/cell1/carry2d/curve.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
from sympy.abc import x, y
|
||||||
|
from sympy.plotting import plot_implicit
|
||||||
|
|
||||||
|
from .anim import animate
|
||||||
|
|
||||||
|
def _first_nonzero(arr: np.ndarray, axis: int):
|
||||||
|
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
|
||||||
|
):
|
||||||
|
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}"
|
||||||
|
|
||||||
|
|
||||||
|
def poly_from_array(array):
|
||||||
|
ret = 0
|
||||||
|
for i, row in enumerate(array):
|
||||||
|
for j, val in enumerate(row):
|
||||||
|
ret += val*(x**i * y**j)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def bindfig(fig):
|
||||||
|
def ret(**kwargs):
|
||||||
|
for i, j in kwargs.items():
|
||||||
|
if i == "figsize":
|
||||||
|
if j is not None:
|
||||||
|
fig.set_figwidth(j[0])
|
||||||
|
fig.set_figheight(j[1])
|
||||||
|
continue
|
||||||
|
fig.__dict__["set_" + i](j)
|
||||||
|
return fig
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def anim_curves(next_func, dims=25, invalid=2, frames=None, interval=200):
|
||||||
|
zero = np.zeros((dims, dims), dtype=np.int32)
|
||||||
|
#zero[0,0] = 1
|
||||||
|
fig = plt.gcf()
|
||||||
|
#plt.colorbar()
|
||||||
|
|
||||||
|
#temp = plt.figure
|
||||||
|
#I hate doing it, but there's no other way to get the figure before it's plotted
|
||||||
|
plt.figure = bindfig(fig)
|
||||||
|
|
||||||
|
@animate(fig, frames, interval=interval)
|
||||||
|
def ret(fr):
|
||||||
|
next_func(zero, invalid)
|
||||||
|
fig.clf()
|
||||||
|
plot_implicit(
|
||||||
|
poly_from_array(zero) - fr,
|
||||||
|
backend='matplotlib',
|
||||||
|
adaptive=False
|
||||||
|
)
|
||||||
|
plt.title(f"{fr+1}")
|
||||||
|
print(fr)
|
||||||
|
|
||||||
|
return ret
|
||||||
78
polycount/cell1/carry2d/extra.py
Normal file
78
polycount/cell1/carry2d/extra.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from .carry import Carry
|
||||||
|
|
||||||
|
xy_2 = Carry([[2,-1],[-1,0]])
|
||||||
|
xy_3 = Carry([[3,-1],[-1,0]])
|
||||||
|
x2y_3 = Carry([[3,-2],[-1,0]])
|
||||||
|
x3y_4 = Carry([[4,-3],[-1,0]])
|
||||||
|
|
||||||
|
laplace = Carry([[0,-1,0],[-1,4,-1],[0,-1,0]])
|
||||||
|
laplace3 = Carry([[0,0,0],[-1,3,-1],[0,-1,0]])
|
||||||
|
|
||||||
|
almost_folium = Carry([[0,0,-1], [0,2,0], [-1,0,0]])
|
||||||
|
folium = Carry([
|
||||||
|
[ 0,0,0,-1],
|
||||||
|
[ 0,2,0, 0],
|
||||||
|
[ 0,0,0, 0],
|
||||||
|
[-1,0,0, 0]
|
||||||
|
])
|
||||||
|
folium3 = Carry([
|
||||||
|
[ 0,0,0,-1],
|
||||||
|
[ 0,3,0, 0],
|
||||||
|
[ 0,0,0, 0],
|
||||||
|
[-1,0,0, 0]
|
||||||
|
])
|
||||||
|
folium4 = Carry([
|
||||||
|
[ 0, 0, 0,-1, 0],
|
||||||
|
[ 0, 0, 0, 0,-1],
|
||||||
|
[ 0, 0, 4, 0, 0],
|
||||||
|
[-1, 0, 0, 0, 0],
|
||||||
|
[ 0,-1, 0, 0, 0]
|
||||||
|
])
|
||||||
|
|
||||||
|
def triangle_spread(n):
|
||||||
|
ret = np.zeros((n + 1, n + 1), dtype=np.int32)
|
||||||
|
ret[0, 0] = -1
|
||||||
|
ret[1, 1] = 3
|
||||||
|
ret[n, 0] = -1
|
||||||
|
ret[0, n] = -1
|
||||||
|
return ret
|
||||||
|
|
||||||
|
triangle1 = Carry(triangle_spread(1))
|
||||||
|
triangle2 = Carry(triangle_spread(2))
|
||||||
|
triangle3 = Carry(triangle_spread(3)) #factorable!
|
||||||
|
triangle4 = Carry(triangle_spread(4))
|
||||||
|
|
||||||
|
tri3_rot = Carry([
|
||||||
|
[ 0, 0,-1, 0, 0],
|
||||||
|
[ 0, 0, 3, 0, 0],
|
||||||
|
[-1, 0, 0, 0,-1]
|
||||||
|
])
|
||||||
|
|
||||||
|
tri3_rot_real = Carry([
|
||||||
|
[ 0, 0, 0,-1, 0, 0, 0],
|
||||||
|
[ 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
[ 0, 0, 0, 3, 0, 0, 0],
|
||||||
|
[-1, 0, 0, 0, 0, 0,-1]
|
||||||
|
])
|
||||||
|
|
||||||
|
tri3_rot2 = Carry([
|
||||||
|
[ 0,-1, 0],
|
||||||
|
[ 0, 3, 0],
|
||||||
|
[-1, 0,-1]
|
||||||
|
])
|
||||||
|
|
||||||
|
tri3_tall = Carry([
|
||||||
|
[ 0,-1, 0],
|
||||||
|
[ 0, 0, 0],
|
||||||
|
[ 0, 3, 0],
|
||||||
|
[-1, 0,-1]
|
||||||
|
])
|
||||||
|
|
||||||
|
tri3_tall2 = Carry([
|
||||||
|
[ 0,-1, 0],
|
||||||
|
[ 0, 3, 0],
|
||||||
|
[ 0, 0, 0],
|
||||||
|
[-1, 0,-1]
|
||||||
|
])
|
||||||
@ -1,148 +0,0 @@
|
|||||||
from functools import partial
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import sympy
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
from sympy.plotting import plot_implicit
|
|
||||||
from matplotlib import animation
|
|
||||||
|
|
||||||
from carry import Carry
|
|
||||||
|
|
||||||
def make_animation(fig, frames, **kwargs):
|
|
||||||
fig.tight_layout()
|
|
||||||
#why isn't this how the function is exposed by default
|
|
||||||
return lambda func: animation.FuncAnimation(fig, func, frames, init_func=lambda: None, **kwargs)
|
|
||||||
|
|
||||||
def poly_from_array(array):
|
|
||||||
ret = 0
|
|
||||||
for i, row in enumerate(array):
|
|
||||||
for j, val in enumerate(row):
|
|
||||||
ret += val*(x**i * y**j)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
x, y = sympy.symbols("x y")
|
|
||||||
|
|
||||||
|
|
||||||
xy_2 = Carry([[2,-1],[-1,0]])
|
|
||||||
xy_3 = Carry([[3,-1],[-1,0]])
|
|
||||||
x2y_3 = Carry([[3,-2],[-1,0]])
|
|
||||||
x3y_4 = Carry([[4,-3],[-1,0]])
|
|
||||||
|
|
||||||
laplace = Carry([[0,-1,0],[-1,4,-1],[0,-1,0]])
|
|
||||||
laplace3 = Carry([[0,0,0],[-1,3,-1],[0,-1,0]])
|
|
||||||
|
|
||||||
almost_folium = Carry([[0,0,-1], [0,2,0], [-1,0,0]])
|
|
||||||
folium = Carry([[0,0,0,-1], [0,2,0,0], [0,0,0,0], [-1,0,0,0]])
|
|
||||||
folium3 = Carry([[0,0,0,-1], [0,3,0,0], [0,0,0,0], [-1,0,0,0]])
|
|
||||||
folium4 = Carry([ [ 0, 0,0,-1, 0],
|
|
||||||
[ 0, 0,0, 0,-1],
|
|
||||||
[ 0, 0,4, 0, 0],
|
|
||||||
[-1, 0,0, 0, 0],
|
|
||||||
[ 0,-1,0, 0, 0]])
|
|
||||||
|
|
||||||
def triangle_spread(n):
|
|
||||||
ret = np.zeros((n + 1, n + 1), dtype=np.int32)
|
|
||||||
ret[0, 0] = -1
|
|
||||||
ret[1, 1] = 3
|
|
||||||
ret[n, 0] = -1
|
|
||||||
ret[0, n] = -1
|
|
||||||
return ret
|
|
||||||
|
|
||||||
triangle1 = Carry(triangle_spread(1))
|
|
||||||
triangle2 = Carry(triangle_spread(2))
|
|
||||||
triangle3 = Carry(triangle_spread(3)) #factorable!
|
|
||||||
triangle4 = Carry(triangle_spread(4))
|
|
||||||
|
|
||||||
tri3_rot = Carry([ [ 0, 0,-1, 0, 0],
|
|
||||||
[ 0, 0, 3, 0, 0],
|
|
||||||
[-1, 0, 0, 0,-1] ])
|
|
||||||
|
|
||||||
tri3_rot_real = Carry([ [ 0, 0, 0,-1, 0, 0, 0],
|
|
||||||
[ 0, 0, 0, 0, 0, 0, 0],
|
|
||||||
[ 0, 0, 0, 3, 0, 0, 0],
|
|
||||||
[-1, 0, 0, 0, 0, 0,-1] ])
|
|
||||||
|
|
||||||
tri3_rot2 = Carry([ [ 0,-1, 0],
|
|
||||||
[ 0, 3, 0],
|
|
||||||
[-1, 0,-1] ])
|
|
||||||
|
|
||||||
tri3_tall = Carry([ [ 0,-1, 0],
|
|
||||||
[ 0, 0, 0],
|
|
||||||
[ 0, 3, 0],
|
|
||||||
[-1, 0,-1] ])
|
|
||||||
|
|
||||||
tri3_tall2 = Carry([ [ 0,-1, 0],
|
|
||||||
[ 0, 3, 0],
|
|
||||||
[ 0, 0, 0],
|
|
||||||
[-1, 0,-1] ])
|
|
||||||
|
|
||||||
def start_anim(dims=100, carry=xy_2, frames=None, interval=200, inter='add', i_val=1, center=(0,0)):
|
|
||||||
if center == (0,0) and carry.over_pos != center:
|
|
||||||
center = (dims // 2, dims // 2)
|
|
||||||
|
|
||||||
if inter == 'add':
|
|
||||||
next_func = partial(carry.add, val=i_val, center=center)
|
|
||||||
elif inter == 'mult':
|
|
||||||
if i_val == 1:
|
|
||||||
raise ValueError(f"too small value {i_val} for repeated multiplication")
|
|
||||||
next_func = partial(carry.mult, val=i_val, center=center)
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Cannot use {repr(inter)} for animation")
|
|
||||||
|
|
||||||
zero = np.zeros((dims, dims))
|
|
||||||
zero[center] = 1
|
|
||||||
val = [1]
|
|
||||||
|
|
||||||
fig = plt.gcf()
|
|
||||||
plt.title('0')
|
|
||||||
image = plt.imshow(zero)
|
|
||||||
image.set_clim(0, carry.overflow-1)
|
|
||||||
|
|
||||||
@make_animation(fig, frames, interval=interval)
|
|
||||||
def ret(fr):
|
|
||||||
next_func(zero)
|
|
||||||
# if next_func != xy_2.add:
|
|
||||||
# fr = sum(i*(invalid**j) for i,j in zip(zero[0], range(dims))) - 1
|
|
||||||
if inter == 'add':
|
|
||||||
val[0] += i_val
|
|
||||||
else:
|
|
||||||
val[0] *= i_val
|
|
||||||
plt.title(f"{val[0]}")
|
|
||||||
image.set_data(zero)
|
|
||||||
fig.tight_layout()
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def anim_curves(dims=25, invalid=2, frames=None, interval=200, next_func=xy_2.add):
|
|
||||||
zero = np.zeros((dims, dims), dtype=np.int32)
|
|
||||||
#zero[0,0] = 1
|
|
||||||
fig = plt.gcf()
|
|
||||||
#plt.colorbar()
|
|
||||||
|
|
||||||
#temp = plt.figure
|
|
||||||
#I hate doing it, but there's no other way to get the figure before it's plotted
|
|
||||||
plt.figure = bindfig(fig)
|
|
||||||
|
|
||||||
@make_animation(fig, frames, interval=interval)
|
|
||||||
def ret(fr):
|
|
||||||
next_func(zero, invalid)
|
|
||||||
fig.clf()
|
|
||||||
plot = plot_implicit(poly_from_array(zero) - fr, backend='matplotlib')
|
|
||||||
plt.title(f"{fr+1}")
|
|
||||||
print(fr)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
writer = animation.writers['ffmpeg'](fps=15, metadata={'artist': 'Me'})
|
|
||||||
|
|
||||||
def bindfig(fig):
|
|
||||||
def ret(**kwargs):
|
|
||||||
for i, j in kwargs.items():
|
|
||||||
if i == "figsize":
|
|
||||||
if j is not None:
|
|
||||||
fig.set_figwidth(j[0])
|
|
||||||
fig.set_figheight(j[1])
|
|
||||||
continue
|
|
||||||
fig.__dict__["set_" + i](j)
|
|
||||||
return fig
|
|
||||||
return ret
|
|
||||||
Loading…
x
Reference in New Issue
Block a user