wisp
 
(Arne Babenhauserheide)
2014-12-02: merge

merge

diff --git a/examples/ensemble-estimation.w b/examples/ensemble-estimation.w
--- a/examples/ensemble-estimation.w
+++ b/examples/ensemble-estimation.w
@@ -33,6 +33,9 @@ exec guile -L $(dirname $(dirname $(real
 
 define-module : examples ensemble-estimation 
 use-modules : srfi srfi-42 ; list-ec
+use-modules 
+  : ice-9 popen
+        . #:select : open-output-pipe close-pipe
 
 ; seed the random number generator
 set! *random-state* : random-state-from-platform
@@ -72,28 +75,46 @@ define* : write-multiple . x
         map : lambda (x) (write x) (newline)
             . x
 
+;; Start with the simple case: One variable and independent observations (R diagonal)
+;; First define a truth
+define x^true : append-ec (: i 10) '(0.5 0.6 7 0.1 0.7 0.9 0.8 0.4)
+;; And add an initial guess of the parameters
+define x^b : append-ec (: i 10)  '(1 1 1 1 1 1 1 1) ; initial guess
+define P : make-covariance-matrix-from-standard-deviations : append-ec (: i 10) '(0.5 0.1 0.3 0.1 0.2 0.2 0.2 0.2)
+
+;; Then generate observations
+define y⁰-num 1000
+define y⁰-pos-max 1000
+;; At the positions where they are measured. Drawn randomly to avoid
+;; giving an undue weight to later values.
+define y⁰-pos : list-ec (: i y⁰-num) : * (random:uniform) y⁰-pos-max
+
+;; We need an observation operator to generate observations from true values
 define : H x pos
        . "Observation operator. It generates modelled observations from the input.
 
 x are parameters to be optimized, pos is another input which is not optimized. For plain functions it could be the position of the measurement on the x-axis. We currently assume absolute knowledge about the position.
 "
-       apply + : list-ec (: i (length x)) : * {i + 1} (list-ref x i) : expt pos 2
+       let*
+           : len : length x
+             ystretch y⁰-pos-max
+             x-pos : list-ec (: i len) : * ystretch {{i + 0.5} / {len + 1}}
+           apply +
+                 list-ec (: i len)
+                      * : list-ref x i
+                          . pos
+                          exp 
+                            - 
+                              expt 
+                                / {pos - (list-ref x-pos i)} {ystretch / 20}
+                                . 2
 
-;; Start with the simple case: One variable and independent observations (R diagonal)
-;; First define a truth
-define x^true '(0.5 0.6 0.7 0.1)
-
-;; Then generate observations
-define y⁰-num 1000
-;; At the positions where they are measured. Drawn randomly to avoid
-;; giving an undue weight to later values.
-define y⁰-pos : list-ec (: i y⁰-num) : random y⁰-num
 
 ;; We start with true observations which we will disturb later to get
 ;; the equivalent of measured observations
 define y^true : list-ec (: i y⁰-pos) : H x^true i
 ;; now we disturb the observations with a fixed standard deviation. This assumes uncorrelated observations.
-define y⁰-std 10
+define y⁰-std 30
 define y⁰ : list-ec (: i y^true) : + i : * y⁰-std : random:normal
 ;; and define the covariance matrix. This assumes uncorrelated observations.
 define R : make-covariance-matrix-from-standard-deviations : list-ec (: i y⁰-num) y⁰-std
@@ -103,9 +124,6 @@ define R : make-covariance-matrix-from-s
 ;; The actual observations
 ;; define y⁰ : list-ec (: i y⁰-num) : + y⁰-mean : * y⁰-std : random:normal
 
-;; And add an initial guess of the parameters
-define x^b '(1 1 1 1) ; initial guess
-define P : make-covariance-matrix-from-standard-deviations '(0.5 0.1 0.3 0.1)
 
 define : EnSRT H x P y R y-pos N
        . "Observation function H, parameters x,
@@ -197,4 +215,22 @@ define : main args
                  mean y⁰
                  standard-deviation y⁰
                  . y⁰-std
-
+      ; now plot the result
+      let : : port : open-output-pipe "python"
+        format port "import pylab as pl\n"
+        format port "y0 = [float(i) for i in '~A'[1:-1].split(' ')]\n" y⁰
+        format port "ypos = [float(i) for i in '~A'[1:-1].split(' ')]\n" y⁰-pos
+        format port "yinit = [float(i) for i in '~A'[1:-1].split(' ')]\n" : list-ec (: i y⁰-pos) : H x^b i
+        format port "ytrue = [float(i) for i in '~A'[1:-1].split(' ')]\n" : list-ec (: i y⁰-pos) : H x^true i
+        format port "yopt = [float(i) for i in '~A'[1:-1].split(' ')]\n" : list-ec (: i y⁰-pos) : H x-opt i
+        format port "pl.plot(*zip(*sorted(zip(ypos, yinit))), label='prior')\n"
+        format port "pl.plot(*zip(*sorted(zip(ypos, ytrue))), label='true')\n"
+        format port "pl.plot(*zip(*sorted(zip(ypos, yopt))), label='optimized')\n"
+        format port "pl.plot(*zip(*sorted(zip(ypos, y0))), marker='+', linewidth=0, label='measurements')\n"
+        format port "pl.legend()\n"
+        format port "pl.xlabel('position [arbitrary units]')\n"
+        format port "pl.ylabel('value [arbitrary units]')\n"
+        format port "pl.title('ensemble optimization results')\n"
+        format port "pl.show()\n"
+        format port "exit()\n"
+        close-pipe port