Skip to content

Commit

Permalink
Remove 3d randomwalk (#17)
Browse files Browse the repository at this point in the history
* Erase 3D random walks

* Hard-code moves

* Update examples
  • Loading branch information
rytheranderson authored Apr 13, 2024
1 parent 3a91a59 commit 54299b4
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 73 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,9 @@ plt.savefig("example_images/lyapunov_ex.png")
Image produced with this code:

```python
basis = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
moves = pf.construct_moves(basis)
res = pf.randomwalk(moves, niter=5000000, width=4, height=3, depth=10, dpi=300)
pf.images.randomwalk_image(res, cmap=colormaps["gist_yarg"], gamma=1.0)
moves = pf.construct_moves((1, 0), (0, 1))
res = pf.randomwalk(moves, niter=1000000, width=4, height=3, dpi=300)
pf.images.image(res, cmap=colormaps["gnuplot"], gamma=1.0)
plt.savefig("example_images/randomwalk_ex.png")
```

Expand Down Expand Up @@ -140,13 +139,12 @@ plt.savefig("example_images/buddhabrot_ex.png")
* Julia
* Buddhabrot
* Markus-Lyapunov
* 3D random walks
* 2D random walks

## Image Creation
* Function `image` wrapping `matplotlib.pyplot.imshow`
* Function `nebula_image` for Buddhabrot ["nebula"](https://en.wikipedia.org/wiki/Buddhabrot#Nuances) coloration
* Function `markus_lyapunov_image` for [Markus-Lyapunov](https://doi.org/10.1016/0097-8493(89)90019-8) coloration
* Function `randomwalk_image` for coloring 3D random walks with depth
* Function `save_animation` for animating a sequence of results

## More than Quadratic Polynomials
Expand Down
Binary file modified example_images/randomwalk_ex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 2 additions & 4 deletions examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,8 @@ def lyapunov_example() -> None:

def randomwalk_example() -> None:
start_time = time.time()
basis = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
moves = pf.construct_moves(basis)
res = pf.randomwalk(moves, niter=5000000, width=4, height=3, depth=10, dpi=300)
pf.images.randomwalk_image(res, cmap=colormaps["gist_yarg"], gamma=1.0)
res = pf.randomwalk(niter=1000000, width=4, height=3, dpi=300)
pf.images.image(res, cmap=colormaps["gnuplot"], gamma=1.0)
plt.savefig("example_images/randomwalk_ex.png")
print(f"calculation took {round((time.time() - start_time), 2)} seconds")

Expand Down
3 changes: 1 addition & 2 deletions pyfracgen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .julia import julia
from .lyapunov import lyapunov
from .mandelbrot import mandelbrot
from .randomwalk import construct_moves, randomwalk
from .randomwalk import randomwalk

__all__ = [
"buddhabrot",
Expand All @@ -15,7 +15,6 @@
"lyapunov",
"mandelbrot",
"randomwalk",
"construct_moves",
"Result",
"Canvas",
"funcs",
Expand Down
10 changes: 1 addition & 9 deletions pyfracgen/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import numpy as np

from pyfracgen.types import Bound, Lattice, Lattice3D
from pyfracgen.types import Bound, Lattice

RESULT_DEFAULT_SAVE = Path("save.pickle")

Expand Down Expand Up @@ -48,14 +48,6 @@ def paint(self, *args: Any, **kwargs: Any) -> None:
raise NotImplementedError


class Canvas3D(Canvas):
def __init__(self, width: int, height: int, depth: int, dpi: int) -> None:
super().__init__(width, height, dpi)
self.lattice: Lattice3D = np.dstack(
[np.zeros(self.lattice.shape) for _ in range(depth)]
)


class CanvasBounded(Canvas):
def __init__(
self, width: int, height: int, dpi: int, xbound: Bound, ybound: Bound
Expand Down
25 changes: 0 additions & 25 deletions pyfracgen/images/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,31 +96,6 @@ def markus_lyapunov_image(
return fig, ax0


def randomwalk_image(
res: Result,
cmap: colors.Colormap = DEFAULT_COLORMAP,
ticks: bool = False,
gamma: float = 0.3,
alpha_scale: float = 1.0,
) -> tuple[Figure, Axes]:
fig, ax0 = plt.subplots(figsize=figaspect(res.image_array[:, :, 0]), dpi=res.dpi)
fig.subplots_adjust(0, 0, 1, 1)
max_ind = float(res.image_array.shape[-1] + 1)
for i in range(res.image_array.shape[-1]):
im = res.image_array[..., i]
im = np.ma.masked_where(im == 0, im) # type: ignore[no-untyped-call]
alpha = alpha_scale * (1 - (i + 1) / max_ind)
norm = colors.PowerNorm(gamma)
ax0.imshow(
im, origin="lower", alpha=alpha, cmap=cmap, norm=norm, interpolation=None
)
if not ticks:
plt.axis(ticks)
fs = plt.gcf()
fs.set_size_inches(res.width_inches, res.height_inches)
return fig, ax0


def save_animation(
series: Sequence[Result],
cmap: colors.Colormap = DEFAULT_COLORMAP,
Expand Down
39 changes: 14 additions & 25 deletions pyfracgen/randomwalk.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,39 @@
from numpy import array
from numpy.random import randint

from pyfracgen.common import Canvas3D, Result
from pyfracgen.types import Lattice3D, Moves3D


def construct_moves(basis: Moves3D) -> Moves3D:
basis = np.r_[basis, -1 * basis, [array([0, 0, 0])]]
nonnull = list(
filter(lambda x: np.any(x), (b0 + b1 for b0, b1 in itt.combinations(basis, 2)))
)
moves: Moves3D = np.unique(nonnull, axis=0)
return moves
from pyfracgen.common import Result, Canvas
from pyfracgen.types import Moves, Lattice


@jit(nopython=True) # type: ignore[misc]
def _randomwalk_paint(
lattice: Lattice3D,
moves: Moves3D,
lattice: Lattice,
moves: Moves,
niter: int,
) -> None:
nmoves = len(moves)
h, w, d = lattice.shape
indices = array([h, w, d]) / 2.0
h, w = lattice.shape
indices = array([h, w]) / 2.0
for iteration in range(niter):
move = moves[randint(0, nmoves)]
indices += move
iy, ix, iz = int(indices[0] % h), int(indices[1] % w), int(indices[2] % d)
lattice[iy, ix, iz] = iteration
iy, ix = int(indices[0] % h), int(indices[1] % w)
lattice[iy, ix] = iteration

lattice /= np.amax(lattice)

class RandomWalk(Canvas):
moves = np.array(list(itt.product([1, -1, 0], [1, -1, 0])))

class RandomWalk(Canvas3D):
def paint(self, moves: Moves3D, niter: int) -> None:
_randomwalk_paint(self.lattice, moves, niter)
def paint(self, niter: int) -> None:
_randomwalk_paint(self.lattice, self.moves, niter)


def randomwalk(
moves: Moves3D,
niter: int,
width: int = 5,
height: int = 4,
depth: int = 1,
dpi: int = 300,
) -> Result:
canvas = RandomWalk(width, height, depth, dpi)
canvas.paint(moves, niter)
canvas = RandomWalk(width, height, dpi)
canvas.paint(niter)
return canvas.result
3 changes: 1 addition & 2 deletions pyfracgen/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
Depth = NewType("Depth", int)

Lattice = NDArray[Shape["Height, Width"], Float64]
Lattice3D = NDArray[Shape["Height, Width, Depth"], Float64]
Moves3D = NDArray[Shape["*, 3"], Int64]
Moves = NDArray[Shape["*, 2"], Int64]
Boxes = NDArray[Shape["*, 2"], Float64]
ComplexSequence = NDArray[Shape["*"], Complex128]

Expand Down

0 comments on commit 54299b4

Please sign in to comment.