Skip to content

Commit 4536a16

Browse files
System AdministratorSystem Administrator
authored andcommitted
updates to tutorial layout/design
1 parent acb0a11 commit 4536a16

19 files changed

Lines changed: 1296 additions & 168 deletions

class_da_system.py

Lines changed: 100 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
from class_state_vector import state_vector
44
from class_obs_data import obs_data
55
import numpy.matlib
6+
import pickle
67

78
class da_system:
89

9-
def __init__(self,x0=[0],yo=[0],t0=0,dt=0,alpha=0.5):
10+
def __init__(self,x0=[0],yo=[0],t0=0,dt=0,alpha=0.5,state_vector=[0],obs_data=[0]):
1011
self.xdim = np.size(x0)
1112
self.ydim = np.size(yo)
1213
self.edim = 1
@@ -15,12 +16,15 @@ def __init__(self,x0=[0],yo=[0],t0=0,dt=0,alpha=0.5):
1516
self.dt = dt
1617
self.X0 = x0
1718
self.t = t0
19+
self.ainc = 1
1820
self.B = np.matrix(np.identity(self.xdim))
1921
self.R = np.matrix(np.identity(self.ydim))
2022
self.H = np.matrix(np.identity(self.xdim))
2123
self.Ht = (self.H).transpose()
2224
self.alpha = alpha
2325
self.SqrtB = sp.linalg.sqrtm(self.B)
26+
self.obs_data = obs_data
27+
self.state_vector = state_vector
2428

2529
def __str__(self):
2630
print('xdim = ', self.xdim)
@@ -38,6 +42,21 @@ def __str__(self):
3842
def setMethod(self,method):
3943
self.method = method
4044

45+
def getMethod(self):
46+
return self.method
47+
48+
def setStateVector(self,sv):
49+
self.state_vector = sv
50+
51+
def setObsData(self,obs):
52+
self.obs_data = obs
53+
54+
def getStateVector(self):
55+
return self.state_vector
56+
57+
def getObsData(self):
58+
return self.obs_data
59+
4160
def update(self,B=[0],R=[0],H=[0],t=[0],x0=[0]):
4261
# Update the state of the DA system for a new cycle
4362
self.B = B
@@ -68,8 +87,8 @@ def getR(self):
6887

6988
def setR(self,R):
7089
self.R = np.matrix(R)
71-
nr,nc = np.shape(R)
72-
self.ydim = nr
90+
# nr,nc = np.shape(R)
91+
# self.ydim = nr
7392
self.Rinv = np.linalg.inv(R)
7493

7594
def getH(self):
@@ -78,13 +97,20 @@ def getH(self):
7897
def setH(self,H):
7998
self.H = np.matrix(H)
8099
self.Ht = np.transpose(self.H)
81-
nr,nc = np.shape(H)
100+
# nr,nc = np.shape(H)
82101

83102
# Verify that H is ydim x xdim
84-
if (nr != self.ydim):
85-
error('H must be ydim x xdim, but instead H is %d x %d'%(nr,nc))
86-
if (nc != self.xdim):
87-
error('H must be ydim x xdim, but instead H is %d x %d'%(nr,nc))
103+
# if (nr != self.ydim):
104+
# error('H must be ydim x xdim, but instead H is %d x %d'%(nr,nc))
105+
# if (nc != self.xdim):
106+
# error('H must be ydim x xdim, but instead H is %d x %d'%(nr,nc))
107+
108+
def reduceYdim(self,yp):
109+
# print('reduceYdim:')
110+
# print('yp = ', yp)
111+
self.ydim = len(yp)
112+
self.setH(self.H[yp,:])
113+
self.setR(self.R[yp,yp])
88114

89115
def compute_analysis(self,xb,yo,params=[0]):
90116
method = self.method
@@ -125,10 +151,10 @@ def initEns(self,x0,mu=0,sigma=0.1,edim=4):
125151
X0 = np.matrix(rmat + xrand)
126152
return X0
127153

