(defn combine-keywords [& a] (keyword (apply str (mapcat #(drop 1 (str %)) a))))
(defn combine-distributions
([P] P)
([P1 P2]
(into {}
(for [[s1 p1] P1
[s2 p2] P2]
[(combine-keywords s1 s2) (* p1 p2)])))
([P1 P2 & Plist] (reduce combine-distributions (cons P1 (cons P2 Plist)))))
(defn decoder
([code-tree stream] (decoder code-tree code-tree stream))
([current-code-tree code-tree stream]
(lazy-seq
(if (keyword? current-code-tree)
(cons current-code-tree (decoder code-tree code-tree stream))
(if-let [stream (seq stream)]
(if (= (first stream) 1)
(decoder (first current-code-tree) code-tree (rest stream))
(decoder (second current-code-tree) code-tree (rest stream))))))))
(defn encoder [code stream] (mapcat code stream))
(defn make-encoder [code] (fn [s] (encoder code s)))
(defn make-decoder [code-tree] (fn[s] (decoder code-tree s)))
(defn symbols [prefix code-tree]
(if (keyword? code-tree) (list prefix code-tree)
(concat (symbols (cons 1 prefix) (first code-tree))
(symbols (cons 0 prefix) (second code-tree)))))
(defn make-code [code-tree]
(into {} (map (fn[[c s]][s (reverse c)]) (partition 2 (symbols '() code-tree)))))
(defn madd [m [k p]] (assoc m p (cons k (m p))))
(defn mpop [m]
(let [[k vlist] (first m)]
[k (first vlist)
(if (empty? (rest vlist))
(dissoc m k)
(assoc m k (rest vlist)))]))
(defn mcombine [m]
(let [[pa a pop1] (mpop m)
[pb b pop2] (mpop pop1)]
(madd pop2 [[a b] (+ pa pb)])))
(defn make-code-tree [P]
(second (mpop
(nth (iterate mcombine (reduce madd (sorted-map) P)) (dec (count P))))))
(def fair-coin {:H 1 :T 1})
(def unfair-coin {:H 3 :T 1})
(def unfair-triples (combine-distributions unfair-coin unfair-coin unfair-coin))
(def triple-code-tree (make-code-tree unfair-triples))
(def triple-code (make-code triple-code-tree))
(defn code-distribution [P code] (for [s (keys P)] [(P s) (code s)]))
(code-distribution unfair-triples triple-code)
(defn expected-code-length [P code]
(let [cd (code-distribution P code)]
(/ (reduce + (for [[k v] cd] (* k (count v))))
(reduce + (map first cd)))))
(expected-code-length unfair-triples triple-code) (float ( / 79/32 3))
(defn cost-for-n-code [ P n ]
(let [Pn (apply combine-distributions (repeat n P))
code (make-code (make-code-tree Pn))]
(float (/ (expected-code-length Pn code) n))))
(cost-for-n-code unfair-coin 1) (cost-for-n-code unfair-coin 2) (cost-for-n-code unfair-coin 3) (cost-for-n-code unfair-coin 4) (cost-for-n-code unfair-coin 5) (cost-for-n-code unfair-coin 6) (cost-for-n-code unfair-coin 7) (cost-for-n-code unfair-coin 8) (cost-for-n-code unfair-coin 9) (cost-for-n-code unfair-coin 10) (cost-for-n-code unfair-coin 11) (cost-for-n-code unfair-coin 12)
(cost-for-n-code fair-coin 1) (cost-for-n-code fair-coin 2) (cost-for-n-code fair-coin 3) (cost-for-n-code fair-coin 4)
(def triad {:A 1 :B 1 :C 1})
(cost-for-n-code triad 1) (cost-for-n-code triad 2) (cost-for-n-code triad 3) (cost-for-n-code triad 4) (cost-for-n-code triad 5) (cost-for-n-code triad 6) (cost-for-n-code triad 7) (cost-for-n-code triad 8)
(def quad {:A 1 :B 1 :C 1 :D 1})
(cost-for-n-code quad 1) (cost-for-n-code quad 2) (cost-for-n-code quad 3) (cost-for-n-code quad 4) (cost-for-n-code quad 5)
(def quint {:A 1 :B 1 :C 1 :D 1 :E 1})
(cost-for-n-code quint 1) (cost-for-n-code quint 2) (cost-for-n-code quint 3) (cost-for-n-code quint 4) (cost-for-n-code quint 5) (cost-for-n-code quint 6)
(def octet {:A 1 :B 1 :C 1 :D 1 :E 1 :F 1 :G 1 :H 1})
(cost-for-n-code octet 1) (cost-for-n-code octet 2) (cost-for-n-code octet 3)
(defn bits [n] (/ (Math/log n)(Math/log 2)))
(map bits (range 2 10))
(def sextet {:A 1 :B 1 :C 1 :D 1 :E 1 :F 1})
(bits 6)
(cost-for-n-code sextet 1) (cost-for-n-code sextet 2) (cost-for-n-code sextet 3) (cost-for-n-code sextet 4) (cost-for-n-code sextet 5) (cost-for-n-code sextet 6)
No comments:
Post a Comment