dapper.mods.Lorenz96.hoteit2015

Reproduce results from bib.hoteit2015mitigating.

 1"""Reproduce results from `bib.hoteit2015mitigating`."""
 2
 3from dapper.mods.Lorenz96.sakov2008 import HMM as _HMM
 4
 5HMM = _HMM.copy()
 6HMM.tseq.T = 365
 7HMM.tseq.BurnIn = 4
 8# Further settings used in paper:
 9# Experiments repeated 10 times.
10# Sometimes used: dko=4.
11# Sometimes used: obs_inds = arange(Nx)[::2].
12# Used localization: as in Whitaker/Hamill'2002: GC.
13
14
15####################
16# Suggested tuning
17####################
18
19# DAPPER only has localization implemented for
20# the ETKF (LETKF) and the serial EAKF (SL_EAKF).
21# Thus, direction comparison to paper (which always uses localization) is difficult.
22# Still, these LETKF scores can be compared with Fig. 2 of the paper.
23# They indicate that the LETKF is a little better than any scheme in the paper.
24# However, the localization implementation is probably not fully equivalent
25# (also, since optimal R seems to be around 6, I think Hoteit et al may have
26# forgotten the sqrt(10/3) factor from Whitaker/Hamill).
27#                                                               # Expected rmse.a:
28# xps += LETKF(        N=10,rot=True,infl=1.02,loc_rad=4)       # 0.21
29# xps += LETKF(        N=10,rot=True,infl=1.04,loc_rad=6)       # 0.20
30# xps += LETKF(        N=10,rot=True,infl=1.10,loc_rad=10)      # 0.22
31# xps += LETKF(        N=10,         infl=1.20,loc_rad=15)      # 0.29
32
33
34# Without localization, DAPPER can also compare ESOPS to many other schemes:
35# xps += EnKF ('Sqrt'           , N=28, infl=1.02,rot=True)     # 0.18
36# xps += EnKF ('Serial'         , N=28, infl=1.02,rot=True)     # 0.18
37# xps += EnKF ('Serial ESOPS'   , N=28, infl=1.02)              # 0.18
38# xps += EnKF ('Serial Stoch'   , N=28, infl=1.08)              # 0.24
39# xps += EnKF ('Serial Var1'    , N=28, infl=1.08)              # 0.24
40# xps += EnKF ('PertObs'        , N=28, infl=1.08)              # 0.24
41# As can be seen, ESOPS does well for a medium-large ensemble,
42# getting RMSE scores on the level of the ETKF (i.e. 'Sqrt').
43# For a small ensemble, however, ESOPS does not do quiet as well as the ETKF
44# (and requires higher inflation to avoid divergence):
45# xps += EnKF ('Sqrt'           , N=17, infl=1.03)              # 0.217
46# xps += EnKF ('Serial'         , N=17, infl=1.06)              # 0.225
47# xps += EnKF ('Serial ESOPS'   , N=17, infl=1.08)              # 0.242
HMM = HiddenMarkovModel({ 'Dyn': Operator({ 'M': 40, 'model': <function step>, 'noise': GaussRV({ 'mu': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'M': 40, 'C': 0 }), 'linear': <function dstep_dx> }), 'Obs': <TimeDependentOperator> CONSTANT operator sepcified by .Op1: Operator({ 'M': 40, 'model': Direct obs. at [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39] <function partial_Id_Obs.<locals>.model>, 'noise': GaussRV({ 'C': <CovMat> M: 40 kind: 'diag' trunc: 1.0 rk: 40 full: (only computing/printing corners) [[1. 0. 0. ... 0. 0. 0.] [0. 1. 0. ... 0. 0. 0.] [0. 0. 1. ... 0. 0. 0.] ... [0. 0. 0. ... 1. 0. 0.] [0. 0. 0. ... 0. 1. 0.] [0. 0. 0. ... 0. 0. 1.]] diag: [1. 1. 1. ... 1. 1. 1.], 'mu': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'M': 40 }), 'linear': Constant matrix [[1. 0. 0. ... 0. 0. 0.] [0. 1. 0. ... 0. 0. 0.] [0. 0. 1. ... 0. 0. 0.] ... [0. 0. 0. ... 1. 0. 0.] [0. 0. 0. ... 0. 1. 0.] [0. 0. 0. ... 0. 0. 1.]] <function partial_Id_Obs.<locals>.linear>, 'localizer': <function localization_setup.<locals>.localization_now at 0x7fa23ff61ab0> }), 'tseq': <Chronology> - K: 7300 - Ko: 7299 - T: 365.0 - BurnIn: 4 - dto: 0.05 - dt: 0.05, 'X0': GaussRV({ 'C': <CovMat> M: 40 kind: 'diag' trunc: 1.0 rk: 40 full: (only computing/printing corners) [[0.001 0. 0. ... 0. 0. 0. ] [0. 0.001 0. ... 0. 0. 0. ] [0. 0. 0.001 ... 0. 0. 0. ] ... [0. 0. 0. ... 0.001 0. 0. ] [0. 0. 0. ... 0. 0.001 0. ] [0. 0. 0. ... 0. 0. 0.001]] diag: [0.001 0.001 0.001 ... 0.001 0.001 0.001], 'mu': array([1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), 'M': 40 }), 'liveplotters': [(1, <function spatial1d.<locals>.init at 0x7fa23ff62560>), (1, <class 'dapper.tools.liveplotting.correlations'>), (0, <class 'dapper.tools.liveplotting.spectral_errors'>), (0, <function phase_particles.<locals>.init at 0x7fa23ff625f0>), (0, <function sliding_marginals.<locals>.init>)], 'sectors': {}, 'name': 'Lorenz96/sakov2008.py' })