aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/probabilities/examples_finite_distributions.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/clojure/contrib/probabilities/examples_finite_distributions.clj')
-rw-r--r--src/clojure/contrib/probabilities/examples_finite_distributions.clj209
1 files changed, 0 insertions, 209 deletions
diff --git a/src/clojure/contrib/probabilities/examples_finite_distributions.clj b/src/clojure/contrib/probabilities/examples_finite_distributions.clj
deleted file mode 100644
index 56f25bad..00000000
--- a/src/clojure/contrib/probabilities/examples_finite_distributions.clj
+++ /dev/null
@@ -1,209 +0,0 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Probability distribution application examples
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(ns
- #^{:author "Konrad Hinsen"
- :skip-wiki true
- :doc "Examples for finite probability distribution"}
- clojure.contrib.probabilities.examples-finite-distributions
- (:use [clojure.contrib.probabilities.finite-distributions
- :only (uniform prob cond-prob join-with dist-m choose
- normalize certainly cond-dist-m normalize-cond)])
- (:use [clojure.contrib.monads
- :only (domonad with-monad m-seq m-chain m-lift)])
- (:require clojure.contrib.accumulators))
-
-;; Simple examples using dice
-
-; A single die is represented by a uniform distribution over the
-; six possible outcomes.
-(def die (uniform #{1 2 3 4 5 6}))
-
-; The probability that the result is odd...
-(prob odd? die)
-; ... or greater than four.
-(prob #(> % 4) die)
-
-; The sum of two dice
-(def two-dice (join-with + die die))
-(prob #(> % 6) two-dice)
-
-; The sum of two dice using a monad comprehension
-(assert (= two-dice
- (domonad dist-m
- [d1 die
- d2 die]
- (+ d1 d2))))
-
-; The two values separately, but as an ordered pair
-(domonad dist-m
- [d1 die
- d2 die]
- (if (< d1 d2) (list d1 d2) (list d2 d1)))
-
-; The conditional probability for two dice yielding X if X is odd:
-(cond-prob odd? two-dice)
-
-; A two-step experiment: throw a die, and then add 1 with probability 1/2
-(domonad dist-m
- [d die
- x (choose (/ 1 2) d
- :else (inc d))]
- x)
-
-; The sum of n dice
-(defn dice [n]
- (domonad dist-m
- [ds (m-seq (replicate n die))]
- (apply + ds)))
-
-(assert (= two-dice (dice 2)))
-
-(dice 3)
-
-
-;; Construct an empirical distribution from counters
-
-; Using an ordinary counter:
-(def dist1
- (normalize
- (clojure.contrib.accumulators/add-items
- clojure.contrib.accumulators/empty-counter
- (for [_ (range 1000)] (rand-int 5)))))
-
-; Or, more efficiently, using a counter that already keeps track of its total:
-(def dist2
- (normalize
- (clojure.contrib.accumulators/add-items
- clojure.contrib.accumulators/empty-counter-with-total
- (for [_ (range 1000)] (rand-int 5)))))
-
-
-;; The Monty Hall game
-;; (see http://en.wikipedia.org/wiki/Monty_Hall_problem for a description)
-
-; The set of doors. In the classical variant, there are three doors,
-; but the code can also work with more than three doors.
-(def doors #{:A :B :C})
-
-; A simulation of the game, step by step:
-(domonad dist-m
- [; The prize is hidden behind one of the doors.
- prize (uniform doors)
- ; The player make his initial choice.
- choice (uniform doors)
- ; The host opens a door which is neither the prize door nor the
- ; one chosen by the player.
- opened (uniform (disj doors prize choice))
- ; If the player stays with his initial choice, the game ends and the
- ; following line should be commented out. It describes the switch from
- ; the initial choice to a door that is neither the opened one nor
- ; his original choice.
- choice (uniform (disj doors opened choice))
- ]
- ; If the chosen door has the prize behind it, the player wins.
- (if (= choice prize) :win :loose))
-
-
-;; Tree growth simulation
-;; Adapted from the code in:
-;; Martin Erwig and Steve Kollmansberger,
-;; "Probabilistic Functional Programming in Haskell",
-;; Journal of Functional Programming, Vol. 16, No. 1, 21-34, 2006
-;; http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP06a
-
-; A tree is represented by two attributes: its state (alive, hit, fallen),
-; and its height (an integer). A new tree starts out alive and with zero height.
-(def new-tree {:state :alive, :height 0})
-
-; An evolution step in the simulation modifies alive trees only. They can
-; either grow by one (90% probability), be hit by lightning and then stop
-; growing (4% probability), or fall down (6% probability).
-(defn evolve-1 [tree]
- (let [{s :state h :height} tree]
- (if (= s :alive)
- (choose 0.9 (assoc tree :height (inc (:height tree)))
- 0.04 (assoc tree :state :hit)
- :else {:state :fallen, :height 0})
- (certainly tree))))
-
-; Multiple evolution steps can be chained together with m-chain,
-; since each step's input is the output of the previous step.
-(with-monad dist-m
- (defn evolve [n tree]
- ((m-chain (replicate n evolve-1)) tree)))
-
-; Try it for zero, one, or two steps.
-(evolve 0 new-tree)
-(evolve 1 new-tree)
-(evolve 2 new-tree)
-
-; We can also get a distribution of the height only:
-(with-monad dist-m
- ((m-lift 1 :height) (evolve 2 new-tree)))
-
-
-
-;; Bayesian inference
-;;
-;; Suppose someone has three dice, one with six faces, one with eight, and
-;; one with twelve. This person throws one die and gives us the number,
-;; but doesn't tell us which die it was. What are the Bayesian probabilities
-;; for each of the three dice, given the observation we have?
-
-; A function that returns the distribution of a dice with n faces.
-(defn die-n [n] (uniform (range 1 (inc n))))
-
-; The three dice in the game with their distributions. With this map, we
-; can easily calculate the probability for an observation under the
-; condition that a particular die was used.
-(def dice {:six (die-n 6)
- :eight (die-n 8)
- :twelve (die-n 12)})
-
-; The only prior knowledge is that one of the three dice is used, so we
-; have no better than a uniform distribution to start with.
-(def prior (uniform (keys dice)))
-
-; Add a single observation to the information contained in the
-; distribution. Adding an observation consists of
-; 1) Draw a die from the prior distribution.
-; 2) Draw an observation from the distribution of that die.
-; 3) Eliminate (replace by nil) the trials that do not match the observation.
-; 4) Normalize the distribution for the non-nil values.
-(defn add-observation [prior observation]
- (normalize-cond
- (domonad cond-dist-m
- [die prior
- number (get dice die)
- :when (= number observation) ]
- die)))
-
-; Add one observation.
-(add-observation prior 1)
-
-; Add three consecutive observations.
-(-> prior (add-observation 1)
- (add-observation 3)
- (add-observation 7))
-
-; We can also add multiple observations in a single trial, but this
-; is slower because more combinations have to be taken into account.
-; With Bayesian inference, it is most efficient to eliminate choices
-; as early as possible.
-(defn add-observations [prior observations]
- (with-monad cond-dist-m
- (let [n-nums #(m-seq (replicate (count observations) (get dice %)))]
- (normalize-cond
- (domonad
- [die prior
- nums (n-nums die)
- :when (= nums observations)]
- die)))))
-
-(add-observations prior [1 3 7])