Skip to content

Commit f0db3ca

Browse files
author
klinogrid
committed
added vec3 functions for ..._ensi_multi_...
1 parent de6dcd9 commit f0db3ca

File tree

2 files changed

+258
-21
lines changed

2 files changed

+258
-21
lines changed

include/gridpp.h

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -293,23 +293,22 @@ namespace gridpp {
293293
int max_points,
294294
bool allow_extrapolation=true);
295295

296-
/** Optimal interpolation for an ensemble gridded field (alternative version). This is an experimental method.
297-
* @param bgrid Grid of background field
296+
/**Optimal interpolation for an ensemble gridded field with ensemble-based correlations. The function supports iterative corrections to the analysis. Each ensemble member is adjusted iteratively or "ensemble member by ensemble member" (ebe).
297+
* @param bgrid Grid of background field
298298
* @param bratios 2D vector (Y, X) of the ratio of background error standard deviation at grid points to that at observation points.
299299
* @param background 3D vector (Y, X, E) representing the background values at grid points to be updated.
300300
* @param background_corr 3D vector (Y, X, E) representing the background values used to compute dynamic correlations.
301-
* @param obs_points observation points. S = num. observations
302-
* @param pobs 2D vector of perturbed observations (S, E)
301+
* @param obs_points Observation points (S = num. observations)
302+
* @param pobs 2D vector of perturbed observations (S, E)
303303
* @param pratios 1D vector (S) of the ratio of observation to background error variance.
304304
* @param pbackground 2D vector (S, E) representing the background values at observation points used to compute innovations.
305305
* @param pbackground_corr 2D vector (S, E) representing the background values at observation points used to compute dynamic correlations.
306-
* @param structure Structure function
306+
* @param structure Structure function for the localization function
307307
* @param max_points Maximum number of observations to use inside localization zone; Use 0 to disable
308-
* @param dynamic_correlations Determines whether to use flow-dependent correlations derived from the ensembles. If true, the structure function defines localization functions. If false, the structure function defines static (non-flow-dependent) correlations.
309308
* @param allow_extrapolation Allow EnSI to extrapolate increments outside increments at observations
310309
* @returns 3D vector of analised values (Y, X, E)
311310
*/
312-
vec3 optimal_interpolation_ensi_multi(const Grid& bgrid,
311+
vec3 optimal_interpolation_ensi_multi_ebe(const Grid& bgrid,
313312
const vec2& bratios,
314313
const vec3& background,
315314
const vec3& background_corr,
@@ -320,7 +319,58 @@ namespace gridpp {
320319
const vec2& pbackground_corr,
321320
const StructureFunction& structure,
322321
int max_points,
323-
bool dynamic_correlations=true,
322+
bool allow_extrapolation=true);
323+
324+
/** Optimal interpolation for an ensemble gridded field with static correlations. The function supports iterative corrections to the analysis.
325+
* @param bgrid Grid of background field
326+
* @param bratios 2D vector (Y, X) of the ratio of background error standard deviation at grid points to that at observation points.
327+
* @param background 3D vector (Y, X, E) representing the background values at grid points to be updated.
328+
* @param obs_points Observation points (S = num. observations)
329+
* @param pobs 2D vector of perturbed observations (S, E)
330+
* @param pratios 1D vector (S) of the ratio of observation to background error variance.
331+
* @param pbackground 2D vector (S, E) representing the background values at observation points used to compute innovations.
332+
* @param structure Structure function for the correlation function
333+
* @param max_points Maximum number of observations to use inside localization zone; Use 0 to disable
334+
* @param allow_extrapolation Allow EnSI to extrapolate increments outside increments at observations
335+
* @returns 3D vector of analised values (Y, X, E)
336+
*/
337+
vec3 optimal_interpolation_ensi_multi_ebesc(const Grid& bgrid,
338+
const vec2& bratios,
339+
const vec3& background,
340+
const Points& obs_points,
341+
const vec2& pobs,
342+
const vec& pratios,
343+
const vec2& pbackground,
344+
const StructureFunction& structure,
345+
int max_points,
346+
bool allow_extrapolation=true);
347+
348+
/** Optimal interpolation for an ensemble gridded field with ensemble-based correlations. The function supports iterative corrections to the analysis. First, "use (and adjust) the ensemble mean" (utem), then generate the analysis ensemble.
349+
* @param bgrid Grid of background field
350+
* @param bratios 2D vector (Y, X) of the ratio of background error standard deviation at grid points to that at observation points.
351+
* @param background 3D vector (Y, X, E) representing the background values at grid points to be updated.
352+
* @param background_corr 3D vector (Y, X, E) representing the background values used to compute dynamic correlations.
353+
* @param obs_points Observation points (S = num. observations)
354+
* @param pobs 1D vector of observations (S)
355+
* @param pratios 1D vector (S) of the ratio of observation to background error variance.
356+
* @param pbackground 2D vector (S, E) representing the background values at observation points used to compute innovations.
357+
* @param pbackground_corr 2D vector (S, E) representing the background values at observation points used to compute dynamic correlations.
358+
* @param structure Structure function for the localization function
359+
* @param max_points Maximum number of observations to use inside localization zone; Use 0 to disable
360+
* @param allow_extrapolation Allow EnSI to extrapolate increments outside increments at observations
361+
* @returns 3D vector of analised values (Y, X, E)
362+
*/
363+
vec3 optimal_interpolation_ensi_multi_utem(const Grid& bgrid,
364+
const vec2& bratios,
365+
const vec3& background,
366+
const vec3& background_corr,
367+
const Points& obs_points,
368+
const vec& pobs,
369+
const vec& pratios,
370+
const vec2& pbackground,
371+
const vec2& pbackground_corr,
372+
const StructureFunction& structure,
373+
int max_points,
324374
bool allow_extrapolation=true);
325375

326376
/** Optimal interpolation for an ensemble point field with ensemble-based correlations. The function supports iterative corrections to the analysis. Each ensemble member is adjusted iteratively or "ensemble member by ensemble member" (ebe).
@@ -380,7 +430,7 @@ namespace gridpp {
380430
* @param bratios 1D vector (L) of the ratio of background error standard deviation at grid points to that at observation points.
381431
* @param background 2D vector (L, E) representing the background values at grid points to be updated.
382432
* @param obs_points Observation points (S = num. observations)
383-
* @param pobs 2D vector of perturbed observations (S, E)
433+
* @param pobs 1D vector of observations (S)
384434
* @param pratios 1D vector (S) of the ratio of observation to background error variance.
385435
* @param pbackground 2D vector (S, E) representing the background values at observation points used to compute innovations.
386436
* @param structure Structure function for the static correlations

src/api/oi_ensi_multi.cpp

Lines changed: 199 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,18 @@ void print_matrix(Matrix matrix) {
3030
template void print_matrix< ::mattype>(::mattype matrix);
3131
template void print_matrix< ::cxtype>(::cxtype matrix);
3232

33-
vec3 gridpp::optimal_interpolation_ensi_multi(const gridpp::Grid& bgrid,
33+
// ensemble member by ensemble member (ebe)
34+
vec3 gridpp::optimal_interpolation_ensi_multi_ebe(const gridpp::Grid& bgrid,
3435
const vec2& bratios,
3536
const vec3& background,
3637
const vec3& background_corr,
3738
const gridpp::Points& points,
3839
const vec2& pobs,
39-
const vec& pratios,
40+
const vec& pratios,
4041
const vec2& pbackground,
4142
const vec2& pbackground_corr,
4243
const gridpp::StructureFunction& structure,
4344
int max_points,
44-
bool dynamic_correlations,
4545
bool allow_extrapolation) {
4646
double s_time = gridpp::clock();
4747

@@ -69,12 +69,12 @@ vec3 gridpp::optimal_interpolation_ensi_multi(const gridpp::Grid& bgrid,
6969
int nE = background[0][0].size();
7070
if(background.size() != nY || background[0].size() != nX) {
7171
std::stringstream ss;
72-
ss << "Input left field (" << background.size() << "," << background[0].size() << "," << background[0][0].size() << ") is not the same size as the grid (" << nY << "," << nX << "," << nE << ")";
72+
ss << "Input background field (" << background.size() << "," << background[0].size() << "," << background[0][0].size() << ") is not the same size as the grid (" << nY << "," << nX << "," << nE << ")";
7373
throw std::invalid_argument(ss.str());
7474
}
7575
if(background_corr.size() != nY || background_corr[0].size() != nX || background_corr[0][0].size() != nE) {
7676
std::stringstream ss;
77-
ss << "Input LEFT field (" << background_corr.size() << "," << background_corr[0].size() << "," << background_corr[0][0].size() << ") is not the same size as the grid (" << nY << "," << nX << "," << nE << ")";
77+
ss << "Input background_corr field (" << background_corr.size() << "," << background_corr[0].size() << "," << background_corr[0][0].size() << ") is not the same size as the grid (" << nY << "," << nX << "," << nE << ")";
7878
throw std::invalid_argument(ss.str());
7979
}
8080
if(bratios.size() != nY || bratios[0].size() != nX) {
@@ -84,12 +84,12 @@ vec3 gridpp::optimal_interpolation_ensi_multi(const gridpp::Grid& bgrid,
8484
}
8585
if(pbackground.size() != nS || pbackground[0].size() != nE) {
8686
std::stringstream ss;
87-
ss << "Input right field at observation location (" << pbackground.size() << "," << pbackground[0].size() << ") and points (" << nS << "," << nE << ") size mismatch";
87+
ss << "Input pbackground field at observation location (" << pbackground.size() << "," << pbackground[0].size() << ") and points (" << nS << "," << nE << ") size mismatch";
8888
throw std::invalid_argument(ss.str());
8989
}
9090
if(pbackground_corr.size() != nS || pbackground_corr[0].size() != nE) {
9191
std::stringstream ss;
92-
ss << "Input RIGHT field at observation location (" << pbackground_corr.size() << "," << pbackground_corr[0].size() << ") and points (" << nS << "," << nE << ") size mismatch";
92+
ss << "Input pbackground_corr field at observation location (" << pbackground_corr.size() << "," << pbackground_corr[0].size() << ") and points (" << nS << "," << nE << ") size mismatch";
9393
throw std::invalid_argument(ss.str());
9494
}
9595
if(pobs.size() != nS || pobs[0].size() != nE) {
@@ -119,12 +119,96 @@ vec3 gridpp::optimal_interpolation_ensi_multi(const gridpp::Grid& bgrid,
119119
}
120120
}
121121
vec2 output1 = gridpp::init_vec2(nY * nX, nE);
122-
if(dynamic_correlations) {
123-
output1 = optimal_interpolation_ensi_multi_ebe(bpoints, bratios1, background1, background_corr1, points, pobs, pratios, pbackground, pbackground_corr, structure, max_points, allow_extrapolation);
122+
output1 = optimal_interpolation_ensi_multi_ebe(bpoints, bratios1, background1, background_corr1, points, pobs, pratios, pbackground, pbackground_corr, structure, max_points, allow_extrapolation);
123+
vec3 output = gridpp::init_vec3(nY, nX, nE);
124+
count = 0;
125+
for(int y = 0; y < nY; y++) {
126+
for(int x = 0; x < nX; x++) {
127+
for(int e = 0; e < nE; e++) {
128+
output[y][x][e] = output1[count][e];
129+
}
130+
count++;
131+
}
124132
}
125-
else {
126-
output1 = optimal_interpolation_ensi_multi_ebesc(bpoints, bratios1, background1, points, pobs, pratios, pbackground, structure, max_points, allow_extrapolation);
133+
return output;
134+
} // end optimal_interpolation_ensi_multi_ebe
135+
136+
// ensemble member by ensemble member with static correlations (ebesc)
137+
vec3 gridpp::optimal_interpolation_ensi_multi_ebesc(const gridpp::Grid& bgrid,
138+
const vec2& bratios,
139+
const vec3& background,
140+
const gridpp::Points& points,
141+
const vec2& pobs,
142+
const vec& pratios,
143+
const vec2& pbackground,
144+
const gridpp::StructureFunction& structure,
145+
int max_points,
146+
bool allow_extrapolation) {
147+
double s_time = gridpp::clock();
148+
149+
// Check input data
150+
if(max_points < 0)
151+
throw std::invalid_argument("max_points must be >= 0");
152+
153+
int nS = points.size();
154+
if(nS == 0)
155+
return background;
156+
157+
int nY = bgrid.size()[0];
158+
int nX = bgrid.size()[1];
159+
160+
if(nY == 0 || nX == 0) {
161+
std::stringstream ss;
162+
ss << "Grid size (" << nY << "," << nX << ") cannot be zero";
163+
throw std::invalid_argument(ss.str());
127164
}
165+
166+
if(bgrid.get_coordinate_type() != points.get_coordinate_type()) {
167+
throw std::invalid_argument("Both background grid and observations points must be of same coordinate type (lat/lon or x/y)");
168+
}
169+
// Check ensembles have consistent sizes
170+
int nE = background[0][0].size();
171+
if(background.size() != nY || background[0].size() != nX) {
172+
std::stringstream ss;
173+
ss << "Input background field (" << background.size() << "," << background[0].size() << "," << background[0][0].size() << ") is not the same size as the grid (" << nY << "," << nX << "," << nE << ")";
174+
throw std::invalid_argument(ss.str());
175+
}
176+
if(bratios.size() != nY || bratios[0].size() != nX) {
177+
std::stringstream ss;
178+
ss << "Input bratios field (" << bratios.size() << "," << bratios[0].size() << ") is not the same size as the grid (" << nY << "," << nX << ")";
179+
throw std::invalid_argument(ss.str());
180+
}
181+
if(pbackground.size() != nS || pbackground[0].size() != nE) {
182+
std::stringstream ss;
183+
ss << "Input pbackground field at observation location (" << pbackground.size() << "," << pbackground[0].size() << ") and points (" << nS << "," << nE << ") size mismatch";
184+
throw std::invalid_argument(ss.str());
185+
}
186+
if(pobs.size() != nS || pobs[0].size() != nE) {
187+
std::stringstream ss;
188+
ss << "Observations (" << pobs.size() << "," << pobs[0].size() << ") and points (" << nS << "," << nE << ") size mismatch";
189+
throw std::invalid_argument(ss.str());
190+
}
191+
if(pratios.size() != nS) {
192+
std::stringstream ss;
193+
ss << "Ratios (" << pratios.size() << ") and points (" << nS << ") size mismatch";
194+
throw std::invalid_argument(ss.str());
195+
}
196+
197+
gridpp::Points bpoints = bgrid.to_points();
198+
vec2 background1 = gridpp::init_vec2(nY * nX, nE);
199+
vec bratios1(nY * nX);
200+
int count = 0;
201+
for(int y = 0; y < nY; y++) {
202+
for(int x = 0; x < nX; x++) {
203+
bratios1[count] = bratios[y][x];
204+
for(int e = 0; e < nE; e++) {
205+
background1[count][e] = background[y][x][e];
206+
}
207+
count++;
208+
}
209+
}
210+
vec2 output1 = gridpp::init_vec2(nY * nX, nE);
211+
output1 = optimal_interpolation_ensi_multi_ebesc(bpoints, bratios1, background1, points, pobs, pratios, pbackground, structure, max_points, allow_extrapolation);
128212
vec3 output = gridpp::init_vec3(nY, nX, nE);
129213
count = 0;
130214
for(int y = 0; y < nY; y++) {
@@ -136,7 +220,110 @@ vec3 gridpp::optimal_interpolation_ensi_multi(const gridpp::Grid& bgrid,
136220
}
137221
}
138222
return output;
139-
}
223+
} // end optimal_interpolation_ensi_multi_ebesc
224+
225+
// use the ensemble mean (utem)
226+
vec3 gridpp::optimal_interpolation_ensi_multi_utem(const gridpp::Grid& bgrid,
227+
const vec2& bratios,
228+
const vec3& background,
229+
const vec3& background_corr,
230+
const gridpp::Points& points,
231+
const vec& pobs,
232+
const vec& pratios,
233+
const vec2& pbackground,
234+
const vec2& pbackground_corr,
235+
const gridpp::StructureFunction& structure,
236+
int max_points,
237+
bool allow_extrapolation) {
238+
double s_time = gridpp::clock();
239+
240+
// Check input data
241+
if(max_points < 0)
242+
throw std::invalid_argument("max_points must be >= 0");
243+
244+
int nS = points.size();
245+
if(nS == 0)
246+
return background;
247+
248+
int nY = bgrid.size()[0];
249+
int nX = bgrid.size()[1];
250+
251+
if(nY == 0 || nX == 0) {
252+
std::stringstream ss;
253+
ss << "Grid size (" << nY << "," << nX << ") cannot be zero";
254+
throw std::invalid_argument(ss.str());
255+
}
256+
257+
if(bgrid.get_coordinate_type() != points.get_coordinate_type()) {
258+
throw std::invalid_argument("Both background grid and observations points must be of same coordinate type (lat/lon or x/y)");
259+
}
260+
// Check ensembles have consistent sizes
261+
int nE = background[0][0].size();
262+
if(background.size() != nY || background[0].size() != nX) {
263+
std::stringstream ss;
264+
ss << "Input background field (" << background.size() << "," << background[0].size() << "," << background[0][0].size() << ") is not the same size as the grid (" << nY << "," << nX << "," << nE << ")";
265+
throw std::invalid_argument(ss.str());
266+
}
267+
if(background_corr.size() != nY || background_corr[0].size() != nX || background_corr[0][0].size() != nE) {
268+
std::stringstream ss;
269+
ss << "Input background_corr field (" << background_corr.size() << "," << background_corr[0].size() << "," << background_corr[0][0].size() << ") is not the same size as the grid (" << nY << "," << nX << "," << nE << ")";
270+
throw std::invalid_argument(ss.str());
271+
}
272+
if(bratios.size() != nY || bratios[0].size() != nX) {
273+
std::stringstream ss;
274+
ss << "Input bratios field (" << bratios.size() << "," << bratios[0].size() << ") is not the same size as the grid (" << nY << "," << nX << ")";
275+
throw std::invalid_argument(ss.str());
276+
}
277+
if(pbackground.size() != nS || pbackground[0].size() != nE) {
278+
std::stringstream ss;
279+
ss << "Input pbackground field at observation location (" << pbackground.size() << "," << pbackground[0].size() << ") and points (" << nS << "," << nE << ") size mismatch";
280+
throw std::invalid_argument(ss.str());
281+
}
282+
if(pbackground_corr.size() != nS || pbackground_corr[0].size() != nE) {
283+
std::stringstream ss;
284+
ss << "Input pbackground_corr field at observation location (" << pbackground_corr.size() << "," << pbackground_corr[0].size() << ") and points (" << nS << "," << nE << ") size mismatch";
285+
throw std::invalid_argument(ss.str());
286+
}
287+
if(pobs.size() != nS) {
288+
std::stringstream ss;
289+
ss << "Observations (" << pobs.size() << ") and points (" << nS << ") size mismatch";
290+
throw std::invalid_argument(ss.str());
291+
}
292+
if(pratios.size() != nS) {
293+
std::stringstream ss;
294+
ss << "Ratios (" << pratios.size() << ") and points (" << nS << ") size mismatch";
295+
throw std::invalid_argument(ss.str());
296+
}
297+
298+
gridpp::Points bpoints = bgrid.to_points();
299+
vec2 background1 = gridpp::init_vec2(nY * nX, nE);
300+
vec2 background_corr1 = gridpp::init_vec2(nY * nX, nE);
301+
vec bratios1(nY * nX);
302+
int count = 0;
303+
for(int y = 0; y < nY; y++) {
304+
for(int x = 0; x < nX; x++) {
305+
bratios1[count] = bratios[y][x];
306+
for(int e = 0; e < nE; e++) {
307+
background1[count][e] = background[y][x][e];
308+
background_corr1[count][e] = background_corr[y][x][e];
309+
}
310+
count++;
311+
}
312+
}
313+
vec2 output1 = gridpp::init_vec2(nY * nX, nE);
314+
output1 = optimal_interpolation_ensi_multi_utem(bpoints, bratios1, background1, background_corr1, points, pobs, pratios, pbackground, pbackground_corr, structure, max_points, allow_extrapolation);
315+
vec3 output = gridpp::init_vec3(nY, nX, nE);
316+
count = 0;
317+
for(int y = 0; y < nY; y++) {
318+
for(int x = 0; x < nX; x++) {
319+
for(int e = 0; e < nE; e++) {
320+
output[y][x][e] = output1[count][e];
321+
}
322+
count++;
323+
}
324+
}
325+
return output;
326+
} // end optimal_interpolation_ensi_multi_utem
140327

141328
// ensemble member by ensemble member (ebe)
142329
vec2 gridpp::optimal_interpolation_ensi_multi_ebe(const gridpp::Points& bpoints,

0 commit comments

Comments
 (0)