Permalink
Browse files

Refactored

  • Loading branch information...
1 parent cf96b10 commit 44a4d51e7af9b30940a9a64a8b2520511cc521b3 @pmbauer pmbauer committed Sep 15, 2011
Showing with 58 additions and 61 deletions.
  1. +58 −61 src/main/clojure/alioth/mandelbrot.clj
@@ -24,75 +24,72 @@
~@body
(recur ~adv))))
-(definterface MandelbrotOps
- (generate [])
- (putLine [^long y])
- (^byte getByte [^long x ^long y])
- (^long getByte_inner [^long x ^long y ^long i]))
+(deftype MandelbrotBuffer [^bytes out ^long n ^long m])
+(deftype CXB [^doubles crb ^doubles cib])
-(deftype MandelbrotJob [^bytes out ^long n ^long m ^doubles crb ^doubles cib]
- MandelbrotOps
-
- (generate [this]
- (let [yIdx (atom -1)
- runner (reify Runnable
- (run [_] (let [y (swap! yIdx inc)]
- (if (< y n) (do (.putLine this y) (recur))))))
- pool (map (fn [_] (Thread. runner)) (range (* 2 (.availableProcessors (Runtime/getRuntime)))))]
- (doseq [^Thread thread pool]
- (.start thread))
- (doseq [^Thread thread pool]
- (.join thread))))
+(defn ^CXB make-cxb [^long n]
+ (let [n+7 (+ n 7)
+ invN (/ 2.0 n)
+ ^doubles crb (double-array n+7)
+ ^doubles cib (double-array n+7)]
+ (for-loop [(i 0) (< i n) (inc i)]
+ (aset crb i (- (* i invN) 1.5))
+ (aset cib i (- (* i invN) 1.0)))
+ (CXB. crb cib)))
- (putLine [this y]
- (let [offset (* y m)]
- (for-loop [(xb 0) (< xb m) (inc xb)]
- (aset out (+ offset xb) (.getByte this (* 8 xb) y)))))
+(defn get-byte-inner ^long [^long x ^long y ^long i ^CXB cxb]
+ (let [^doubles cib (.cib cxb)
+ ^doubles crb (.crb cxb)
+ ciby (aget cib y)
+ crbx+i (aget crb (+ x i))
+ crbx+i+1 (aget crb (+ x i 1))]
+ (loop [j 0
+ zr1 crbx+i zi1 ciby
+ zr2 crbx+i+1 zi2 ciby
+ b 0]
+ (if (< j MAX_ITERATIONS)
+ (let [nzr1 (+ crbx+i (- (* zr1 zr1) (* zi1 zi1)))
+ nzi1 (+ ciby (* zr1 zi1 2))
+ nzr2 (+ crbx+i+1 (- (* zr2 zr2) (* zi2 zi2)))
+ nzi2 (+ ciby (* zr2 zi2 2))
+ nb (if (> (+ (* nzr1 nzr1) (* nzi1 nzi1)) 4) (bit-or b 2) b)
+ nb (if (> (+ (* nzr2 nzr2) (* nzi2 nzi2)) 4) (bit-or nb 1) nb)]
+ (if (= nb 3)
+ nb
+ (recur (inc j) nzr1 nzi1 nzr2 nzi2 nb)))
+ b))))
- (getByte [this x y]
- (loop [i 0 res 0]
+(defn get-byte ^long [^long x ^long y ^CXB cxb]
+ (loop [i 0 res 0]
(if (< i 8)
(recur (+ i 2) (+ (bit-shift-left res 2)
- (.getByte_inner this x y i)))
- (byte (bit-xor res -1)))))
-
- (getByte_inner [_ x y i]
- (let [ciby (aget cib y)
- crbx+i (aget crb (+ x i))
- crbx+i+1 (aget crb (+ x i 1))]
- (loop [j 0
- zr1 crbx+i zi1 ciby
- zr2 crbx+i+1 zi2 ciby
- b 0]
- (if (< j MAX_ITERATIONS)
- (let [nzr1 (+ crbx+i (- (* zr1 zr1) (* zi1 zi1)))
- nzi1 (+ ciby (* zr1 zi1 2))
- nzr2 (+ crbx+i+1 (- (* zr2 zr2) (* zi2 zi2)))
- nzi2 (+ ciby (* zr2 zi2 2))
- nb (if (> (+ (* nzr1 nzr1) (* nzi1 nzi1)) 4) (bit-or b 2) b)
- nb (if (> (+ (* nzr2 nzr2) (* nzi2 nzi2)) 4) (bit-or nb 1) nb)]
- (if (= nb 3)
- nb
- (recur (inc j) nzr1 nzi1 nzr2 nzi2 nb)))
- b)))))
+ (get-byte-inner x y i cxb)))
+ (bit-xor res -1))))
-(defn ^MandelbrotJob compute-mandelbrot [^long n]
- (let [n+7 (+ n 7)
- m (/ n+7 8)
+(defn put-line [^bytes out ^long m ^long y ^CXB cxb]
+ (let [offset (* y m)]
+ (for-loop [(xb 0) (< xb m) (inc xb)]
+ (aset out (+ offset xb) (byte (get-byte (* 8 xb) y cxb))))))
+
+(defn ^MandelbrotBuffer compute-mandelbrot [^long n]
+ (let [m (/ (+ n 7) 8)
^bytes out (byte-array (* n m))
- ^doubles crb (double-array n+7)
- ^doubles cib (double-array n+7)
- invN (/ 2.0 n)]
- (for-loop [(i 0) (< i n) (inc i)]
- (aset crb i (- (* i invN) 1.5))
- (aset cib i (- (* i invN) 1.0)))
- (let [^MandelbrotJob job (MandelbrotJob. out n m crb cib)]
- (.generate job) job)))
+ ^CXB cxb (make-cxb n)
+ yIdx (atom -1)
+ runner (reify Runnable
+ (run [_] (let [y (swap! yIdx inc)]
+ (if (< y n) (do (put-line out m y cxb) (recur))))))
+ pool (map (fn [_] (Thread. runner)) (range (* 2 (.availableProcessors (Runtime/getRuntime)))))]
+ (doseq [^Thread thread pool]
+ (.start thread))
+ (doseq [^Thread thread pool]
+ (.join thread))
+ (MandelbrotBuffer. out n m)))
-(defn write-bmp [^MandelbrotJob job ^OutputStream outStream]
- (let [^bytes out (.out job)
- len (* (.m job) (.n job))] ; (.length out) <-- won't compile ??
- (.write outStream (.getBytes (str "P4\n" (.n job) " " (.n job) "\n")))
+(defn write-bmp [^MandelbrotBuffer buff ^OutputStream outStream]
+ (let [^bytes out (.out buff) n (.n buff) m (.m buff)
+ len (* n m)] ; (.length out) <-- won't compile ??
+ (.write outStream (.getBytes (str "P4\n" n " " n "\n")))
(.write outStream out 0 len) ; puzzling bug, just (.write outStream out) prints garbage
outStream))

0 comments on commit 44a4d51

Please sign in to comment.