wisp
 
(Arne Babenhauserheide)
2014-11-25: not yet working ensemble estimation.

not yet working ensemble estimation.

diff --git a/examples/ensemble-estimation.w b/examples/ensemble-estimation.w
new file mode 100755
--- /dev/null
+++ b/examples/ensemble-estimation.w
@@ -0,0 +1,116 @@
+#!/usr/bin/env sh
+exec guile -L ~/wisp --language=wisp "$0" "$@"
+; !#
+
+;; Simple Ensemble Square Root Filter to estimate function parameters
+;; based on measurements.
+
+;; Provide first guess parameters x^b and measurements y⁰ to get
+;; optimized parameters x^a.
+
+;; Method
+;; x^b = '(…) ; first guess of the parameters
+;; P = '((…) (…) …) ; parameter covariance
+;; y⁰ = '(…) ; observations
+;; R = '((…) (…) …) ; observation covariance
+;; H: H(x) → y ; provide modelled observations for the given parameters. Just run the function.
+;; with N ensemble members (i=1, … N) drawn from the state x^b:
+;; For each measurement y⁰_j:
+;;     x'^b: X = 1/√(N-1)(x'b_1, …, x'b_N)^T
+;;     with P = XX^T ; in the simplest case x'^b are gaussian
+;;                     distributed with standard distribution from
+;;                     square root of the diagonals.
+;;     x_i = x^b + x'^b_i
+;;     H(x^b_i) = H(x^b + x'^b_i)
+;;     H(x^b) = (1/N)·Σ H(x^b + x'^b_i)
+;;     H(x'^b_i) = H(x^b + x'_i) - H(x^b)
+;;     HPHt = 1/(N-1)(H(x'_1), …, H(x'_N))(H(x'1), …, H(x'N))T
+;;     PHt = 1/(N-1)(x'_1, …, x'_N)(H(x'1), …, H(x'N))T
+;;     K = PHt*(HPHt + R)⁻¹
+;;     x^a = x^b + K(y⁰_j - H(x^b))
+;;     α = (1 + √(R/(HPHt+R)))⁻¹
+;;     x'^a = x'^b - αK·H(x'^b)
+
+use-modules : srfi srfi-42 ; list-ec
+
+; seed the random number generator
+; set! *random-state* : random-state-from-platform
+;; Start with the simple case: One variable and independent observations (R diagonal)
+define x^b '(1) ; initial guess
+define P '((0.25)) ; standard deviation 0.5
+
+define y⁰ '(0.8 0.7 0.9 0.75) ; real value: 0.8
+define R '((0.1 0 0 0) ; standard deviation √0.1
+           (0 0.1 0 0)
+           (0 0 0.1 0)
+           (0 0 0 0.1))
+
+define : H-single x
+       . "Simple single state observation operator which just returns the state."
+       . x
+
+define* : write-multiple . x
+        map : lambda (x) (write x) (newline)
+            . x
+
+define : EnSRT-single-state H x P y R N
+       . "Observation function H, parameters x,
+parameter-covariance P, observations y, observation covariance R
+and number of ensemble members N.
+
+Limitations: x is a single value, P is a single value (variance of x).
+"
+       let process-observation
+         : observations-to-process y
+           observation-variances : list-ec (: i (length y)) : list-ref (list-ref R i) i
+           x^b : list-ref x 0
+           x-deviations : list-ec (: i N) : * (random:normal) : sqrt : list-ref (list-ref P 0) 0; only for single x'^b 
+         cond
+            : null? observations-to-process
+              list x^b x-deviations
+            else
+               write : list x^b : list-ec (: i x-deviations) {x^b + i}
+               newline
+               let*
+                 : y_cur : car observations-to-process
+                   R_cur : car observation-variances
+                   Hx^b_i : list-ec (: i x-deviations) : H {x^b + i} ; this only works for single value x!
+                   Hx^b 
+                      / : sum-ec (: i Hx^b_i) i 
+                        . N
+                   Hx^b-prime 
+                       list-ec (: i N) 
+                           - : list-ref Hx^b_i i
+                             . Hx^b
+                   HPHt 
+                      / : sum-ec (: i Hx^b-prime) {i * i}
+                        . {N - 1}
+                   PHt 
+                      list-ec (: j (length x)) ; for each x^b_i multiply the state-element and model-deviation for all ensemble members. This is not used at the moment.
+                         * {1 / {N - 1}} 
+                             sum-ec (: i N) 
+                               * : list-ref x-deviations i ; FIXME: this currently does not use j because I only do length 1 x
+                                   list-ref Hx^b-prime i
+                   K : list-ec (: i PHt) {1 / {HPHt + R_cur}}
+                   a : write-multiple "XXX" Hx^b-prime PHt HPHt
+                   x^a 
+                     list-ec (: i (length K)) 
+                       + x^b
+                         * : list-ref K i
+                           . {y_cur - Hx^b}
+                   α-weight-sqrt : sqrt {R_cur / {HPHt + R_cur}}
+                   α {1 / {1 + α-weight-sqrt}}
+                   x^a-deviations 
+                     list-ec (: i N)
+                       - : list-ref x-deviations i
+                         * α
+                           list-ref K 0
+                           list-ref Hx^b-prime i
+                 process-observation
+                   cdr observations-to-process
+                   cdr observation-variances
+                   list-ref x^a 0
+                   . x^a-deviations
+
+write : EnSRT-single-state H-single x^b P y⁰ R 4
+newline