簡體   English   中英

Clojure循環和狀態空間模型中的遞歸或歸約

[英]Clojure loop and recur or reduce in state space model

我正在嘗試編寫一個簡單的馬爾可夫狀態空間模型,顧名思義,該模型反復地回溯一步以預測下一個狀態。

這是應該成為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還是一個新手)。 我的問題確實是,它似乎不必在let使用recur ,但是鑒於loop/recur遞歸的設計方式,它不起作用。

您的任務實際上是根據上一個種子生成下一個種子。 在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))))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM