Example #1
0
def HMMs(stepper="Tay2", resolution="Low", R=1):
    """Define the various HMMs used."""
    # Use small version of L96. Has 4 non-stable Lyapunov exponents.
    Nx = 10

    # Time sequence
    # Grudzien'2020 uses the below chronology with Ko=25000, BurnIn=5000.
    t = modelling.Chronology(dt=0.005, dto=.1, T=30, Tplot=Tplot, BurnIn=10)
    if resolution == "High":
        t.dt = 0.001
    elif stepper != "Tay2":
        t.dt = 0.01

    # Dynamical operator
    Dyn = {'M': Nx, 'model': steppers(stepper)}

    # (Random) initial condition
    X0 = modelling.GaussRV(mu=x0(Nx), C=0.001)

    # Observation operator
    jj = range(Nx)  # obs_inds
    Obs = modelling.partial_Id_Obs(Nx, jj)
    Obs['noise'] = R

    return modelling.HiddenMarkovModel(Dyn, Obs, t, X0)
Example #2
0
def X0(param_mean, param_var):
    # State
    x0 = np.zeros(Nx)
    C0 = .01*np.ones(Nx)
    # Append param params
    x0 = np.hstack([x0, param_mean*np.ones(Np)])
    C0 = np.hstack([C0, param_var*np.ones(Np)])
    return modelling.GaussRV(x0, C0)
Example #3
0
import dapper.mods as modelling
import dapper.tools.randvars as RVs
from dapper.mods.Lorenz96 import step
from dapper.tools.localization import nd_Id_localization

t = modelling.Chronology(0.05, dko=2, T=4**5, BurnIn=20)

Nx = 80
Dyn = {
    'M': Nx,
    'model': step,
    'noise': 0,
}

X0 = modelling.GaussRV(M=Nx, C=0.001)

jj = np.arange(0, Nx, 2)
Obs = modelling.partial_Id_Obs(Nx, jj)
Obs['localizer'] = nd_Id_localization((Nx,), (1,), jj)
# Obs['noise'] = RVs.LaplaceRV(C=1,M=len(jj))
Obs['noise'] = RVs.LaplaceParallelRV(C=1, M=len(jj))

HMM = modelling.HiddenMarkovModel(Dyn, Obs, t, X0)

####################
# Suggested tuning
####################

#                                                          rmse.a
# xps += LETKF(N=20,rot=True,infl=1.04       ,loc_rad=5) # 0.44
Example #4
0
try:
    # Load pre-generated
    L = np.load(sample_filename)['Left']
except FileNotFoundError:
    # First-time use
    print('Did not find sample file', sample_filename,
          'for experiment initialization. Generating...')
    NQ = 20000  # Must have NQ > (2*wnumQ+1)
    A = sinusoidal_sample(Nx, wnumQ, NQ)
    A = 1 / 10 * (A - A.mean(0)) / np.sqrt(NQ)
    Q = A.T @ A
    U, s, _ = tsvd(Q)
    L = U * np.sqrt(s)
    np.savez(sample_filename, Left=L)

X0 = modelling.GaussRV(C=modelling.CovMat(np.sqrt(5) * L, 'Left'))

###################
#  Forward model  #
###################
damp = 0.98
Fm = Fmat(Nx, -1, 1, tseq.dt)


def step(x, t, dt):
    assert dt == tseq.dt
    return x @ Fm.T


