|
1 |
| - |
2 | 1 | clear;
|
3 | 2 | close all;
|
4 | 3 | figure;
|
5 | 4 | drawnow;
|
6 | 5 |
|
7 |
| -Deltat = 0.11; |
| 6 | +Deltat = 0.11; |
8 | 7 |
|
9 | 8 | solvermodel = @(f, t, y) datools.utils.rk4(f, t, y, 22);
|
10 | 9 | solvernature = @(f, t, y) datools.utils.rk4(f, t, y, 22);
|
|
16 | 15 | modelODE = otp.lorenz96.presets.Canonical;
|
17 | 16 | modelODE.TimeSpan = [0, Deltat];
|
18 | 17 |
|
19 |
| -[tt, yy] = ode45(natureODE.Rhs.F, [0 10], nature0); |
20 |
| -nature0 = yy(end, :).'; |
| 18 | +[tt, yy] = ode45(natureODE.Rhs.F, [0, 10], nature0); |
| 19 | +nature0 = yy(end, :).'; |
21 | 20 | natureODE.Y0 = nature0;
|
22 | 21 |
|
23 |
| -model = datools.Model('Solver', solvermodel, 'ODEModel', modelODE); |
| 22 | +model = datools.Model('Solver', solvermodel, 'ODEModel', modelODE); |
24 | 23 | nature = datools.Model('Solver', solvernature, 'ODEModel', natureODE);
|
25 | 24 |
|
26 | 25 | naturetomodel = datools.observation.Linear(numel(nature0), 'H', speye(natureODE.NumVars));
|
|
29 | 28 |
|
30 | 29 | nobsvars = numel(observeindicies);
|
31 | 30 |
|
32 |
| -R = (8/1)*speye(nobsvars); |
| 31 | +R = (8 / 1) * speye(nobsvars); |
33 | 32 |
|
34 | 33 | obserrormodel = datools.error.Gaussian('CovarianceSqrt', sqrtm(R));
|
35 | 34 | %obserrormodel = datools.error.Tent;
|
|
46 | 45 | ensNs = 20:5:30;
|
47 | 46 | alphass = 0.0:0.1:0.5;
|
48 | 47 |
|
49 |
| -rmses = inf*ones(numel(ensNs), numel(alphass)); |
| 48 | +rmses = inf * ones(numel(ensNs), numel(alphass)); |
50 | 49 |
|
51 | 50 | maxallowerr = 16;
|
52 | 51 |
|
53 | 52 | mm = min(rmses(:));
|
54 | 53 |
|
55 |
| -if mm >= maxallowerr |
| 54 | +if mm >= maxallowerr |
56 | 55 | mm = 0;
|
57 | 56 | end
|
58 | 57 |
|
59 | 58 | runsleft = find(rmses == inf);
|
60 | 59 |
|
61 | 60 | for runn = runsleft.'
|
62 | 61 | [ensNi, infi] = ind2sub([numel(ensNs), numel(alphass)], runn);
|
63 |
| - |
| 62 | + |
64 | 63 | fprintf('N: %d, inf: %.3f\n', ensNs(ensNi), alphass(infi));
|
65 |
| - |
| 64 | + |
66 | 65 | ns = 1;
|
67 | 66 | sE = zeros(ns, 1);
|
68 |
| - |
| 67 | + |
69 | 68 | alphassAll = alphass(infi);
|
70 | 69 | ensN = ensNs(ensNi);
|
71 |
| - |
| 70 | + |
72 | 71 | for sample = 1:ns
|
73 | 72 | % Set rng for standard experiments
|
74 |
| - rng(17 + sample - 1); |
75 |
| - |
| 73 | + rng(17+sample-1); |
| 74 | + |
76 | 75 | inflation = 1;
|
77 |
| - |
| 76 | + |
78 | 77 | % No localization
|
79 | 78 | %localization = [];
|
80 |
| - |
| 79 | + |
81 | 80 | %localization= @(t, y, H) datools.tapering.gc(t, y, r, d, H);
|
82 | 81 | r = 3;
|
83 | 82 | d = @(t, y, i, j) modelODE.DistanceFunction(t, y, i, j);
|
84 | 83 | localization = @(t, y, Hi, k) datools.tapering.gcCTilde(t, y, Hi, r, d, k);
|
85 | 84 | %localization = @(t, y, Hi, k) datools.tapering.cutoffCTilde(t, y, r, d, Hi, k);
|
86 |
| - |
| 85 | + |
87 | 86 | % required for LETPF
|
88 |
| - localizationEnsembleDistance = @(~, ~, inds, k) spdiags([zeros(k - 1, 1); 1; zeros(numel(inds) - k + 1, 1)], 0, numel(inds), numel(inds)); |
89 |
| - |
| 87 | + localizationEnsembleDistance = @(~, ~, inds, k) spdiags([zeros(k-1, 1); 1; zeros(numel(inds)-k+1, 1)], 0, numel(inds), numel(inds)); |
| 88 | + |
90 | 89 | fnum = 1;
|
91 |
| - |
| 90 | + |
92 | 91 | filters = cell(fnum, 1);
|
93 | 92 | %alphas = ones(fnum*2, 1)/(2*fnum);
|
94 |
| - alphas = ones(fnum, 1)/(fnum); |
95 |
| - |
| 93 | + alphas = ones(fnum, 1) / (fnum); |
| 94 | + |
96 | 95 | for i = 1:fnum
|
97 |
| - |
| 96 | + |
98 | 97 | letkf = datools.statistical.ensemble.LETKF(model, ...
|
99 | 98 | 'Observation', observation, ...
|
100 | 99 | 'NumEnsemble', ensN, ...
|
101 | 100 | 'ModelError', modelerror, ...
|
102 | 101 | 'EnsembleGenerator', ensembleGenerator, ...
|
103 |
| - 'Inflation', inflation^(1/fnum), ... |
| 102 | + 'Inflation', inflation^(1 / fnum), ... |
104 | 103 | 'Localization', localization, ...
|
105 | 104 | 'Rejuvenation', 0, ...
|
106 | 105 | 'Parallel', false);
|
107 |
| - |
108 |
| - |
109 |
| - |
| 106 | + |
| 107 | + |
110 | 108 | letpf = datools.statistical.ensemble.LETPF2(model, ...
|
111 | 109 | 'Observation', observation, ...
|
112 | 110 | 'NumEnsemble', ensN, ...
|
|
118 | 116 | 'Rejuvenation', 0, ...
|
119 | 117 | 'Parallel', false);
|
120 | 118 |
|
121 |
| - filters{2*i - 1} = letpf; |
122 |
| - filters{2*i} = letkf; |
123 |
| - alphas(2*i - 1) = alphassAll; |
124 |
| - alphas(2*i) = 1 - alphassAll; |
125 |
| - |
| 119 | + filters{2*i-1} = letpf; |
| 120 | + filters{2*i} = letkf; |
| 121 | + alphas(2*i-1) = alphassAll; |
| 122 | + alphas(2*i) = 1 - alphassAll; |
| 123 | + |
126 | 124 | end
|
127 |
| - |
128 |
| - alphas = alphas/sum(alphas); |
129 |
| - |
130 |
| - |
| 125 | + |
| 126 | + alphas = alphas / sum(alphas); |
| 127 | + |
| 128 | + |
131 | 129 | hybrid = datools.statistical.ensemble.Hybrid(model, ...
|
132 | 130 | 'Observation', observation, ...
|
133 | 131 | 'NumEnsemble', ensN, ...
|
|
137 | 135 | 'Localization', localization, ...
|
138 | 136 | 'Filters', filters, ...
|
139 | 137 | 'Alphas', alphas, ...
|
140 |
| - 'Rejuvenation', (0.2^2), ... |
| 138 | + 'Rejuvenation', (0.2^2), ... |
141 | 139 | 'Parallel', false);
|
142 |
| - |
143 |
| - |
144 |
| - |
| 140 | + |
| 141 | + |
145 | 142 | natureODE.Y0 = nature0;
|
146 | 143 | nature = datools.Model('Solver', solvernature, 'ODEModel', natureODE);
|
147 | 144 |
|
148 |
| - |
| 145 | + |
149 | 146 | hybrid.setMean(natureODE.Y0);
|
150 | 147 | hybrid.scaleAnomalies(1/10);
|
151 |
| - |
| 148 | + |
152 | 149 | spinup = 200;
|
153 |
| - times = 11*spinup; |
154 |
| - |
| 150 | + times = 11 * spinup; |
| 151 | + |
155 | 152 | mses = zeros(times - spinup, 1);
|
156 |
| - |
| 153 | + |
157 | 154 | rmse = nan;
|
158 |
| - |
| 155 | + |
159 | 156 | ps = '';
|
160 |
| - |
| 157 | + |
161 | 158 | do_enkf = true;
|
162 |
| - |
| 159 | + |
163 | 160 | for i = 1:times
|
164 | 161 | % forecast
|
165 |
| - |
| 162 | + |
166 | 163 | nature.evolve();
|
167 |
| - |
| 164 | + |
168 | 165 | if do_enkf
|
169 | 166 | hybrid.forecast();
|
170 | 167 | end
|
171 |
| - |
172 |
| - |
| 168 | + |
| 169 | + |
173 | 170 | % observe
|
174 | 171 | xt = naturetomodel.observeWithoutError(nature.TimeSpan(1), nature.State);
|
175 | 172 | y = hybrid.Observation.observeWithError(model.TimeSpan(1), xt);
|
176 |
| - |
| 173 | + |
177 | 174 | % analysis
|
178 |
| - |
| 175 | + |
179 | 176 | % try
|
180 | 177 | if do_enkf
|
181 | 178 | hybrid.analysis(R, y);
|
182 | 179 | end
|
183 | 180 | %catch
|
184 | 181 | % do_enkf = false;
|
185 | 182 | %end
|
186 |
| - |
| 183 | + |
187 | 184 | xa = hybrid.BestEstimate;
|
188 |
| - |
| 185 | + |
189 | 186 | err = xt - xa;
|
190 |
| - |
| 187 | + |
191 | 188 | if i > spinup
|
192 |
| - |
| 189 | + |
193 | 190 | mses(i - spinup) = mean((xa - xt).^2);
|
194 | 191 | rmse = sqrt(mean(mses(1:(i - spinup))));
|
195 |
| - |
196 |
| - if rmse > maxallowerr || isnan(rmse) || mses(i - spinup) > 200*maxallowerr |
| 192 | + |
| 193 | + if rmse > maxallowerr || isnan(rmse) || mses(i - spinup) > 200 * maxallowerr |
197 | 194 | do_enkf = false;
|
198 | 195 | end
|
199 |
| - |
| 196 | + |
200 | 197 | if mod(i, 10) == 0
|
201 | 198 | fprintf('step %d %.5f\n', i, rmse);
|
202 | 199 | end
|
203 |
| - |
| 200 | + |
204 | 201 | else
|
205 |
| - |
| 202 | + |
206 | 203 | fprintf('%d|', i)
|
207 | 204 | if mod(i, 10) == 0
|
208 | 205 | fprintf('\n');
|
209 | 206 | end
|
210 |
| - |
| 207 | + |
211 | 208 | end
|
212 |
| - |
213 |
| - |
| 209 | + |
| 210 | + |
214 | 211 | if ~do_enkf
|
215 | 212 | break;
|
216 | 213 | end
|
217 |
| - |
| 214 | + |
218 | 215 | end
|
219 |
| - |
| 216 | + |
220 | 217 | if isnan(rmse)
|
221 | 218 | rmse = 1000;
|
222 | 219 | end
|
223 |
| - |
| 220 | + |
224 | 221 | if ~do_enkf
|
225 | 222 | sE(sample) = 1000;
|
226 | 223 | else
|
227 | 224 | sE(sample) = rmse;
|
228 | 225 | end
|
229 |
| - |
| 226 | + |
230 | 227 | end
|
231 |
| - |
| 228 | + |
232 | 229 | resE = mean(sE);
|
233 |
| - |
| 230 | + |
234 | 231 | if isnan(resE)
|
235 | 232 | resE = 1000;
|
236 | 233 | end
|
237 |
| - |
| 234 | + |
238 | 235 | rmses(ensNi, infi) = resE;
|
239 |
| - |
| 236 | + |
240 | 237 | mm = min(rmses(:));
|
241 |
| - |
242 |
| - if mm >= maxallowerr |
| 238 | + |
| 239 | + if mm >= maxallowerr |
243 | 240 | mm = 0;
|
244 | 241 | end
|
245 |
| - |
246 |
| - imagesc(ensNs, alphass, rmses.'); caxis([1, 2.5]); colorbar; set(gca,'YDir','normal'); |
247 |
| - axis square; title('EnKF'); colormap('pink'); |
248 |
| - xlabel('Ensemble Size'); ylabel('\alpha'); |
| 242 | + |
| 243 | + imagesc(ensNs, alphass, rmses.'); |
| 244 | + caxis([1, 2.5]); |
| 245 | + colorbar; |
| 246 | + set(gca, 'YDir', 'normal'); |
| 247 | + axis square; |
| 248 | + title('EnKF'); |
| 249 | + colormap('pink'); |
| 250 | + xlabel('Ensemble Size'); |
| 251 | + ylabel('\alpha'); |
249 | 252 | drawnow;
|
250 | 253 | end
|
251 | 254 |
|
|
0 commit comments