0

名前が示すように、次の状態を予測するために 1 つのステップを繰り返し振り返る単純なマルコフ状態空間モデルを作成しようとしています。

これは 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]。私の考えでは、これはうまくいくはずですが、おそらく(方法がわからない、まだClojureに慣れていない)でもloop/recur実行できます。reduce私の問題は、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)))))))

そして、もう1つの例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 に答える