128-
# def init_4D(self):
154+
# def init4D(self):
129155
# xdim = size(self.x0)
130156

131-
# def init_4DEns(self):
157+
# def init4DEns(self):
132158
# xdim = size(self.x0)
133159

134160
#---------------------------------------------------------------------------------------------------
@@ -157,19 +183,27 @@ def OI(self,xb,yo):
157183
yo = np.matrix(yo).flatten().T
158184

159185
# Use explicit expression to solve for the analysis
160-
print(self)
186+
# print(self)
161187
Hl = self.H
162188
Ht = self.Ht
163189
B = self.B
164190
R = self.R
165191

166-
KH = B*Ht*np.linalg.inv(H*B*Ht + R)*Hl
192+
# print('H = ')
193+
# print(Hl)
194+
195+
# print('R = ')
196+
# print(R)
197+
198+
# Should be dimensioned: xdim * xdim
199+
K = B*Ht*np.linalg.inv(Hl*B*Ht + R)
200+
KH = K*Hl
167201

168-
print('KH = ')
169-
print(KH)
202+
# print('KH = ')
203+
# print(KH)
170204

171205
Hxb = Hl*xb
172-
xa = xb + KH*(yo - Hxb)
206+
xa = xb + K*(yo - Hxb)
173207

174208
return xa.A1, KH
175209

@@ -179,20 +213,18 @@ def _3DVar(self,xb,yo):
179213
#---------------------------------------------------------------------------------------------------
180214
# Use minimization algorithm to solve for the analysis
181215

216+
# make inputs column vectors
182217
xb = np.matrix(xb).flatten().T
183218
yo = np.matrix(yo).flatten().T
184219

220+
# Set parameters
185221
xdim = self.xdim
186222
Hl = self.H
187223
Ht = self.Ht
188224
B = self.B
189225
R = self.R
190226
Rinv = np.linalg.inv(R)
191227

192-
# make inputs column vectors
193-
xb = np.matrix(xb).flatten().T
194-
yo = np.matrix(yo).flatten().T
195-
196228
# 'preconditioning with B'
197229
I = np.identity(xdim)
198230
BHt = B*Ht
@@ -204,13 +236,12 @@ def _3DVar(self,xb,yo):
204236
xa,ierr = sp.sparse.linalg.cg(A,b1,x0=xb,tol=1e-05,maxiter=1000)
205237
# xa,ierr = sp.sparse.linalg.bicgstab(A,b1,x0=np.zeros_like(b1),tol=1e-05,maxiter=1000)
206238
# try: gmres,
207-
# xa = sp.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)
208239

209240
# Compute KH:
210241
HBHtPlusR_inv = np.linalg.inv(Hl*BHt + R)
211242
KH = BHt*HBHtPlusR_inv*Hl
212243

213-
return xa.A1, KH
244+
return xa, KH
214245

215246

216247
#---------------------------------------------------------------------------------------------------
@@ -282,27 +313,27 @@ def ETKF(self,Xb,yo):
282313
#---------------------------------------------------------------------------------------------------
283314
# Use minimization over a time window to solve for the analysis
284315
#
316+
# xb_4d = np.matrix(np.atleast_2d(xb_4d))
317+
# yo_4d = np.matrix(np.atleast_2d(yo_4d))
318+
# nr,nc = np.shape(xb_4d) ! columns are state vectors at consecutive timesteps
319+
# xdim = nr
320+
# tdim = nc
285321
# B = self.B
286-
# R = self.R
287-
# xdim = self.xdim
288-
# Xb = np.matrix(np.atleast_2d(Xb))
289-
# Yo = np.matrix(np.atleast_2d(Yo))
290-
# Yp = np.matrix(np.atleast_2d(Yp))
291-
322+
# R_4d = self.R ! may need list of R matrices if observations are non-uniform over time
323+
# H_4d = self.H ! may need list of H matrices if observations are non-uniform over time
324+
# M_4d = self.M ! input list of TLMs for each timestep
292325

