1 // @HEADER
2 // ************************************************************************
3 //
4 // Rapid Optimization Library (ROL) Package
5 // Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions: Alejandro Mota (amota@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41
42 #include <gtest/gtest.h>
43 #include <MiniTensor_FunctionSet.h>
44 #include "ROL_MiniTensor_BoundConstraint.hpp"
45 #include "ROL_MiniTensor_EqualityConstraint.hpp"
46 #include "ROL_MiniTensor_Function.hpp"
47
48 using Real = double;
49
50 int
main(int ac,char * av[])51 main(int ac, char * av[])
52 {
53 Kokkos::initialize();
54
55 ::testing::GTEST_FLAG(print_time) = (ac > 1) ? true : false;
56
57 ::testing::InitGoogleTest(&ac, av);
58
59 auto const
60 retval = RUN_ALL_TESTS();
61
62 Kokkos::finalize();
63
64 return retval;
65 }
66
TEST(MiniTensor_ROL,MT_Basics)67 TEST(MiniTensor_ROL, MT_Basics)
68 {
69 bool const
70 print_output = ::testing::GTEST_FLAG(print_time);
71
72 // outputs nothing
73 ROL::nullstream
74 bhs;
75
76 std::ostream &
77 os = (print_output == true) ? std::cout : bhs;
78
79 constexpr minitensor::Index
80 DIM{2};
81
82 minitensor::Paraboloid<Real>
83 p;
84
85 minitensor::Vector<Real, DIM> const
86 x(0.0, 0.0);
87
88 Real const
89 f = p.value(x);
90
91 minitensor::Vector<Real, DIM> const
92 df = p.gradient(x);
93
94 minitensor::Tensor<Real, DIM> const
95 ddf = p.hessian(x);
96
97 os << "Point : " << x << '\n';
98 os << "Value : " << f << '\n';
99 os << "Gradient: " << df << '\n';
100 os << "Hessian : " << ddf << '\n';
101
102 minitensor::Tensor<Real, DIM> const
103 I = minitensor::identity<Real, DIM>(DIM);
104
105 Real const
106 error = std::sqrt(f) + minitensor::norm(df) + minitensor::norm(ddf - 2.0 * I);
107
108 ASSERT_LE(error, minitensor::machine_epsilon<Real>());
109 }
110
TEST(MiniTensor_ROL,Objective)111 TEST(MiniTensor_ROL, Objective)
112 {
113 bool const
114 print_output = ::testing::GTEST_FLAG(print_time);
115
116 // outputs nothing
117 ROL::nullstream
118 bhs;
119
120 std::ostream &
121 os = (print_output == true) ? std::cout : bhs;
122
123 constexpr minitensor::Index
124 DIM{2};
125
126 using MSFN = minitensor::Paraboloid<Real, DIM>;
127
128 MSFN
129 msfn(0.0, 0.0);
130
131 ROL::MiniTensor_Objective<MSFN, Real, DIM>
132 obj(msfn);
133
134 minitensor::Vector<Real, DIM>
135 xval(minitensor::Filler::RANDOM);
136
137 os << "xval:" << xval << '\n';
138
139 minitensor::Vector<Real, DIM>
140 dval(minitensor::Filler::RANDOM);
141
142 os << "dval:" << dval << '\n';
143
144 minitensor::Vector<Real, DIM>
145 vval(minitensor::Filler::RANDOM);
146
147 os << "vval:" << vval << '\n';
148
149 ROL::MiniTensorVector<Real, DIM>
150 x(xval);
151
152 ROL::MiniTensorVector<Real, DIM>
153 d(dval);
154
155 ROL::MiniTensorVector<Real, DIM>
156 v(dval);
157
158 std::vector<std::vector<Real>>
159 grad_check = obj.checkGradient(x, d, print_output, os);
160
161 std::vector<std::vector<Real>>
162 hess_check = obj.checkHessVec(x, v, print_output, os);
163
164 std::vector<Real>
165 symm_check = obj.checkHessSym(x, d, v, print_output, os);
166
167 Real
168 error1{1.0};
169
170 Real
171 error2{1.0};
172
173 Real const
174 error3 = symm_check[3];
175
176 for (minitensor::Index i = 0; i < grad_check.size(); ++i) {
177 error1 = std::min(error1, grad_check[i][3]);
178 error2 = std::min(error2, hess_check[i][3]);
179 }
180
181 Real const
182 epsilon{minitensor::machine_epsilon<Real>()};
183
184 Real const
185 tol{std::sqrt(epsilon)};
186
187 ASSERT_LE(error1, tol);
188 ASSERT_LE(error2, epsilon);
189 ASSERT_LE(error3, epsilon);
190 }
191
TEST(MiniTensor_ROL,EqualityConstraintId)192 TEST(MiniTensor_ROL, EqualityConstraintId)
193 {
194 bool const
195 print_output = ::testing::GTEST_FLAG(print_time);
196
197 // outputs nothing
198 ROL::nullstream
199 bhs;
200
201 std::ostream &
202 os = (print_output == true) ? std::cout : bhs;
203
204 constexpr minitensor::Index
205 NUM_CONSTR{2};
206
207 constexpr minitensor::Index
208 NUM_VAR{2};
209
210 using MSEC = minitensor::Identity<Real, NUM_CONSTR, NUM_VAR>;
211
212 MSEC
213 msec;
214
215 ROL::MiniTensor_EqualityConstraint<MSEC, Real, NUM_CONSTR, NUM_VAR>
216 constr(msec);
217
218 minitensor::Vector<Real, NUM_VAR>
219 xval(minitensor::Filler::RANDOM);
220
221 os << "xval:" << xval << '\n';
222
223 minitensor::Vector<Real, NUM_VAR>
224 vval(minitensor::Filler::RANDOM);
225
226 os << "vval:" << vval << '\n';
227
228 minitensor::Vector<Real, NUM_CONSTR>
229 jvval(minitensor::Filler::RANDOM);
230
231 os << "jvval:" << jvval << '\n';
232
233 minitensor::Vector<Real, NUM_VAR>
234 ajvval(minitensor::Filler::RANDOM);
235
236 os << "ajvval:" << ajvval << '\n';
237
238 ROL::MiniTensorVector<Real, NUM_VAR>
239 x(xval);
240
241 ROL::MiniTensorVector<Real, NUM_VAR>
242 v(vval);
243
244 ROL::MiniTensorVector<Real, NUM_CONSTR>
245 jv(jvval);
246
247 ROL::MiniTensorVector<Real, NUM_VAR>
248 ajv(ajvval);
249
250 std::vector<std::vector<Real>>
251 jac_check = constr.checkApplyJacobian(x, v, jv, print_output, os);
252
253 std::vector<std::vector<Real>>
254 ajac_check = constr.checkApplyAdjointJacobian(x, jv, jv, ajv, print_output, os);
255
256 Real
257 error1{1.0};
258
259 Real
260 error2{1.0};
261
262 for (minitensor::Index i = 0; i < jac_check.size(); ++i) {
263 error1 = std::min(error1, jac_check[i][3]);
264 error2 = std::min(error2, jac_check[i][3]);
265 }
266
267 Real const
268 tol{1.0e-07};
269
270 ASSERT_LE(error1, tol);
271 ASSERT_LE(error2, tol);
272 }
273
TEST(MiniTensor_ROL,EqualityConstraint01)274 TEST(MiniTensor_ROL, EqualityConstraint01)
275 {
276 bool const
277 print_output = ::testing::GTEST_FLAG(print_time);
278
279 // outputs nothing
280 ROL::nullstream
281 bhs;
282
283 std::ostream &
284 os = (print_output == true) ? std::cout : bhs;
285
286 constexpr minitensor::Index
287 NUM_CONSTR{3};
288
289 constexpr minitensor::Index
290 NUM_VAR{5};
291
292 using MSEC = minitensor::Nonlinear01<Real, NUM_CONSTR, NUM_VAR>;
293
294 MSEC
295 msec;
296
297 ROL::MiniTensor_EqualityConstraint<MSEC, Real, NUM_CONSTR, NUM_VAR>
298 constr(msec);
299
300 minitensor::Vector<Real, NUM_VAR>
301 xval(minitensor::Filler::RANDOM);
302
303 os << "xval:" << xval << '\n';
304
305 minitensor::Vector<Real, NUM_VAR>
306 vval(minitensor::Filler::RANDOM);
307
308 os << "vval:" << vval << '\n';
309
310 minitensor::Vector<Real, NUM_CONSTR>
311 jvval(minitensor::Filler::RANDOM);
312
313 os << "jvval:" << jvval << '\n';
314
315 minitensor::Vector<Real, NUM_VAR>
316 ajvval(minitensor::Filler::RANDOM);
317
318 os << "ajvval:" << ajvval << '\n';
319
320 ROL::MiniTensorVector<Real, NUM_VAR>
321 x(xval);
322
323 ROL::MiniTensorVector<Real, NUM_VAR>
324 v(vval);
325
326 ROL::MiniTensorVector<Real, NUM_CONSTR>
327 jv(jvval);
328
329 ROL::MiniTensorVector<Real, NUM_VAR>
330 ajv(ajvval);
331
332 std::vector<std::vector<Real>>
333 jac_check = constr.checkApplyJacobian(x, v, jv, print_output, os);
334
335 std::vector<std::vector<Real>>
336 ajac_check = constr.checkApplyAdjointJacobian(x, jv, jv, ajv, print_output, os);
337
338 Real
339 error1{1.0};
340
341 Real
342 error2{1.0};
343
344 for (minitensor::Index i = 0; i < jac_check.size(); ++i) {
345 error1 = std::min(error1, jac_check[i][3]);
346 error2 = std::min(error2, ajac_check[i][3]);
347 }
348
349 Real const
350 tol{1.0e-07};
351
352 ASSERT_LE(error1, tol);
353 ASSERT_LE(error2, tol);
354 }
355
TEST(MiniTensor_ROL,BoundConstraint)356 TEST(MiniTensor_ROL, BoundConstraint)
357 {
358 bool const
359 print_output = ::testing::GTEST_FLAG(print_time);
360
361 // outputs nothing
362 ROL::nullstream
363 bhs;
364
365 std::ostream &
366 os = (print_output == true) ? std::cout : bhs;
367
368 constexpr minitensor::Index
369 DIM{16};
370
371 minitensor::Vector<Real, DIM>
372 lo_mt(minitensor::Filler::ONES);
373
374 lo_mt *= -0.5;
375
376 os << "Lower bound:" << lo_mt << '\n';
377
378 minitensor::Vector<Real, DIM>
379 hi_mt(minitensor::Filler::ONES);
380
381 hi_mt *= 0.5;
382
383 os << "Upper bound:" << hi_mt << '\n';
384
385 minitensor::Vector<Real, DIM>
386 x_mt(minitensor::Filler::RANDOM);
387
388 os << "Initial x :" << x_mt << '\n';
389
390 ROL::MiniTensorVector<Real, DIM>
391 lo_rol(lo_mt);
392
393 ROL::MiniTensorVector<Real, DIM>
394 hi_rol(hi_mt);
395
396 ROL::MiniTensorVector<Real, DIM>
397 x_rol(x_mt);
398
399 ROL::MiniTensor_BoundConstraint<Real, DIM>
400 rol_bounds(lo_rol, hi_rol);
401
402 rol_bounds.project(x_rol);
403
404 x_mt = ROL::MTfromROL<Real, DIM>(x_rol);
405
406 os << "Pruned x :" << x_mt << '\n';
407
408 bool const
409 is_feasible = rol_bounds.isFeasible(x_rol);
410
411 ASSERT_EQ(is_feasible, true);
412 }
413