2010-10-17 16 views
5

Per il codice successivo:Clojure: limite gc testa superato, valutazione pigra, sequenza pi

(ns clojure101.series) 

(defn avg [[x y]] (/ (+ x y) 2)) 

(defn avg-damp 
    [seq] 
    (map avg (partition 2 seq))) 

(defn avg-damp-n 
    [n] 
    (apply comp (repeat n avg-damp))) 

(defn sums 
    [seq] 
    (reductions + seq)) 

(defn Gregory-Leibniz-n 
    [n] 
    (/ (Math/pow -1 n) (inc (* 2 n)))) 

(def Gregory-Leibniz-pi 
    (map #(* 4 (Gregory-Leibniz-n %)) (iterate inc 0))) 

(println (first ((avg-damp-n 10) (sums Gregory-Leibniz-pi)))) 

ottengo "limite gc sovraccarico superato" errore per n = 20. Come posso risolvere questo?

UPDATE: ho cambiato funzione medio-umido-n

(defn avg-damp-n 
    [n seq] 
    (if (= n 0) seq 
     (recur (dec n) (avg-damp seq)))) 

ora posso ottenere il numero per n = 20

(time 
(let [n 20] 
    (println n (first (avg-damp-n n (sums Gregory-Leibniz-pi)))))) 

20 3.141593197943081 
"Elapsed time: 3705.821263 msecs" 

UPDATE 2 ho fissato un errore e ora funziona perfettamente:

(ns clojure101.series) 

(defn avg [[x y]] (/ (+ x y) 2)) 

(defn avg-damp 
    [seq] 
    (map avg (partition 2 1 seq))) 

(defn avg-damp-n 
    [n] 
    (apply comp (repeat n avg-damp))) 

(defn sums 
    [seq] 
    (reductions + seq)) 

(defn Gregory-Leibniz-n 
    [n] 
    (/ (int (Math/pow -1 n)) (inc (* 2 n)))) 

(def Gregory-Leibniz-pi 
    (map #(* 4 (Gregory-Leibniz-n %)) (range))) 

; π = 3.14159265358979323846264338327950288419716939937510... 

(time 
(let [n 100] 
    (println n (double (first ((avg-damp-n n) (sums Gregory-Leibniz-pi))))))) 

USCITA:

100 3.141592653589793 
"Elapsed time: 239.253227 msecs" 

risposta

2

Hmm ... Questo funziona per me. Testato con Clojure 1.2 su Windows XP.

user=> (defn avg 
     [xs & {:keys [n] :or {n 2}}] 
     (/ (reduce + xs) n)) 
#'user/avg 
user=> (defn Gregory-Leibniz-n 
     [n] 
     (/ (Math/pow -1 n) (inc (+ n n)))) 
#'user/Gregory-Leibniz-n 
user=> (->> (range) 
     (map #(* 4 (Gregory-Leibniz-n %))) 
     (reductions +) 
     (partition 20) 
     (map #(avg % :n 20)) 
     first 
     println) 
3.1689144018345354 

È la risposta giusta? Non conosco questa ricorsione di Gregory-Leibniz, quindi sono non sicuro se questo è corretto.

Un punto che ho notato: stai cercando di essere troppo intelligente. Vale a dire il tuo avg-damp-n stack pigro seq su pigro seq. Poiché puoi estendere i valori arbitrari di n, , prima o poi sperimenterai anche overflow dello stack per il grande nello scenario . Se esiste una soluzione semplice, preferisci lo . Non sono sicuro che questo sia il tuo problema attuale. (Come ho già detto: piuttosto inutilmente funziona per me.)

+1

Considerando questo si suppone per risolvere a Pi, I don' Penso che sia la risposta giusta.;) –

+0

@ataggert Hai punti lì. ;) (Piccola modifica: Ma potrebbe essere ancora il numero che l'OP si aspetta ...) (E ovviamente con la ('partizione 2 1 ...) 'cambiare quanto sopra non funziona più.) – kotarak

2

Prima di tutto, provare la soluzione stupida che funziona: aumentare il vostro spazio java heap.

;in your clojure launch script 
java -Xmx2G ...other options... 

C'è una parte del programma che non è pigro nel divisorio, ma cambiando in modo che esso è pigro (da sbarazzarsi di una chiamata a count) ancora mi dà un OutOfMemoryError per la dimensione predefinita heap. Sostituendo l'intelligenza di medio-umido-n con una media ridurre calcolata sulla

(take (integer-exponent 2 20) seq) 

provoca ancora un OutOfMemoryError. Guardando la fonte di tutto il resto, non vedo altre cose che sembrano consumate.

3

Come kotarak detto, l'accatastamento della SEQ pigri di sulla ss pigri di sembra piuttosto inefficiente quanto riguarda la GC. Potrei riprodurre questo problema su un sistema di atomo lento. Vedi anche:

Error java.lang.OutOfMemoryError: GC overhead limit exceeded

Per me Gregory-Leibniz PI caclulation trasforma direttamente in questo codice Clojure che utilizza solo una sequenza pigro:

(defn Gregory-Leibniz-pi [n] 
    (->> (range n) 
     (map (fn [n] (/ (Math/pow -1 n) (inc (* 2 n))))) 
     (apply +) 
     (* 4))) 
Problemi correlati