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