- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在学习 Clojure 并从复制 Python 程序的功能开始,该程序将通过遵循(非常简单的)隐马尔可夫模型来创建基因组序列。
一开始,我坚持使用我已知的串行编程方式并大量使用 def 关键字,从而解决了具有大量副作用的问题,几乎将 Clojure 的每个概念都放在了屁股上。 (虽然它按预期工作)
然后我尝试将其转换为更实用的方式,使用循环、递归、原子等。现在,当我运行时,我得到了一个 ArityException,但我无法以一种方式读取错误消息,甚至无法显示哪个函数抛出它。
(defn create-model [name pA pC pG pT pSwitch]
; converts propabilities to cumulative prop's and returns a char
(with-meta
(fn []
(let [x (rand)]
(if (<= x pA)
\A
(if (<= x (+ pA pC))
\C
(if (<= x (+ pA pC pG))
\G
\T))))) ; the function object
{:p-switch pSwitch :name name})) ; the metadata, used to change model
(defn create-genome [n]
; adds random chars from a model to a string and 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 to model 1, increase island counter
; (swap! islands #(inc @islands)))) ; EDIT: my try, with error
(swap! islands inc)))) ; EDIT: correction
(if (< (count result) n) ; repeat until result reaches length n
(recur (format "%s%c" result (model)))
result)))))
ArityException Wrong number of args (1) passed to: user/create-genome/fn--772 clojure.lang.AFn.throwArity (AFn.java:429)
最佳答案
既然你问了改进的方法,这是我经常发现自己要去的一种方法:我可以抽象这个loop
进入更高阶的模式?
在这种情况下,您的循环随机选择字符 - 这可以建模为调用返回一个字符的无参数 fn - 然后将它们累加在一起,直到有足够的字符为止。这非常适合 repeatedly
,它采用这样的函数,并将其结果的惰性序列制作成您想要的任何长度。
然后,因为您将整个字符序列放在一起,您可以将它们连接成一个字符串比重复 format
更有效一点。 s - clojure.string/join
应该很合身,或者你可以 apply
str
超过它。
这是我对这种代码形状的尝试 - 我还尝试使其完全由数据驱动,这可能导致它有点神秘,所以请耐心等待:
(defn make-generator
"Takes a probability distribution, in the form of a map
from values to the desired likelihood of that value appearing in the output.
Normalizes the probabilities and returns a nullary producer fn with that distribution."
[p-distribution]
(let[sum-probs (reduce + (vals p-distribution))
normalized (reduce #(update-in %1 [%2] / sum-probs) p-distribution (keys p-distribution) )]
(fn [] (reduce
#(if (< %1 (val %2)) (reduced (key %2)) (- %1 (val %2)))
(rand)
normalized))))
(defn markov-chain
"Takes a series of states, returns a producer fn.
Each call, the process changes to the next state in the series with probability :p-switch,
and produces a value from the :producer of the current state."
[states]
(let[cur-state (atom (first states))
next-states (atom (cycle states))]
(fn []
(when (< (rand) (:p-switch @cur-state))
(reset! cur-state (first @next-states))
(swap! next-states rest))
((:producer @cur-state)))))
(def my-states [{:p-switch 0.02 :producer (make-generator {\A 1 \C 1 \G 1 \T 1}) :name "std"}
{:p-switch 0.04 :producer (make-generator {\A 1 \C 4 \G 4 \T 1}) :name "cpg"}])
(defn create-genome [n]
(->> my-states
markov-chain
(repeatedly n)
clojure.string/join))
let
在 make-generator
只是确保概率总和为 1。make-generator
大量使用另一种高阶循环模式,即 reduce
.这本质上需要一个包含 2 个值的函数,并通过它线程化一个集合。 (reduce + [4 5 2 9])
就像 (((4 + 5) + 2) + 9)。我主要用它来做与您嵌套的 if
类似的事情s 在 create-model
,但没有指明概率分布中有多少个值。 markov-chain
形成两个原子,cur-state
保持当前状态和 next-states
,它包含要切换到的下一个状态的无限序列(来自 cycle
)。这就像您的 m
一样工作和 models
,但对于任意数量的状态。 when
检查随机状态切换是否应该发生,如果它确实执行了两个副作用,我需要保持状态原子是最新的。然后我只是不带参数地调用@cur-state 的 :producer 并返回它。 关于recursion - 学习Clojure : recursion for Hidden Markov Model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31046044/
为什么该语言的名称是“Clojure”? 我用谷歌搜索了一下,在#clojure 中询问。到目前为止,还没有运气。 最佳答案 Rich Hickey(他是 Clojure 的设计者)对此的评论是 wi
我不明白为什么升级后会出现以下编译错误: Compiling addr-verify.core Exception in thread "main" java.lang.NoClassDefFound
我试图将从映射操作返回的(惰性)序列传递给另一个映射操作,以便我可以在第一个序列中查找元素。代码从文本文件(以行/列格式)解析一些足球装置,清理它,然后返回一张 map 。 这是代码: (ns fix
我想过滤一组,例如: (filter-set even? #{1 2 3 4 5}) ; => #{2 4} 如果我使用clojure.core/filter我得到一个不是集合的seq: (filte
(defn hi[](+ 5 6)) (hi) (defn hi[](+ 6 7)) (hi) 你好,我是 clojure 的新手。如上所述,我编写了两个具有相同名称的函数。我们可以在 cloj
我按照这个伪代码递归地将十进制转换为二进制。 findBinary(decimal) if (decimal == 0) binary = 0 else binar
我正在尝试学习 Clojure 并尝试定义这个简单的函数: user=> (defn triple [arg] (* 3 arg)) #'user/triple user=> (triple 1) 3
是->和 ->>宏只是为了使代码更具可读性还是它们还有其他特定功能? 最佳答案 线程优先( -> )和线程最后( ->> )是为了使代码更具可读性。但这已经很重要了! 它允许取消嵌套函数调用(示例取自
我在 http://www.learningclojure.com/2010/11/yet-another-way-to-write-factorial.html 上找到了这个代码,但我不明白 pop
我正在阅读 Programming Clojure 2nd edition,在第 49 页它涵盖了 Clojure 的 for 循环结构,它说它实际上是一个序列理解。 作者建议使用以下代码: (def
Clojure 中有双端队列吗?我的印象是 Clojure 的 PersistentQueue 是单端的(我错了吗?)。我需要能够从队列的任一端删除(即“pop”)和“peek”数据。我所说的双端队列
换句话说,有没有办法在看起来不像 (MACRO arg* ...) 的表单上触发宏扩展? . 举一个假设的例子: (defmacro my-var (do (printf "Using my-va
我很难理解懒惰。 有人能帮我理解为什么我下面的函数不是懒惰的吗 (defn my-red ([f coll] (my-red f (first coll) (rest coll) ))
在 Clojure 核心中决定参数函数顺序的规则是什么(如果有的话)? 类似 map 的函数和 filter期望数据结构作为最后一个 争论。 类似 assoc 的函数和 select-keys期待数据
我在 clojuredocs 上遇到过 completing 函数,但目前没有文档。 你能提供一些例子吗? 最佳答案 completing 用于扩充可能没有具有一元“完成”元数的一元重载的二元归约函数
这个现在支持吗?我能找到的唯一信息是来自维基的示例( https://github.com/clojure/core.match/wiki/Deftype-and-defrecord-matching
我正在关注“Clojure in Action”,对此我感到困惑: (defn with-log [function-to-call log-statement ] (fn [& args
对于下面的代码,箭头是宏还是函数名称中的简单字符? (来自 here) (defn file->map [file] ;; TODO ) 最佳答案 箭头是函数名称的一部分。有一个函数定义,不是
Clojure 的 range函数包含来自 start独家在end (如果提供)。核心库中是否有一个函数可以提供完全包含(开始和结束)的范围? 我发现在某些情况下必须调整最终值的代码 - 例如向下而不
当我尝试从 REPL 运行以下代码时(使用动态记录): (defrecord (symbol "rec2") (vec (map symbol ["f1" "f2"]))) 我收到错误 Compile
我是一名优秀的程序员,十分优秀!