Increase efficiency in Clojure Mandelbrot generator - clojure

I wanted to learn Clojure and started with a Mandelbrot generator using quil, I got it to work - however it takes some time to generate images and is a massive resource hog. Any advice for how to make it faster or if you spot any un-clojure-esque parts of my code.
Core.clj
(ns frac.core
(:require [quil.core :as q])
(:require [frac.complex :refer :all]))
(def scale (atom 0.01))
(def xoff (atom -200))
(def yoff (atom -200))
(def its 50)
(defn mandelbrot [r i]
(count (take its (take-while #(<= (modu %) 2) (iterate #( add (mul % %) [r i]) [r i])))))
(defn gen []
(let [p (q/pixels)
w (q/width)
h (q/height)]
(doseq [x (range w) y (range h)]
(let [m (mandelbrot (* #scale (+ x #xoff)) (* #scale (+ y #yoff)))
c (if (= m its) 0 m)]
(aset p (+ x (* y w)) (q/color (* 1.5 c) (* 4 c) (* 5.2 c))))))
(q/update-pixels))
(defn setup []
(gen))
(defn draw [])
(defn click []
(swap! xoff #(+ (q/mouse-x) (- (/ (q/width) 2)) %))
(swap! yoff #(+ (q/mouse-y) (- (/ (q/height) 2)) %))
(gen))
(defn wheel [z]
(swap! scale #(if (pos? z) (* 1.1 %) (* 0.9 %)))
(prn #scale)
(gen))
(q/defsketch example
:title "Mandel"
:setup setup
:draw draw
:size [400 400]
:mouse-clicked click
:mouse-wheel wheel)
(defn -main [& args])
Complex.clj
(ns frac.complex)
(defn mul [z1 z2]
(let [r1 (first z1)
i1 (second z1)
r2 (first z2)
i2 (second z2)]
[(- (* r1 r2) (* i1 i2)) (+ (* r1 i2) (* r2 i1))]))
(defn add [z1 z2]
(let [r1 (first z1)
i1 (second z1)
r2 (first z2)
i2 (second z2)]
[(+ r1 r2) (+ i1 i2)]))
(defn modu [z]
(let [r (first z)
i (second z)]
(Math/sqrt (+ (* r r) (* i i)))))

Try set this:
(set! *unchecked-math* :warn-on-boxed)
and remove all warnings. Use type hints as needed.

Related

Genetic programming Clojure

I've pasted the code on this page in an IDE and it works. The problem is that when I replace the definition of target-data with this vector of pairs* it gives me this error**.
(vector [[1 2]
[2 3]
[3 4]
[4 5]] ) ; *
UnsupportedOperationException nth not supported on this type: core$vector clojure.lang.RT.nthFrom (RT.java:857) **
What should I do to use my own target-data?
UPDATED FULL CODE:
(ns evolvefn.core)
;(def target-data
; (map #(vector % (+ (* % %) % 1))
; (range -1.0 1.0 0.1)))
;; We'll use input (x) values ranging from -1.0 to 1.0 in increments
;; of 0.1, and we'll generate the target [x y] pairs algorithmically.
;; If you want to evolve a function to fit your own data then you could
;; just paste a vector of pairs into the definition of target-data instead.
(def target-data
(vec[1 2]
[2 3]
[3 4]
[4 5]))
;; An individual will be an expression made of functions +, -, *, and
;; pd (protected division), along with terminals x and randomly chosen
;; constants between -5.0 and 5.0. Note that for this problem the
;; presence of the constants actually makes it much harder, but that
;; may not be the case for other problems.
(defn random-function
[]
(rand-nth '(+ - * pd)))
(defn random-terminal
[]
(rand-nth (list 'x (- (rand 10) 5))))
(defn random-code
[depth]
(if (or (zero? depth)
(zero? (rand-int 2)))
(random-terminal)
(list (random-function)
(random-code (dec depth))
(random-code (dec depth)))))
;; And we have to define pd (protected division):
(defn pd
"Protected division; returns 0 if the denominator is zero."
[num denom]
(if (zero? denom)
0
(/ num denom)))
;; We can now evaluate the error of an individual by creating a function
;; built around the individual, calling it on all of the x values, and
;; adding up all of the differences between the results and the
;; corresponding y values.
(defn error
[individual]
(let [value-function (eval (list 'fn '[x] individual))]
(reduce + (map (fn [[x y]]
(Math/abs
(- (value-function x) y)))
target-data))))
;; We can now generate and evaluate random small programs, as with:
;; (let [i (random-code 3)] (println (error i) "from individual" i))
;; To help write mutation and crossover functions we'll write a utility
;; function that injects something into an expression and another that
;; extracts something from an expression.
(defn codesize [c]
(if (seq? c)
(count (flatten c))
1))
(defn inject
"Returns a copy of individual i with new inserted randomly somwhere within it (replacing something else)."
[new i]
(if (seq? i)
(if (zero? (rand-int (count (flatten i))))
new
(if (< (rand)
(/ (codesize (nth i 1))
(- (codesize i) 1)))
(list (nth i 0) (inject new (nth i 1)) (nth i 2))
(list (nth i 0) (nth i 1) (inject new (nth i 2)))))
new))
(defn extract
"Returns a random subexpression of individual i."
[i]
(if (seq? i)
(if (zero? (rand-int (count (flatten i))))
i
(if (< (rand) (/ (codesize (nth i 1))
(- (codesize i)) 1))
(extract (nth i 1))
(extract (nth i 2))))
i))
;; Now the mutate and crossover functions are easy to write:
(defn mutate
[i]
(inject (random-code 2) i))
(defn crossover
[i j]
(inject (extract j) i))
;; We can see some mutations with:
;; (let [i (random-code 2)] (println (mutate i) "from individual" i))
;; and crossovers with:
;; (let [i (random-code 2) j (random-code 2)]
;; (println (crossover i j) "from" i "and" j))
;; We'll also want a way to sort a populaty by error that doesn't require
;; lots of error re-computation:
(defn sort-by-error
[population]
(vec (map second
(sort (fn [[err1 ind1] [err2 ind2]] (< err1 err2))
(map #(vector (error %) %) population)))))
;; Finally, we'll define a function to select an individual from a sorted
;; population using tournaments of a given size.
(defn select
[population tournament-size]
(let [size (count population)]
(nth population
(apply min (repeatedly tournament-size #(rand-int size))))))
;; Now we can evolve a solution by starting with a random population and
;; repeatedly sorting, checking for a solution, and producing a new
;; population.
(defn evolve
[popsize]
(println "Starting evolution...")
(loop [generation 0
population (sort-by-error (repeatedly popsize #(random-code 2)))]
(let [best (first population)
best-error (error best)]
(println "======================")
(println "Generation:" generation)
(println "Best error:" best-error)
(println "Best program:" best)
(println " Median error:" (error (nth population
(int (/ popsize 2)))))
(println " Average program size:"
(float (/ (reduce + (map count (map flatten population)))
(count population))))
(if (< best-error 0.1) ;; good enough to count as success
(println "Success:" best)
(recur
(inc generation)
(sort-by-error
(concat
(repeatedly (* 1/2 popsize) #(mutate (select population 7)))
(repeatedly (* 1/4 popsize) #(crossover (select population 7)
(select population 7)))
(repeatedly (* 1/4 popsize) #(select population 7)))))))))
;; Run it with a population of 1000:
(evolve 1000)
And the error is:
(evolve 1000)
Starting evolution...
IllegalArgumentException No matching method found: abs clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
evolvefn.core=>

Lazy sequence using loop/recur?

I'd like to write an implementation to an algorithm that produces an infinite sequence of results, where each element represents the calculation of a single iteration of the algorithm. Using a lazy sequence is convenient, as it decouples the logic of the number of iterations (by using take) and burn-in iterations (by using drop) from the implementation.
Here's an example of two algorithm implementations, one that produces a lazy sequence (yadda-lazy), and one that does not (yadda-loop).
(defn yadda-iter
[v1 v2 v3]
(+ (first v1)
(first v2)
(first v3)))
(defn yadda-lazy
[len]
(letfn [(inner [v1 v2 v3]
(cons (yadda-iter v1 v2 v3)
(lazy-seq (inner (rest v1)
(rest v2)
(rest v3)))))]
(let [base (cycle (range len))]
(inner base
(map #(* %1 %1) base)
(map #(* %1 %1 %1) base)))))
(defn yadda-loop
[len iters]
(let [base (cycle (range len))]
(loop [result nil
i 0
v1 base
v2 (map #(* %1 %1) base)
v3 (map #(* %1 %1 %1) base)]
(if (= i iters)
result
(recur (cons (yadda-iter v1 v2 v3) result)
(inc i)
(rest v1)
(rest v2)
(rest v3))))))
(prn (take 11 (yadda-lazy 4)))
(prn (yadda-loop 4 11))
Is there a way to create a lazy sequence using the same style as loop/recur? I like yadda-loop better, because:
It's more obvious what the initial conditions are and how the algorithm progresses to the next iteration.
It won't suffer from a stack overflow due to tail optimization.
Your loop version would be better written to (1) pull the addition out of the loop so you don't have to recur on so many sequences, and (2) use conj on a vector accumulator so your results are in the same order as your yadda-lazy.
(defn yadda-loop-2 [len iters]
(let [v1 (cycle (range len))
v2 (map * v1 v1)
v3 (map * v1 v2)
s (map + v1 v2 v3)]
(loop [result [], s s, i 0]
(if (= i iters)
result
(recur (conj result (first s)), (rest s), (inc i))))))
However, at this point it becomes clear that the loop is pointless as this is just
(defn yadda-loop-3 [len iters]
(let [v1 (cycle (range len))
v2 (map * v1 v1)
v3 (map * v1 v2)
s (map + v1 v2 v3)]
(into [] (take iters s))))
and we might as well pull out the iters parameter, return simply s and take from it.
(defn yadda-yadda [len]
(let [v1 (cycle (range len))
v2 (map * v1 v1)
v3 (map * v1 v2)]
(map + v1 v2 v3)))
This produces the same results as your yadda-lazy, is also lazy, and is quite clear
(take 11 (yadda-yadda 4)) ;=> (0 3 14 39 0 3 14 39 0 3 14)
You could also, equivalently
(defn yadda-yadda [len]
(as-> (range len) s
(cycle s)
(take 3 (iterate (partial map * s) s))
(apply map + s)))
Addendum
If you are looking for a pattern for converting an eager loop like yours to a lazy-sequence
(loop [acc [] args args] ...) -> ((fn step [args] ...) args)
(if condition (recur ...) acc) -> (when condition (lazy-seq ...)
(recur (conj acc (f ...)) ...) -> (lazy-seq (cons (f ...) (step ...)))
Applying this to your yadda-lazy
(defn yadda-lazy-2 [len iters]
(let [base (cycle (range len))]
((fn step [i, v1, v2, v3]
(when (< i iters)
(lazy-seq
(cons (yadda-iter v1 v2 v3)
(step (inc i), (rest v1), (rest v2), (rest v3))))))
0, base, (map #(* %1 %1) base), (map #(* %1 %1 %1) base))))
And at this point you'd probably want to pull out the iters
(defn yadda-lazy-3 [len]
(let [base (cycle (range len))]
((fn step [v1, v2, v3]
(lazy-seq
(cons (yadda-iter v1 v2 v3)
(step (rest v1), (rest v2), (rest v3)))))
base, (map #(* %1 %1) base), (map #(* %1 %1 %1) base))))
So you can
(take 11 (yadda-lazy-3 4)) ;=> (0 3 14 39 0 3 14 39 0 3 14)
And then you might say, hey, my yadda-iter is just applying + on the first and step is applied on the rest, so why not combine my v1, v2, v3 and make this a bit clearer?
(defn yadda-lazy-4 [len]
(let [base (cycle (range len))]
((fn step [vs]
(lazy-seq
(cons (apply + (map first vs))
(step (map rest vs)))))
[base, (map #(* %1 %1) base), (map #(* %1 %1 %1) base)])))
And lo and behold, you have just re-implemented variadic map
(defn yadda-lazy-5 [len]
(let [base (cycle (range len))]
(map + base, (map #(* %1 %1) base), (map #(* %1 %1 %1) base))))
#A.Webb's answer is perfect, but if your love for loop/recur overcomes his arguments, know that you can still combine both styles of recursion.
For example, take a look at the implementation of range:
(defn range
(...)
([start end step]
(lazy-seq
(let [b (chunk-buffer 32)
comp (cond (or (zero? step) (= start end)) not=
(pos? step) <
(neg? step) >)]
(loop [i start] ;; chunk building through loop/recur
(if (and (< (count b) 32)
(comp i end))
(do
(chunk-append b i)
(recur (+ i step)))
(chunk-cons (chunk b)
(when (comp i end)
(range i end step))))))))) ;; lazy recursive call
Here's another example, an alternate implementation of filter:
(defn filter [pred coll]
(letfn [(step [pred coll]
(when-let [[x & more] (seq coll)]
(if (pred x)
(cons x (lazy-seq (step pred more))) ;; lazy recursive call
(recur pred more))))] ;; eager recursive call
(lazy-seq (step pred coll))))
The Tupelo library has a new lazy-gen/yield feature that mimics generator functions in Python. It can generate a lazy sequence from any point in a looping structure. Here is version of yadda-loop that shows lazy-gen & yield in action:
(ns tst.xyz
(:use clojure.test tupelo.test)
(:require [tupelo.core :as t] ))
(defn yadda-lazy-gen
[len iters]
(t/lazy-gen
(let [base (cycle (range len))]
(loop [i 0
v1 base
v2 (map #(* %1 %1) base)
v3 (map #(* %1 %1 %1) base)]
(when (< i iters)
(t/yield (yadda-iter v1 v2 v3))
(recur
(inc i)
(rest v1)
(rest v2)
(rest v3)))))))
Testing tst.clj.core
(take 11 (yadda-lazy 4)) => (0 3 14 39 0 3 14 39 0 3 14)
(yadda-loop 4 11) => (0 3 14 39 0 3 14 39 0 3 14)
(yadda-lazy-gen 4 11) => (0 3 14 39 0 3 14 39 0 3 14)
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

Simplify this monad expression

I'm working through some of my own examples after watching this tutorial: http://www.infoq.com/presentations/Why-is-a-Monad-Like-a-Writing-Desk and reading http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html.
I have come up with the following functions:
(defn unit [v s]
(fn [] [v s]))
(defn bind [mv f]
(f (mv)))
(defn inc+ [mv]
(bind
mv
(fn [[v s]]
(let [r (inc v)]
(unit r (apply str (concat s " inc+(" (str r) ")")))))))
(defn double+ [mv]
(bind
mv
(fn [[v s]]
(let [r (* 2 v)]
(unit r (apply str (concat s " double+(" (str r) ")")))))))
(defn triple+ [mv]
(bind
mv
(fn [[v s]]
(let [r (* 3 v)]
(unit r (apply str (concat s " triple+(" (str r) ")")))))))
;; Testing:
((-> (unit 1 "1 ->") inc+))
;; => [2 "1 -> inc+(2)"]
((-> (unit 3 "3 ->") inc+ double+ inc+))
;; => [27 "3 -> inc+(4) double+(8) inc+(9) triple+(27)"]
I wish to rewrite bind to encapsulate the patterns the methods inc+ double+ and triple+ and get the same output as before. How would this be done?
I figured it out in two stages:
(defn unit [v s]
(fn [] [v s]))
(defn bind [mv f]
(let [[iv is] (mv)
[av as] (f iv)]
(unit av (str is " " as))))
(defn inc+ [mv]
(bind
mv
(fn [v]
[(inc v) (str " inc+(" (inc v) ")")])))
(defn double+ [mv]
(bind
mv
(fn [v]
[(inc v) (str " double+(" (inc v) ")")])))
(defn triple+ [mv]
(bind
mv
(fn [v]
[(inc v) (str " triple+(" (inc v) ")")])))
then:
(defn unit [v s]
(fn [] [v s]))
(defn bind [mv f]
(let [[v s] (mv)
r (f v)
xs (->> (str (type f))
(re-find #"\$([^\$]*)\$?")
second) ]
(unit r (str s " " (str xs "(" r ")")))))
(defn inc+ [mv]
(bind mv inc))
(defn double+ [mv]
(bind mv #(* 2 %)))
(defn triple+ [mv]
(bind mv #(* 3 %)))
((-> (unit 3 "3 ->") inc+ double+ inc+ triple+))
;;=> [27 "3 -> inc_PLUS_(4) double_PLUS_(8) inc_PLUS_(9) triple_PLUS_(27)"]
So looking at other Monad tutorials, especially http://channel9.msdn.com/Shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads, I think I understand the core principles now. 'Monads' really is all about being able to reuse the functions we have on hand. unit and bind have to be designed to work together. Then, its almost quite trivial to compose together functions.
Then one more abstraction to write the do-m operator:
(defn unit [v s]
(fn [] [v s]))
(defn bind [mv f]
(let [[v s] (mv)
r (f v)
xs (->> (str (type f))
(re-find #"\$([^\$]*)\$?")
second) ]
(unit r (str s " " (str xs "(" r ")")))))
(defn double [v] (* 2 v))
(defn triple [v] (* 3 v))
(defn do-m [v & fs]
(let [fn-ms (map #(fn [mv] (bind mv %)) fs)]
(((apply comp (reverse fn-ms)) (unit v (str v "->"))))))
(do-m 3 inc double triple)
;;=> [24 "3 -> inc(4) double(8) triple(24)"]
This is another way to write achieve the same result, notice that the change was to take out the lambda function in unit and the associated calls for bind and do-m.
(defn unit [v s] [v s])
(defn bind [mv f]
(let [[v s] mv
r (f v)
xs (->> (str (type f))
(re-find #"\$([^\$]*)\$?")
second) ]
(unit r (str s " " (str xs "(" r ")")))))
(defn double [v] (* 2 v))
(defn triple [v] (* 3 v))
(defn sqrt [v] (Math/sqrt v))
(defn do-m [v & fs]
(let [fn-ms (map #(fn [mv] (bind mv %)) fs)]
((apply comp (reverse fn-ms)) (unit v (str v " ->")))))
(do-m 3 inc double double triple triple sqrt)
;; => [12.0 "3 -> inc(4) double(8) double(16) triple(48) triple(144) sqrt(12.0)"]

putting clojure code in a loop

(def throws 10)
(defn r-squared [x y]
(+ (* (- 0.5 x) (- 0.5 x))
(* (- 0.5 y) (- 0.5 y))))
(loop [hits 0]
(let [x (rand)
y (rand)]
; still inside the let
(if (< (r-squared x y) 0.25) ;is it a hit or not? if not, try again
(recur (inc hits))
(* 4 (/ hits throws)))))
I got that code working and running until the if condition is true. How can I rewrite it so it takes X as parameter and runs X times?
I basically want to call (r-squared 100) and get how many hits I got as return value.
I think this is what you want, if understend question correctly.
(defn test [n]
(loop [hits 0 n n]
(let [x (rand)
y (rand)]
(if (< n 0)
hits ;// you can put (* 4 (/ hits throws)) here
(if (< (r-squared x y) 0.25)
(recur (inc hits) (dec n))
(recur hits (dec n)))))))
Didn't eval it, so parn might be slightly wrong.
(def throws 10)
(defn r-squared [x y]
(+ (* (- 0.5 x) (- 0.5 x))
(* (- 0.5 y) (- 0.5 y))))
(defn test-r-squared [n]
(loop [hits (int 0) n (int n)]
(let [x (rand)
y (rand)]
; still inside the let
(if (< n 0)
(* 4 (/ hits throws))
(if (< (r-squared x y) 0.25) ;is it a hit or not? if not, try again
(recur (inc hits) (dec n))
(recur hits (dec n)))))))
(defn r-squared [x y]
(+ (* (- 0.5 x) (- 0.5 x))
(* (- 0.5 y) (- 0.5 y))))
(defn hit[]
(let [x (rand) y (rand)]
(< (r-squared x y) 0.25)))
(frequencies (for [i (range 1000)] (hit))) ; {true 787, false 213}

Project Euler #14 and memoization in Clojure

As a neophyte clojurian, it was recommended to me that I go through the Project Euler problems as a way to learn the language. Its definitely a great way to improve your skills and gain confidence. I just finished up my answer to problem #14. It works fine, but to get it running efficiently I had to implement some memoization. I couldn't use the prepackaged memoize function because of the way my code was structured, and I think it was a good experience to roll my own anyways. My question is if there is a good way to encapsulate my cache within the function itself, or if I have to define an external cache like I have done. Also, any tips to make my code more idiomatic would be appreciated.
(use 'clojure.test)
(def mem (atom {}))
(with-test
(defn chain-length
([x] (chain-length x x 0))
([start-val x c]
(if-let [e (last(find #mem x))]
(let [ret (+ c e)]
(swap! mem assoc start-val ret)
ret)
(if (<= x 1)
(let [ret (+ c 1)]
(swap! mem assoc start-val ret)
ret)
(if (even? x)
(recur start-val (/ x 2) (+ c 1))
(recur start-val (+ 1 (* x 3)) (+ c 1)))))))
(is (= 10 (chain-length 13))))
(with-test
(defn longest-chain
([] (longest-chain 2 0 0))
([c max start-num]
(if (>= c 1000000)
start-num
(let [l (chain-length c)]
(if (> l max)
(recur (+ 1 c) l c)
(recur (+ 1 c) max start-num))))))
(is (= 837799 (longest-chain))))
Since you want the cache to be shared between all invocations of chain-length, you would write chain-length as (let [mem (atom {})] (defn chain-length ...)) so that it would only be visible to chain-length.
In this case, since the longest chain is sufficiently small, you could define chain-length using the naive recursive method and use Clojure's builtin memoize function on that.
Here's an idiomatic(?) version using plain old memoize.
(def chain-length
(memoize
(fn [n]
(cond
(== n 1) 1
(even? n) (inc (chain-length (/ n 2)))
:else (inc (chain-length (inc (* 3 n))))))))
(defn longest-chain [start end]
(reduce (fn [x y]
(if (> (second x) (second y)) x y))
(for [n (range start (inc end))]
[n (chain-length n)])))
If you have an urge to use recur, consider map or reduce first. They often do what you want, and sometimes do it better/faster, since they take advantage of chunked seqs.
(inc x) is like (+ 1 x), but inc is about twice as fast.
You can capture the surrounding environment in a clojure :
(defn my-memoize [f]
(let [cache (atom {})]
(fn [x]
(let [cy (get #cache x)]
(if (nil? cy)
(let [fx (f x)]
(reset! cache (assoc #cache x fx)) fx) cy)))))
(defn mul2 [x] (do (print "Hello") (* 2 x)))
(def mmul2 (my-memoize mul2))
user=> (mmul2 2)
Hello4
user=> (mmul2 2)
4
You see the mul2 funciton is only called once.
So the 'cache' is captured by the clojure and can be used to store the values.