This repository contains two complex-plane zoom animations:
- Mandelbrot adapted from a Julia community example
- Newton-fractal implementation that uses Enzyme to differentiate the selected polynomial.
Both animations evaluate an orbit for every pixel, color the result by the number of iterations required to escape or converge, and progressively shrink the complex-plane viewport.
Instantiate the Julia environment from the repository root:
julia --project=. -e 'using Pkg; Pkg.instantiate()'Plots renders the heatmaps and GIFs. The Newton implementation additionally
uses Enzyme for automatic differentiation.
mandelbrot.jl samples each pixel as the complex parameter
c in
The escape-time function returns the first iteration for which
abs2(z) >= 4. The animation zooms toward
-0.5626805 + 0.6422555im, increasing the iteration limit as the viewport gets
smaller so that the boundary remains detailed.
Run it with:
julia --project=. mandelbrot.jlnewton.jl visualizes Newton iteration for the polynomial
For every pixel, the pixel coordinate supplies an independent starting value
z_0. The orbit follows
until abs(p(z)) falls below the convergence tolerance or the iteration limit
is reached. Enzyme computes the complex derivative with forward-mode automatic
differentiation. Because p is holomorphic, seeding the derivative with
1 + 0im produces the usual complex derivative p'(z).
The heatmap stores the convergence iteration for every pixel. log1p is
applied only to spread those integer counts more evenly across the color
palette.
Run the animation with Julia threads enabled:
julia --threads=auto --project=. newton.jl
open newton_fractal.gifThe default animation renders 120 frames at 600 by 600 pixels and zooms around a repelling period-2 point of the Newton map:
0.5309620407446378 + 0.19807575472155833imUnlike an attracting root, a repelling periodic point lies on the Julia set, so arbitrarily small neighborhoods continue to intersect different attracting basins.
This is what the final image looks like:
Ironically, finding a good zoom center was harder than I thought. I initially spammed
center values, then saw how the animation turned out. A little bit of digging had me
solve the equation
find_period2_centers.jl reproduces the search used
to choose the default Newton zoom center. It numerically solves
where N is the Newton map. It then removes the attracting fixed points,
deduplicates numerical solutions, and retains cycles whose multiplier satisfies
Print the selected center and its cycle information with:
julia --project=. find_period2_centers.jlPrint every candidate found by the default grid search with:
julia --project=. find_period2_centers.jl --allThe final selection heuristic favors a strongly repelling point away from the
real and diagonal symmetry axes. Other reported candidates can be passed as
the center keyword to render_newton_animation.
