0

我正在尝试编写一个简单的马尔可夫状态空间模型,顾名思义,它迭代地回顾一步来预测下一个状态。

这应该是一个 MWE,但这不是因为我无法完全弄清楚我应该如何放置(recur ... )在下面的代码中。

;; helper function
(defn dur-call 
  [S D]
    (if (< 1 D)
      (- D 1)
      (rand-int S)))

;; helper function
(defn trans-call
  [S D]
    (if (< 1 D)
      S
      (rand-int 3)))

;; state space model
(defn test-func
  [t]
  (loop 
    [S (rand-int 3)]
    (if (<= t 0)
      [S (rand-int (+ S 1))] 
      (let [pastS (first (test-func (- t 1)))
            pastD (second (test-func (- t 1)))
            S (trans-call pastS pastD)]

           (recur ...?)

        [S (dur-call S pastD)]))))

我的目标是在比如说时间计算一些状态t=5,在这种情况下,模型也需要回顾并计算状态t=[0 1 2 3 4]。在我看来,这应该做得很好,loop/recur但也许也可以完成reduce(不确定如何,对 Clojure 来说还是新手)。我的问题实际上是它似乎必须在recur内部使用,let但考虑到设计方式,这应该不起作用loop/recur

4

1 回答 1

2

您的任务实际上是根据前一个项目生成下一个项目,从一些种子开始。在 clojure 中,它可以通过使用iterate函数来实现:

user> (take 10 (iterate #(+ 2 %) 1))
(1 3 5 7 9 11 13 15 17 19)

你只需要定义函数来产生下一个值。它可能看起来像这样(不确定计算算法的正确性,仅基于问题中的内容):

(defn next-item [[prev-s prev-d :as prev-item]]
  (let [s (trans-call prev-s prev-d)]
    [s (dur-call s prev-d)]))

现在让我们从一些值开始迭代它:

user> (take 5 (iterate next-item [3 4]))
([3 4] [3 3] [3 2] [3 1] [0 0])

现在您的测试功能可以这样实现:

(defn test-fn [t]
  (when (not (neg? t))
    (nth (iterate next-item
                  (let [s (rand-int 3)]
                    [s (rand-int (inc s))]))
         t)))

你也可以用循环来做(但它仍然不那么惯用):

(defn test-fn-2 [t]
  (when (not (neg? t))
    (let [s (rand-int 3)
          d (rand-int (inc s))]
      (loop [results [[s d]]]
        (if (< t (count results))
          (peek results)
          (recur (conj results (next-item (peek results)))))))))

在这里,我们将所有累积的结果传递给循环的下一次迭代。

您也可以引入循环的迭代索引,然后将最后一个结果与它一起传递:

(defn test-fn-3 [t]
  (when (not (neg? t))
    (let [s (rand-int 3)
          d (rand-int (inc s))]
      (loop [result [s d] i 0]
        (if (= i t)
          result
          (recur (next-item result) (inc i)))))))

还有一个例子reduce

(defn test-fn-4 [t]
  (when (not (neg? t))
    (reduce (fn [prev _] (next-item prev))
            (let [s (rand-int 3)
                  d (rand-int (inc s))]
              [s d])
            (range t))))
于 2016-11-02T11:30:58.270 回答