Let’s take a look at a somewhat more interesting example than the overused Fibonacci and prime number generators that are often used for microbenchmarking numeric performance. Visualizing the Mandelbrot Set (or really, any fractal shape visualization) has long been a common practicum, and it will serve well here as a demonstration of how to optimize numeric algorithms in Clojure.
The Mandelbrot Set is defined by a complex polynomial that is applied iteratively:
zk+1 = zk2 + c
where c (a complex number) is a member of the Mandelbrot Set if zk+1 is bounded as k increases when z0 is initialized to 0. c’s that produce unbounded results from this calculation are said to escape to infinity.
First, let’s look at a naive implementation of the Mandelbrot Set in Clojure, which includes a couple utility functions for rendering the results of that implementation:
Example 11-4. Mandelbrot Set in Clojure
(ns clojureprogramming.mandelbrot (:import java.awt.image.BufferedImage (java.awt Color RenderingHints))) (defn- escape "Returns an integer indicating how many iterations were required before the value of z (using the components `a` and `b`) could be determined to have escaped the Mandelbrot set. If z will not escape, -1 is returned." [a0 b0 depth] (loop [a a0 b b0 iteration 0] (cond (< 4 (+ (* a a) (* b b))) iteration (>= iteration depth) -1 :else (recur (+ a0 (- (* a a) (* b b))) (+ b0 (* 2 (* a b))) (inc iteration))))) (defn mandelbrot "Calculates ...