293326

294327
#---------------------------------------------------------------------------------------------------
295328
# def _4DEnVar(self,Xb_4d,yo_4d):
296329
#---------------------------------------------------------------------------------------------------
297330
# Use ensemble of states over a time window to estimate temporal correlations
298-
# xdim = size(self.x0)
299331

300332

301333
#---------------------------------------------------------------------------------------------------
302334
# def _4DETKF(self,Xb_4d,yo_4d):
303335
#---------------------------------------------------------------------------------------------------
304336
# Use ensemble of states over a time window to estimate temporal correlations
305-
# xdim = size(self.x0)
306337

307338

308339
#---------------------------------------------------------------------------------------------------
@@ -370,8 +401,8 @@ def PF(self,Xb,yo):
370401
if (Neff < edim/2):
371402
# Apply additive inflation (remove sample mean)
372403
const=1.0
373-
rmat=np.rand.randn(xdim,edim) * np.matlib.repmat(np.std(Xa,axis=1),0,edim) * const;
374-
Xa = Xa + rmat - np.matlib.repmat(np.mean(rmat,axis=1),0,edim);
404+
rmat=np.rand.randn(xdim,edim) * np.matlib.repmat(np.std(Xa,axis=1),1,edim) * const;
405+
Xa = Xa + rmat - np.matlib.repmat(np.mean(rmat,axis=1),1,edim);
375406

376407
KH = [0] # dummy output
377408

@@ -386,17 +417,53 @@ def HybridGain(self,Xb,yo):
386417
Xb = np.matrix(Xb)
387418
yo = np.matrix(yo).flatten().T
388419

420+
# Get parameters
421+
alpha = self.alpha
422+
nr,nc = np.shape(Xb)
423+
xdim = nr
424+
edim = nc
425+
ydim = len(yo)
426+
389427
# Compute ETKF analysis
390428
Xa_ETKF, KH_ETKF = self.ETKF(Xb,yo)
429+
print('Xa_ETKF = ')
430+
print(Xa_ETKF)
391431

392432
# Compute 3DVar analysis
393433
xa_ETKF = np.mean(Xa_ETKF,axis=1)
434+
print('xa_ETKF = ')
435+
print(xa_ETKF)
394436
xa_3DVar, KH_3DVar = self._3DVar(xa_ETKF,yo)
437+
print('xa_3DVar = ')
438+
print(xa_3DVar)
439+
440+
xa_ETKF = np.matrix(xa_ETKF).flatten().T
441+
xa_3DVar = np.matrix(xa_3DVar).flatten().T
442+
443+
# Recover ensemble perturbations
444+
Xa_ETKF = Xa_ETKF - np.matlib.repmat(xa_ETKF,1,edim)
395445

396-
# Form hybrid combination
446+
# Form hybrid combination to update the mean state
397447
xa_hybrid = (1-alpha)*xa_ETKF + alpha*xa_3DVar
398-
Xa = Xa_ETKF + xa_hybrid[:,np.newaxis]
448+
Xa = Xa_ETKF + np.matlib.repmat(xa_hybrid,1,edim)
449+
450+
print('xa_hybrid = ')
451+
print(xa_hybrid)
399452

400453
KH = (1-alpha)*KH_ETKF + alpha*KH_3DVar
401454

402455
return Xa, KH
456+
457+
458+
#---------------------------------------------------------------------------------------------------
459+
def save(self,outfile):
460+
#---------------------------------------------------------------------------------------------------
461+
with open(outfile,'wb') as output:
462+
pickle.dump(self,output,pickle.HIGHEST_PROTOCOL)
463+
464+
#---------------------------------------------------------------------------------------------------
465+
def load(self,infile):
466+
#---------------------------------------------------------------------------------------------------
467+
with open(infile,'rb') as input:
468+
das = pickle.load(input)
469+
return das

0 commit comments

Comments
 (0)