Learning Clojure: recursion for Hidden Markov Model -


i'm learning clojure , started copying functionality of python program create genomic sequences following (extremely simple) hidden markov model.

in beginning stuck known way of serial programming , used def keyword lot, solving problem tons of side effects, kicking every concept of clojure right in butt. (although worked supposed)

then tried convert more functional way, using loop, recur, atom , on. when run arityexception, can't read error message in way shows me function throws it.

(defn create-model [name pa pc pg pt pswitch] ; converts propabilities cumulative prop's , returns char   (with-meta     (fn []       (let [x (rand)]         (if (<= x pa)           \a           (if (<= x (+ pa pc))             \c             (if (<= x (+ pa pc pg))               \g               \t)))))                   ; function object     {:p-switch pswitch :name name}))    ; metadata, used change model   (defn create-genome [n] ; adds random chars model string , switches models randomly   (let [models [(create-model "std" 0.25 0.25 0.25 0.25 0.02) ; standard model, equal props                 (create-model "cpg" 0.1 0.4 0.4 0.1 0.04)]    ; cpg model         islands (atom 0)                 ; island counter         m (atom 0)]                      ; model index     (loop [result (str)]       (let [model (nth models @m)]         (when (< (rand) (:p-switch (meta model))) ; random says "switch model!" ;          (swap! m #(mod (inc @m) 2))   ; swap model used in next iteration                (swap! m #(mod (inc %) 2))     ; edit: correction           (if (= @m 1)                   ; on switch model 1, increase island counter ;            (swap! islands #(inc @islands)))) ; edit: try, error             (swap! islands inc)))) ;             edit: correction         (if (< (count result) n)         ; repeat until result reaches length n           (recur (format "%s%c" result (model)))           result))))) 

running works, calling (create-genome 1000) leads to

arityexception wrong number of args (1) passed to: user/create-genome/fn--772  clojure.lang.afn.throwarity (afn.java:429) 

my questions:

  • (obviously) doing wrong?
  • how have understand error message?

information i'd glad receive

  • how can code improved (in way clojure-newb can understand)? different paradigms - i'm grateful suggestions.
  • why need put pound-signs # before forms use in changing atoms' states? saw in example, function wouldn't evaluate without it, don't understand :)

ok, it's long shot, looks atom-updating functions:

#(mod (inc @m) 2) 

and

#(inc @islands) 

are of 0-arity, , should of arity @ least 1.

this leads answer last question: #(body) form shortcut (fn [...] (body)). creates anonymous function. trick if body contains % or %x x number, position appears substituted referece created function's argument number x (or first argument if it's %).

in case body doesn't contain references function arguments, #() creates anonymous function takes no arguments, not swap! expects.

so swap tries pass argument doesn't expect , boom!, arityexception.

what needed in cases was:

(swap! m #(mod (inc %) 2)) ; swap value of m (mod (inc current-value-of-m) 2) internally 

and

(swap! islands inc) ; swap value of islands (inc current-value-of-islands) internally 

respectively


Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -