While logistic and tent maps are entirely deterministic and do not involve any coin tossing, the fern is a probabilistic system. In its core lie four different affine transforms, which give way to new points. The choice of the transform to be used on a particular step is made by a fair coin – or, to be more precise, by a random number generator. I lied a bit when I said that the coin is fair, because the probabilities assigned to each of the four transforms are not equal, hence the coin is unfair too – leave the fact that it has four sides. This way, each of the affine transforms constituting the system is characterized by seven numbers. Four of them are the quotients for scaling and rotating, another two – for translation and the last one is the probability of selecting this particular transform to produce the next point. This looks like something great to implement in a simple program, ain’t it?
(defn affinity [a b c d e f] (fn [x y] [(+ (* a x) (* b y) e) (+ (* c x) (* d y) f)]))
(defn scale [probs] (let [s (apply + probs)] (map #(/ % s) probs))) (defn accumulate [probs] (conj (vec (take (dec (count probs)) (drop 1 (reduce #(conj %1 (+ (last %1) %2))  probs)))) 1))
(defn chooser [probs options] (let [threshes (accumulate (scale probs)) chsr (for [[t o] (map vector threshes options)] [#(< % t) o])] (fn  (let [v (clojure.core/rand)] (loop [[checker option] (first chsr) other (next chsr)] (if (checker v) option (recur (first other) (next other))))))))
(defn fern [transforms] (let [selector (chooser (map #(nth % 6) transforms) (map #(apply affinity (take 6 %)) transforms))] (fn [[x y]] ((selector) x y))))
(def default-fern [[0.0 0.0 0.0 0.16 0.0 0.0 0.01] [0.85 0.04 -0.04 0.85 0.0 1.6 0.85] [0.2 -0.26 0.23 0.22 0.0 1.6 0.07] [-0.15 0.28 0.26 0.24 0.0 0.44 0.07]]) (take 100 (iterate (fern default-fern) [0.0 0.0]))