Dyn = {
    'M': Nx,
Example #5
0
################
# Full
################

# tseq = modelling.Chronology(dt=0.001,dto=0.05,T=4**3,BurnIn=6) # allows using rk2
tseq = modelling.Chronology(dt=0.005, dto=0.05, T=4**3,
                            BurnIn=6)  # requires rk4

Dyn = {
    'M': LUV.M,
    'model': modelling.with_rk4(LUV.dxdt, autonom=True),
    'noise': 0,
    'linear': LUV.dstep_dx,
}

X0 = modelling.GaussRV(mu=LUV.x0, C=0.01)

R = 0.1
jj = np.arange(nU)
Obs = modelling.partial_Id_Obs(LUV.M, jj)
Obs['noise'] = R

other = {'name': rel2mods(__file__) + '_full'}
HMM_full = modelling.HiddenMarkovModel(Dyn,
                                       Obs,
                                       tseq,
                                       X0,
                                       LP=LUV.LPs(jj),
                                       **other)

################
Example #6
0
Nx = len(x0)
Ny = Nx

day = 0.05 / 6 * 24  # coz dt=0.05 <--> 6h in "model time scale"
t = modelling.Chronology(0.05, dkObs=1, T=200 * day, BurnIn=10 * day)

Dyn = {
    'M': Nx,
    'model': step,
    'linear': dstep_dx,
    'noise': 0,
}

# X0 = modelling.GaussRV(C=0.01,M=Nx) # Decreased from Pajonk's C=1.
X0 = modelling.GaussRV(C=0.01, mu=x0)

jj = np.arange(Nx)
Obs = modelling.partial_Id_Obs(Nx, jj)
Obs['noise'] = 0.1

HMM = modelling.HiddenMarkovModel(Dyn, Obs, t, X0, LP=LPs(jj))

####################
# Suggested tuning
####################
# xps += ExtKF(infl=2)
# xps += EnKF('Sqrt',N=3,infl=1.01)
# xps += PartFilt(reg=1.0, N=100, NER=0.4) # add reg!
# xps += PartFilt(reg=1.0, N=1000, NER=0.1) # add reg!
Example #7
0
def hmod(E, t):
    return E[obs_inds(t)]


# Localization.
batch_shape = [2, 2]  # width (in grid points) of each state batch.
# Increasing the width
#  => quicker analysis (but less rel. speed-up by parallelzt., depending on NPROC)
#  => worse (increased) rmse (but width 4 is only slightly worse than 1);
#     if inflation is applied locally, then rmse might actually improve.
localizer = nd_Id_localization(shape[::-1], batch_shape[::-1], obs_inds, periodic=False)

Obs = {
    'M': Ny,
    'model': hmod,
    'noise': modelling.GaussRV(C=4*np.eye(Ny)),
    'localizer': localizer,
}

# Moving localization mask for smoothers:
Obs['loc_shift'] = lambda ii, dt: ii  # no movement (suboptimal, but easy)

# Jacobian left unspecified coz it's (usually) employed by methods that
# compute full cov, which in this case is too big.


############################
# Other
############################
HMM = modelling.HiddenMarkovModel(Dyn, Obs, t, X0, LP=LP_setup(obs_inds))
Example #8
0
import dapper.mods as modelling

from dapper.mods.LotkaVolterra import step, dstep_dx, x0, LP_setup, Tplot

t = modelling.Chronology(0.5, dto=10, T=1000, BurnIn=Tplot, Tplot=Tplot)

Nx = len(x0)

Dyn = {
    'M': Nx,
    'model': step,
    'linear': dstep_dx,
    'noise': 0,
}

X0 = modelling.GaussRV(mu=x0, C=0.01**2)

jj = [1, 3]
Obs = modelling.partial_Id_Obs(Nx, jj)
Obs['noise'] = 0.04**2

HMM = modelling.HiddenMarkovModel(Dyn, Obs, t, X0, LP=LP_setup(jj))

####################
# Suggested tuning
####################
# Not carefully tuned:
# xps += EnKF_N(N=6)
# xps += ExtKF(infl=1.02)
Example #9
0
Ny much lower than for the case H = Identity,
even though the rmse is a lot lower with spectral H.
Am I missing something?
"""

import numpy as np

import dapper.mods as modelling
from dapper.mods.Lorenz96.sakov2008 import Dyn, Nx, tseq

# The (Nx-Ny) highest frequency observation modes are left out of H below.
# If Ny>Nx, then H no longer has independent (let alone orthogonal) columns,
# yet more information is gained, since the observations are noisy.
Ny = 12

X0 = modelling.GaussRV(M=Nx, C=0.001)


def make_H(Ny, Nx):
    xx = np.linspace(-1, 1, Nx + 1)[1:]
    H = np.zeros((Ny, Nx))
    H[0] = 1 / np.sqrt(2)
    for k in range(-(Ny // 2), (Ny + 1) // 2):
        ind = 2 * abs(k) - (k < 0)
        H[ind] = np.sin(np.pi * k * xx + np.pi / 4)
    H /= np.sqrt(Nx / 2)
    return H


H = make_H(Ny, Nx)
# plt.figure(1).gca().matshow(H)
Example #10
0
from dapper.tools.localization import nd_Id_localization

# Sakov uses K=300000, BurnIn=1000*0.05
tseq = modelling.Chronology(0.05, dko=1, Ko=1000, Tplot=Tplot, BurnIn=2*Tplot)

Nx = 40
x0 = x0(Nx)

Dyn = {
    'M': Nx,
    'model': step,
    'linear': dstep_dx,
    'noise': 0,
}

X0 = modelling.GaussRV(mu=x0, C=0.001)

jj = np.arange(Nx)  # obs_inds
Obs = modelling.partial_Id_Obs(Nx, jj)
Obs['noise'] = 1
Obs['localizer'] = nd_Id_localization((Nx,), (2,))

HMM = modelling.HiddenMarkovModel(Dyn, Obs, tseq, X0)

HMM.liveplotters = LPs(jj)


####################
# Suggested tuning
####################
Example #11
0
"""From `dapper.mods.Lorenz96.todter2015` again, but with Gaussian likelihood."""

import dapper.mods as modelling
from dapper.mods.Lorenz96.todter2015 import HMM as _HMM

HMM = _HMM.copy()
HMM.Obs.noise = modelling.GaussRV(C=HMM.Obs.noise.C)

####################
# Suggested tuning
####################

#                                                          rmse.a
# xps += LETKF(N=40,rot=True,infl=1.04       ,loc_rad=5) # 0.42
# xps += LETKF(N=80,rot=True,infl=1.04       ,loc_rad=5) # 0.42

# xps += LNETF(N=40,rot=True,infl=1.10,Rs=1.9,loc_rad=5) # 0.54
# xps += LNETF(N=80,rot=True,infl=1.06,Rs=1.4,loc_rad=5) # 0.47
Example #12
0
"""Settings that produce somewhat interesting/challenging DA problems."""

import numpy as np
import dapper.mods as modelling

from dapper.mods.Ikeda import step, x0, Tplot, LPs

tseq = modelling.Chronology(1, dko=1, Ko=1000, Tplot=Tplot, BurnIn=4 * Tplot)

Nx = len(x0)

Dyn = {
    'M': Nx,
    'model': step,
    'noise': 0,
}

X0 = modelling.GaussRV(C=.1, mu=x0)

jj = np.arange(Nx)  # obs_inds
Obs = modelling.partial_Id_Obs(Nx, jj)
Obs['noise'] = .1  # modelling.GaussRV(C=CovMat(1*eye(Nx)))

HMM = modelling.HiddenMarkovModel(Dyn, Obs, tseq, X0)

HMM.liveplotters = LPs(jj)

####################
# Suggested tuning
####################
Example #13
0
t = modelling.Chronology(0.01,
                         dkObs=12,
                         KObs=1000,
                         Tplot=Tplot,
                         BurnIn=4 * Tplot)

Nx = len(x0)

Dyn = {
    'M': Nx,
    'model': step,
    'linear': dstep_dx,
    'noise': 0,
}

X0 = modelling.GaussRV(C=2, mu=x0)

Obs = modelling.partial_Id_Obs(Nx, np.arange(Nx))
Obs['noise'] = 8.0

HMM = modelling.HiddenMarkovModel(Dyn, Obs, t, X0)

####################
# Suggested tuning
####################
# Compare with Anderson's figure 10.
# Benchmarks are fairly reliable (KObs=2000):
# from dapper.mods.Lorenz63.anderson2010rhf import HMM   # rmse.a
# xps += SL_EAKF(N=20,infl=1.01,rot=True,loc_rad=np.inf) # 0.87
# xps += EnKF_N (N=20,rot=True)                          # 0.87
# xps += RHF    (N=50,infl=1.10)                         # 1.28
Example #14
0
model.Force = 8.17
tseq = modelling.Chronology(0.01, dko=10, K=4000, Tplot=10, BurnIn=10)

Nx = 1000

Dyn = {
    'M': Nx,
    'model': step,
    # It's not clear from the paper whether Q=0.5 or 0.25.
    # But I'm pretty sure it's applied each dto (not dt).
    'noise': 0.25 / tseq.dto,
    # 'noise': 0.5 / t.dto,
}

X0 = modelling.GaussRV(mu=x0(Nx), C=0.001)

jj = linspace_int(Nx, Nx // 4, periodic=True)
Obs = modelling.partial_Id_Obs(Nx, jj)
Obs['noise'] = 0.1**2
Obs['localizer'] = nd_Id_localization((Nx, ), (1, ), jj, periodic=True)

HMM = modelling.HiddenMarkovModel(Dyn, Obs, tseq, X0)

HMM.liveplotters = LPs(jj)

# Pinheiro et al. use
# - N = 30, but this is only really stated for their PF.
# - loc-rad = 4, but don't state its definition, nor the exact tapering function.
# - infl-factor 1.05, but I'm not sure if it's squared or not.
#
Example #15
0
Fm = Fmat(Nx, -1, 1, tseq.dt)


def step(x, t, dt):
    assert dt == tseq.dt
    return x @ Fm.T


Dyn = {
    'M': Nx,
    'model': step,
    'linear': lambda x, t, dt: Fm,
    'noise': 0,
}

X0 = modelling.GaussRV(mu=np.zeros(Nx),
                       C=homogeneous_1D_cov(Nx, Nx / 8, kind='Gauss'))

Ny = 4
jj = modelling.linspace_int(Nx, Ny)
Obs = modelling.partial_Id_Obs(Nx, jj)
Obs['noise'] = 0.01

HMM = modelling.HiddenMarkovModel(Dyn, Obs, tseq, X0, LP=LPs(jj))

####################
# Suggested tuning
####################
# xps += EnKF('PertObs',N=16 ,infl=1.02)
# xps += EnKF('Sqrt'   ,N=16 ,infl=1.0)
Example #16
0
"""The identity model (that does nothing, i.e. sets `output = input`).

This means that the state dynamics are just Brownian motion.

Next to setting the state to a constant, this is the simplest model you can think of.
"""
import dapper.mods as modelling

tseq = modelling.Chronology(1, dko=1, Ko=2000, Tplot=10, BurnIn=0)
M = 4
Obs = {'noise': 2, 'M': M}
Dyn = {'noise': 1, 'M': M}
X0 = modelling.GaussRV(C=1, M=M)

HMM = modelling.HiddenMarkovModel(Dyn, Obs, tseq, X0)

#########################
#  Benchmarking script  #
#########################
# import dapper as dpr
# dpr.rc.field_summaries.append("ms")

# # We do not include Climatology and OptInterp because their variance and accuracy
# # are less interesting since they grow with the duration of the experiment.
# import dapper.da_methods as da
# xps = dpr.xpList()
# xps += da.Var3D("eye", xB=2)
# xps += da.ExtKF()
# xps += da.EnKF('Sqrt', N=100)

# save_as = xps.launch(HMM, save_as=False)