Skip to content

Instantly share code, notes, and snippets.

@qmuloadmin
Last active June 18, 2021 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qmuloadmin/502a0532d8c78f5dcfd786b68b3f09ba to your computer and use it in GitHub Desktop.
Save qmuloadmin/502a0532d8c78f5dcfd786b68b3f09ba to your computer and use it in GitHub Desktop.
Calculate Pi using Chudnovsky's Algorithm Synchronously and Concurrently Using Clojure
(ns clojure-chudnovskys.core)
(require '[clojure.math.numeric-tower :as math :refer [expt]])
(import '(java.util.concurrent Executors))
(defn factorial [n]
(reduce *' (range 1 n))) ; *' automatically handles bigints for us
(defn calc-denominator [i]
(*' (factorial (*' 3 i)) (expt (factorial i) 3) (expt 262537412640768000 (+' 0.5 i))))
(defn calc-numerator [i]
(*' (expt -1 i) (factorial (*' 6 i)) (+' (*' 545140134 i) 13591409)))
(defn -main [& args]
(println "Enter number of iterations: ")
(def iterations (Integer/parseInt (read-line)))
; Synchronous calculation
(def sum
(reduce +'
(for [i (range iterations)]
(/ (calc-numerator i)
(calc-denominator i))
)
)
)
(println (/ 1 (*' 12 sum)))
; Concurrent calculation using STM
(def csum (ref 0))
(def pool (Executors/newFixedThreadPool 8))
; Our tasks are functions that take the current iteration number and return a closure that does
; the work
(def tasks
(map
(fn [i]
(fn []; this is what the map function returns -- another function to be worked by thread exc
(def itervalue (/ (calc-numerator i) (calc-denominator i)))
(dosync ; Start our transaction
(alter csum + itervalue)
) ; End our transaction
)
), (range iterations) ; -> (0..iterations)
) ;; basically, for i in 0..iterations, return a closure processing i and += csum
)
(doseq [future (.invokeAll pool tasks)]
(.get future))
(.shutdown pool)
(println (/ 1 (*' 12 (deref csum))))
)
(defproject clojure-chudnovskys "0.1.0-SNAPSHOT"
:description "Calculate Pi"
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url "https://www.eclipse.org/legal/epl-2.0/"}
:dependencies [[org.clojure/clojure "1.10.1"], [org.clojure/math.numeric-tower "0.0.4"]]
:repl-options {:init-ns clojure-chudnovskys.core}
:main clojure-chudnovskys.core
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment