;;;================================================================== ;;; Computing PI. ;;;================================================================== ;;;------------------------------------------------------------------ ;;; Serial version. (defn pi [num-rects] (let [width (/ 1.0 num-rects)] (loop [i 0 sum 0] (if (= i num-rects) (* width sum) (let [mid (* (+ i 0.5) width) height (/ 4.0 (+ 1 (* mid mid)))] (recur (inc i) (+ sum height))))))) ;;;------------------------------------------------------------------ ;;; Serial version using sequences. (defn pi2 [num-rects] (let [width (/ 1.0 num-rects)] (->> (for [i (range num-rects) :let [mid (* (+ i 0.5) width) height (/ 4.0 (+ 1 (* mid mid)))]] height) (reduce +) (* width)))) (def num-procs (.availableProcessors (Runtime/getRuntime))) ;;;------------------------------------------------------------------ ;;; Parallel version. (defn ppi [num-rects] (->> (generate-ranges num-rects num-procs) (pmap (fn [[start finish]] (pi-split start finish num-rects))) (reduce +))) (defn generate-ranges [n t] (let [size (/ n t)] (->> (range 0 n size) (map #(vector % (+ % size)))))) (defn pi-split [start finish num-rects] (let [width (/ 1.0 num-rects)] (loop [i start sum 0] (if (= i finish) (* width sum) (let [mid (* (+ i 0.5) width) height (/ 4.0 (+ 1 (* mid mid)))] (recur (inc i) (+ sum height)))))))