8 #ifndef TEST_INTERFACE_LINEAROBSOPERATOR_H_
9 #define TEST_INTERFACE_LINEAROBSOPERATOR_H_
15 #define ECKIT_TESTING_SELF_REGISTER_CASES 0
18 #include "eckit/testing/Test.h"
27 #include "oops/util/dot_product.h"
28 #include "oops/util/Logger.h"
37 typedef ObsTestsFixture<OBS> Test_;
40 std::vector<eckit::LocalConfiguration> conf;
43 for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
45 std::string confname =
"obs operator";
46 if (conf[jj].
has(
"linear obs operator")) confname =
"linear obs operator";
47 eckit::LocalConfiguration linobsopconf(conf[jj], confname);
48 std::unique_ptr<LinearObsOperator_> ov(
49 new LinearObsOperator_(Test_::obspace()[jj], linobsopconf));
69 const double zero = 0.0;
70 const double coef = 3.14;
71 const double tol = 1.0e-11;
72 std::vector<eckit::LocalConfiguration> conf;
75 for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
78 eckit::LocalConfiguration obsopconf(conf[jj],
"obs operator");
79 ObsOperator_ hop(Test_::obspace()[jj], obsopconf);
83 std::string confname =
"obs operator";
84 if (conf[jj].
has(
"linear obs operator")) confname =
"linear obs operator";
85 eckit::LocalConfiguration linobsopconf(conf[jj], confname);
86 LinearObsOperator_ hoptl(Test_::obspace()[jj], linobsopconf);
89 const ObsAuxCtrl_ ybias(Test_::obspace()[jj], conf[jj]);
90 ObsAuxIncr_ ybinc(Test_::obspace()[jj], conf[jj]);
93 const eckit::LocalConfiguration gconf(conf[jj],
"geovals");
95 hopvars += ybias.requiredVars();
96 const GeoVaLs_ gval(gconf, Test_::obspace()[jj], hopvars);
99 const ObsAuxCov_ Bobsbias(Test_::obspace()[jj], conf[jj]);
102 hoptl.setTrajectory(gval, ybias);
105 ObsVector_ dy1(Test_::obspace()[jj]);
108 GeoVaLs_ dx(gconf, Test_::obspace()[jj], hoptl.requiredVars());
113 hoptl.simulateObsTL(dx, dy1, ybinc);
114 EXPECT(dy1.rms() == zero);
118 Bobsbias.randomize(ybinc);
119 hoptl.simulateObsTL(dx, dy1, ybinc);
120 EXPECT(dy1.rms() > zero);
126 ObsVector_ dy2(Test_::obspace()[jj]);
127 hoptl.simulateObsTL(dx, dy2, ybinc);
130 EXPECT(dy2.rms() / dy1.rms() < tol);
146 const double zero = 0.0;
147 std::vector<eckit::LocalConfiguration> conf;
150 for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
153 eckit::LocalConfiguration obsopconf(conf[jj],
"obs operator");
154 ObsOperator_ hop(Test_::obspace()[jj], obsopconf);
158 std::string confname =
"obs operator";
159 if (conf[jj].
has(
"linear obs operator")) confname =
"linear obs operator";
160 eckit::LocalConfiguration linobsopconf(conf[jj], confname);
161 LinearObsOperator_ hoptl(Test_::obspace()[jj], linobsopconf);
163 const double tol = conf[jj].getDouble(
"linear obs operator test.tolerance AD");
165 const ObsAuxCtrl_ ybias(Test_::obspace()[jj], conf[jj]);
166 ObsAuxIncr_ ybinc1(Test_::obspace()[jj], conf[jj]);
167 ObsAuxIncr_ ybinc2(Test_::obspace()[jj], conf[jj]);
170 const ObsAuxCov_ Bobsbias(Test_::obspace()[jj], conf[jj]);
173 eckit::LocalConfiguration gconf(conf[jj],
"geovals");
175 hopvars += ybias.requiredVars();
176 const GeoVaLs_ gval(gconf, Test_::obspace()[jj], hopvars);
179 hoptl.setTrajectory(gval, ybias);
181 ObsVector_ dy1(Test_::obspace()[jj]);
182 ObsVector_ dy2(Test_::obspace()[jj]);
183 GeoVaLs_ dx1(gconf, Test_::obspace()[jj], hoptl.requiredVars());
184 GeoVaLs_ dx2(gconf, Test_::obspace()[jj], hoptl.requiredVars());
188 EXPECT(dot_product(dx1, dx1) > zero);
189 Bobsbias.randomize(ybinc1);
190 hoptl.simulateObsTL(dx1, dy1, ybinc1);
191 EXPECT(dot_product(dy1, dy1) > zero);
195 EXPECT(dot_product(dy2, dy2) > zero);
198 hoptl.simulateObsAD(dx2, dy2, ybinc2);
199 EXPECT(dot_product(dx2, dx2) > zero);
201 const double zz1 = dot_product(dx1, dx2) + dot_product(ybinc1, ybinc2);
202 const double zz2 = dot_product(dy1, dy2);
204 oops::Log::info() <<
"Adjoint test result: (<x,HTy>-<Hx,y>)/<Hx,y> = "
205 << (zz1-zz2)/zz2 << std::endl;
209 EXPECT(oops::is_close(zz1, zz2, tol));
227 std::vector<eckit::LocalConfiguration> conf;
230 for (std::size_t jj = 0; jj < Test_::obspace().size(); ++jj) {
233 eckit::LocalConfiguration obsopconf(conf[jj],
"obs operator");
234 ObsOperator_ hop(Test_::obspace()[jj], obsopconf);
238 std::string confname =
"obs operator";
239 if (conf[jj].
has(
"linear obs operator")) confname =
"linear obs operator";
240 eckit::LocalConfiguration linobsopconf(conf[jj], confname);
241 LinearObsOperator_ hoptl(Test_::obspace()[jj], linobsopconf);
243 const double tol = conf[jj].getDouble(
"linear obs operator test.tolerance TL");
244 const double alpha = conf[jj].getDouble(
"linear obs operator test.coef TL", 0.1);
245 const int iter = conf[jj].getInt(
"linear obs operator test.iterations TL", 1);
248 const ObsAuxCtrl_ ybias0(Test_::obspace()[jj], conf[jj]);
249 ObsAuxCtrl_ ybias(Test_::obspace()[jj], conf[jj]);
252 const ObsAuxCov_ Bobsbias(Test_::obspace()[jj], conf[jj]);
255 const eckit::LocalConfiguration gconf(conf[jj],
"geovals");
257 hopvars += ybias0.requiredVars();
258 const GeoVaLs_ x0(gconf, Test_::obspace()[jj], hopvars);
259 GeoVaLs_ x(gconf, Test_::obspace()[jj], hopvars);
262 hoptl.setTrajectory(x0, ybias0);
265 ObsVector_ y1(Test_::obspace()[jj]);
266 ObsVector_ y2(Test_::obspace()[jj]);
267 ObsVector_ y3(Test_::obspace()[jj]);
271 diagvars += ybias0.requiredHdiagnostics();
272 ObsDiags_ ydiag(Test_::obspace()[jj],
273 hop.locations(Test_::obspace()[jj].windowStart(),
274 Test_::obspace()[jj].windowEnd()),
278 hop.simulateObs(x0, y1, ybias0, ydiag);
281 GeoVaLs_ dx(gconf, Test_::obspace()[jj], hoptl.requiredVars());
283 ObsAuxIncr_ ybinc(Test_::obspace()[jj], conf[jj]);
284 Bobsbias.randomize(ybinc);
289 for (
int jter = 0; jter < iter; ++jter) {
300 hop.simulateObs(x, y2, ybias, ydiag);
303 hoptl.simulateObsTL(dx, y3, ybinc);
306 double test_norm = y2.rms();
307 oops::Log::info() <<
"Iter:" << jter <<
" ||(h(x+alpha*dx)-h(x)-h'*(alpha*dx))||="
308 << test_norm << std::endl;
310 EXPECT(y2.rms() < tol);
316 template <
typename OBS>
323 std::string
testid()
const override {
return "test::LinearObsOperator<" + OBS::name() +
">";}
326 std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
328 ts.emplace_back(
CASE(
"interface/GeometryIterator/testConstructor")
329 { testConstructor<OBS>(); });
330 ts.emplace_back(
CASE(
"interface/GeometryIterator/testLinearity")
331 { testLinearity<OBS>(); });
332 ts.emplace_back(
CASE(
"interface/GeometryIterator/testTangentLinear")
333 { testTangentLinear<OBS>(); });
334 ts.emplace_back(
CASE(
"interface/GeometryIterator/testAdjoint")
335 { testAdjoint<OBS>(); });
347 #endif // TEST_INTERFACE_LINEAROBSOPERATOR_H_