1 /*  _________________________________________________________________________
2  *
3  *  Acro: A Common Repository for Optimizers
4  *  Copyright (c) 2008 Sandia Corporation.
5  *  This software is distributed under the BSD License.
6  *  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
7  *  the U.S. Government retains certain rights in this software.
8  *  For more information, see the README.txt file in the top Acro directory.
9  *  _________________________________________________________________________
10  */
11 
12 #include <acro_config.h>
13 
14 #include <cxxtest/TestSuite.h>
15 
16 #include <colin/ApplicationMngr.h>
17 #include <colin/XMLProcessor.h>
18 #include <boost/bimap.hpp>
19 
20 #include "CommonTestUtils.h"
21 #include "TestApplications.h"
22 
23 namespace colin {
24 namespace unittest { class Application_RealDomain; }
25 
26 class colin::unittest::Application_RealDomain : public CxxTest::TestSuite
27 {
28 public:
29    typedef boost::bimap<size_t, std::string>  labels_t;
30 
31    // The test application
32    TestApplications::singleObj_denseCon<NLP0_problem> *app;
33 
setUp()34    void setUp()
35    {
36       utilib::exception_mngr::set_mode(utilib::exception_mngr::Standard);
37       app = new TestApplications::singleObj_denseCon<NLP0_problem>(3);
38 
39       labels_t labels;
40       app->real_labels = labels;
41 
42       BoundTypeArray bta(3);
43       app->real_lower_bound_types = bta;
44       app->real_upper_bound_types = bta;
45       app->enforcing_domain_bounds = false;
46 
47       app->num_linear_constraints = 0;
48       app->num_nonlinear_constraints = 0;
49    }
50 
tearDown()51    void tearDown()
52    {
53       delete app;
54    }
55 
test_num_real_vars()56    void test_num_real_vars()
57    {
58       TS_TRACE("--------------------------------------------------------");
59       TS_TRACE(" num_real_vars - Verify that we have the appropriate");
60       TS_TRACE("    number of real variables.");
61       TS_TRACE("--------------------------------------------------------");
62       TS_ASSERT_EQUALS( app->num_real_vars, 3);
63    }
64 
test_bounds_feasibility1()65    void test_bounds_feasibility1()
66    {
67       TS_TRACE("--------------------------------------------------------");
68       TS_TRACE(" bounds_feasibility1 - Verify that simple bounds checks work");
69       TS_TRACE("--------------------------------------------------------");
70 
71       utilib::BasicArray<double> point(3);
72       point << 0.0;
73       TS_ASSERT_EQUALS(app->testBoundsFeasibility(point),true);
74 
75       utilib::BasicArray<double> lower(3);
76       lower << -1.0;
77       utilib::BasicArray<double> upper(3);
78       upper << 1.0;
79       app->real_lower_bounds = lower;
80       app->real_upper_bounds = upper;
81       TS_ASSERT_EQUALS(app->testBoundsFeasibility(point),true);
82 
83       lower[1] = 1.0;
84       app->real_lower_bounds = lower;
85       TS_ASSERT_EQUALS(app->testBoundsFeasibility(point),false);
86 
87       lower[1] = -1.0;
88       upper[1] = -1.0;
89       app->real_lower_bounds = lower;
90       app->real_upper_bounds = upper;
91       TS_ASSERT_EQUALS(app->testBoundsFeasibility(point),false);
92 
93       app->setRealUpperBoundType(1, colin::soft_bound);
94       TS_ASSERT_EQUALS(app->testBoundsFeasibility(point),true);
95     }
96 
test_bounds1()97    void test_bounds1()
98    {
99       TS_TRACE("--------------------------------------------------------");
100       TS_TRACE(" bounds1 - Verify that setting and gettings bounds works");
101       TS_TRACE("--------------------------------------------------------");
102 
103       utilib::BasicArray<double> lower(3);
104       lower << -1.0;
105       utilib::BasicArray<double> upper(3);
106       upper << 1.0;
107       app->real_lower_bounds = lower;
108       app->real_upper_bounds = upper;
109 
110       utilib::BasicArray<double> _lower = app->real_lower_bounds;
111       utilib::BasicArray<double> _upper = app->real_upper_bounds;
112       TS_ASSERT_EQUALS(lower,_lower);
113       TS_ASSERT_EQUALS(upper,_upper);
114     }
115 
test_bounds2()116    void test_bounds2()
117    {
118       TS_TRACE("--------------------------------------------------------");
119       TS_TRACE(" bounds2 - Verify finite bounds");
120       TS_TRACE("--------------------------------------------------------");
121 
122       TS_ASSERT_EQUALS( app->finite_bound_constraints(),false);
123       TS_ASSERT_EQUALS( app->enforcing_domain_bounds, false);
124       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), false);
125       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), false);
126 
127       utilib::BasicArray<double> lower(3);
128       lower << -1.0;
129       utilib::BasicArray<double> upper(3);
130       upper << 1.0;
131 
132       app->real_lower_bounds = lower;
133       app->real_upper_bounds = upper;
134       TS_ASSERT_EQUALS( app->finite_bound_constraints(),true);
135       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
136       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), true);
137       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), true);
138       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
139 
140       app->setRealLowerBoundType(0, soft_bound);
141       TS_ASSERT_EQUALS( app->finite_bound_constraints(),true);
142       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
143       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), true);
144       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), true);
145       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
146 
147       app->setRealLowerBoundType(0, no_bound);
148       TS_ASSERT_EQUALS( app->finite_bound_constraints(),false);
149       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
150       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), false);
151       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), true);
152       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
153 
154       TS_ASSERT_THROWS_ASSERT
155          ( app->setRealLowerBoundType(0, hard_bound), std::logic_error e,
156            TEST_WHAT(e, "Application_RealDomain::cb_validate_bound_types(): "
157                      "unsetting no_bound on an infinite bound (index=0).") );
158 
159       app->setRealLowerBoundType(1, soft_bound);
160       TS_ASSERT_EQUALS( app->finite_bound_constraints(),false);
161       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
162       TS_ASSERT_EQUALS( app->hasRealLowerBound(1), true);
163       TS_ASSERT_EQUALS( app->hasRealUpperBound(1), true);
164       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(1), false);
165 
166       app->setRealLowerBoundType(1, no_bound);
167       TS_ASSERT_EQUALS( app->finite_bound_constraints(),false);
168       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
169       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), false);
170       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), true);
171       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
172       TS_ASSERT_EQUALS( app->hasRealLowerBound(1), false);
173       TS_ASSERT_EQUALS( app->hasRealUpperBound(1), true);
174       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(1), false);
175 
176       lower = app->real_lower_bounds;
177       lower[0] = -1;
178       app->real_lower_bounds = lower;
179       TS_ASSERT_EQUALS( app->finite_bound_constraints(),false);
180       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
181       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), true);
182       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), true);
183       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
184 
185       lower[1] = -1;
186       app->real_lower_bounds = lower;
187       TS_ASSERT_EQUALS( app->finite_bound_constraints(),true);
188       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
189       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), true);
190       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), true);
191       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
192 
193       app->setRealUpperBoundType(0, no_bound);
194       TS_ASSERT_EQUALS( app->finite_bound_constraints(),false);
195       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
196       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), true);
197       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), false);
198       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
199 
200       TS_ASSERT_THROWS_ASSERT
201          ( app->setPeriodicRealBound(0), std::logic_error e,
202            TEST_WHAT(e, "Application_RealDomain::cb_validate_bound_types(): "
203                      "unsetting no_bound on an infinite bound (index=0).") );
204 
205       app->real_upper_bounds = upper;
206       app->setPeriodicRealBound(0);
207       TS_ASSERT_EQUALS( app->finite_bound_constraints(),true);
208       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
209       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), true);
210       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), true);
211       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), true);
212 
213       app->enforcing_domain_bounds = false;
214       TS_ASSERT_EQUALS( app->finite_bound_constraints(),false);
215       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,false);
216       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), false);
217       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), false);
218       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
219 
220       app->enforcing_domain_bounds = true;
221 
222       // changing the upper bound should not clear the periodic flag
223       upper[0] = 100;
224       app->real_upper_bounds = upper;
225       TS_ASSERT_EQUALS( app->finite_bound_constraints(),true);
226       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
227       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), true);
228       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), true);
229       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), true);
230 
231       // clearing the upper bound *should* clear the periodic flag
232       upper[0] = MAXDOUBLE;
233       app->real_upper_bounds = upper;
234       TS_ASSERT_EQUALS( app->finite_bound_constraints(),false);
235       TS_ASSERT_EQUALS( app->enforcing_domain_bounds,true);
236       TS_ASSERT_EQUALS( app->hasRealLowerBound(0), true);
237       TS_ASSERT_EQUALS( app->hasRealUpperBound(0), false);
238       TS_ASSERT_EQUALS( app->hasPeriodicRealBound(0), false);
239     }
240 
test_bounds3()241    void test_bounds3()
242    {
243       TS_TRACE("--------------------------------------------------------");
244       TS_TRACE(" bounds3 - Verify bound types");
245       TS_TRACE("--------------------------------------------------------");
246 
247       BoundTypeArray lower_bt = app->real_lower_bound_types;
248       BoundTypeArray upper_bt = app->real_upper_bound_types;
249       TS_ASSERT_EQUALS( lower_bt.size(), 3u);
250       TS_ASSERT_EQUALS( upper_bt.size(), 3u);
251       TS_ASSERT_EQUALS( upper_bt[0], colin::no_bound);
252       TS_ASSERT_EQUALS( app->realLowerBoundType(0), colin::no_bound);
253       TS_ASSERT_EQUALS( app->realUpperBoundType(0), colin::no_bound);
254 
255       utilib::BasicArray<double> lower(3);
256       lower << -1.0;
257       utilib::BasicArray<double> upper(3);
258       upper << 1.0;
259       app->real_lower_bounds = lower;
260       app->real_upper_bounds = upper;
261       lower_bt = app->real_lower_bound_types;
262       upper_bt = app->real_upper_bound_types;
263       TS_ASSERT_EQUALS( upper_bt[0], colin::hard_bound);
264       TS_ASSERT_EQUALS( app->realLowerBoundType(0), colin::hard_bound);
265       TS_ASSERT_EQUALS( app->realUpperBoundType(0), colin::hard_bound);
266 
267       lower[1] = -MAXDOUBLE;
268       app->real_lower_bounds = lower;
269       lower_bt = app->real_lower_bound_types;
270       upper_bt = app->real_upper_bound_types;
271       TS_ASSERT_EQUALS( lower_bt[0], colin::hard_bound);
272       TS_ASSERT_EQUALS( lower_bt[1], colin::no_bound);
273       TS_ASSERT_EQUALS( app->realLowerBoundType(1), colin::no_bound);
274       TS_ASSERT_EQUALS( app->realUpperBoundType(0), colin::hard_bound);
275    }
276 
test_bounds4()277    void test_bounds4()
278    {
279       TS_TRACE("--------------------------------------------------------");
280       TS_TRACE(" bounds4 - Verify bound types (some more)");
281       TS_TRACE("--------------------------------------------------------");
282 
283       BoundTypeArray lower_bt = app->real_lower_bound_types;
284       BoundTypeArray upper_bt = app->real_upper_bound_types;
285       TS_ASSERT_EQUALS( lower_bt.size(), 3u);
286       TS_ASSERT_EQUALS( upper_bt.size(), 3u);
287       TS_ASSERT_EQUALS( upper_bt[0], colin::no_bound);
288       TS_ASSERT_EQUALS( app->realLowerBoundType(0), colin::no_bound);
289       TS_ASSERT_EQUALS( app->realUpperBoundType(0), colin::no_bound);
290 
291       utilib::BasicArray<double> lower(3);
292       lower << -1.0;
293       utilib::BasicArray<double> upper(3);
294       upper << 1.0;
295       app->real_lower_bounds = lower;
296       app->real_upper_bounds = upper;
297       lower_bt = app->real_lower_bound_types;
298       upper_bt = app->real_upper_bound_types;
299       TS_ASSERT_EQUALS( upper_bt[0], colin::hard_bound);
300       TS_ASSERT_EQUALS( app->realLowerBoundType(0), colin::hard_bound);
301       TS_ASSERT_EQUALS( app->realUpperBoundType(0), colin::hard_bound);
302 
303       lower_bt[1] = colin::soft_bound;
304       upper_bt[0] = colin::periodic_bound;
305       app->real_lower_bound_types = lower_bt;
306       app->real_upper_bound_types = upper_bt;
307       TS_ASSERT_EQUALS( app->realLowerBoundType(1), colin::soft_bound);
308       TS_ASSERT_EQUALS( app->realUpperBoundType(0), colin::periodic_bound);
309    }
310 
test_bounds5()311    void test_bounds5()
312    {
313       TS_TRACE("--------------------------------------------------------");
314       TS_TRACE(" bounds5 - Verify error checking for bounds methods");
315       TS_TRACE("--------------------------------------------------------");
316 
317       try {
318         app->realLowerBoundType(4);
319         TS_FAIL("Expected runtime error");
320         }
321       catch (std::runtime_error&) {}
322 
323       try {
324         app->realUpperBoundType(4);
325         TS_FAIL("Expected runtime error");
326         }
327       catch (std::runtime_error&) {}
328 
329       try {
330         app->hasRealLowerBound(4);
331         TS_FAIL("Expected runtime error");
332         }
333       catch (std::runtime_error&) {}
334 
335       try {
336         app->hasRealUpperBound(4);
337         TS_FAIL("Expected runtime error");
338         }
339       catch (std::runtime_error&) {}
340 
341       try {
342         app->setRealLowerBoundType(4, colin::no_bound);
343         TS_FAIL("Expected runtime error");
344         }
345       catch (std::runtime_error&) {}
346 
347       try {
348         app->setRealUpperBoundType(4, colin::no_bound);
349         TS_FAIL("Expected runtime error");
350         }
351       catch (std::runtime_error&) {}
352 
353       try {
354         app->hasPeriodicRealBound(4);
355         TS_FAIL("Expected runtime error");
356         }
357       catch (std::runtime_error&) {}
358 
359       try {
360         app->setPeriodicRealBound(4);
361         TS_FAIL("Expected runtime error");
362         }
363       catch (std::runtime_error&) {}
364 
365       utilib::BasicArray<double> lower(3);
366       lower << -1.0;
367       utilib::BasicArray<double> upper(2);
368       upper << -1.0;
369       try {
370          app->real_lower_bounds = lower;
371          app->real_upper_bounds = upper;
372          TS_FAIL("Expected runtime error");
373       }
374       catch (std::runtime_error&) {}
375       lower.resize(2);
376       upper.resize(3);
377       try {
378          app->real_lower_bounds = lower;
379          app->real_upper_bounds = upper;
380          TS_FAIL("Expected runtime error");
381       }
382       catch (std::runtime_error&) {}
383 
384       BoundTypeArray lower_bt(3);
385       BoundTypeArray upper_bt(2);
386       try {
387          app->real_lower_bound_types = lower_bt;
388          app->real_upper_bound_types = upper_bt;
389          TS_FAIL("Expected runtime error");
390       }
391       catch (std::runtime_error&) {}
392       lower_bt.resize(2);
393       upper_bt.resize(3);
394       try {
395          app->real_lower_bound_types = lower_bt;
396          app->real_upper_bound_types = upper_bt;
397          TS_FAIL("Expected runtime error");
398       }
399       catch (std::runtime_error&) {}
400     }
401 
402    /*
403    void xtest_fixed1()
404    {
405       TS_TRACE("--------------------------------------------------------");
406       TS_TRACE(" fixed1 - Verify that map of fixed variables can be");
407       TS_TRACE("    accessed.");
408       TS_TRACE("--------------------------------------------------------");
409 
410       const std::map<size_t, double>& fixed = app->get_fixed_real_vars();
411       TS_ASSERT_EQUALS( fixed.size(), 0u);
412       app->fix_real_var(1,0.5);
413       TS_ASSERT_EQUALS( fixed.size(), 1u);
414       app->unfix_real_var(1);
415       TS_ASSERT_EQUALS( fixed.size(), 0u);
416 
417       try {
418         app->fix_real_var(3,0.5);
419         TS_FAIL("expected runtime errro");
420         }
421       catch (std::runtime_error&) {}
422     }
423    */
424 
test_var_labels1()425    void test_var_labels1()
426    {
427       TS_TRACE("--------------------------------------------------------");
428       TS_TRACE(" var_labels1 - Verify that variable labels can be ");
429       TS_TRACE("    accessed and modified.");
430       TS_TRACE("--------------------------------------------------------");
431 
432       TS_ASSERT_EQUALS( app->real_labels.as<labels_t>().size(), 0u);
433 
434       app->setRealLabel(0, "x0");
435       TS_ASSERT_EQUALS( app->real_labels.as<labels_t>().size(), 1u);
436 
437       app->setRealLabel(0, "");
438       TS_ASSERT_EQUALS( app->real_labels.as<labels_t>().size(), 0u);
439     }
440 
test_var_labels2()441    void test_var_labels2()
442    {
443       TS_TRACE("--------------------------------------------------------");
444       TS_TRACE(" var_labels2 - Verify that variable labels can be ");
445       TS_TRACE("    setup with a bimap.");
446       TS_TRACE("--------------------------------------------------------");
447 
448       labels_t _labels;
449       _labels.left.insert(std::make_pair(0, "x0"));
450       _labels.left.insert(std::make_pair(2, "x2"));
451       app->real_labels = _labels;
452 
453       labels_t labels = app->real_labels;
454       TS_ASSERT_EQUALS( labels.size(), 2u);
455 
456       app->real_labels = labels_t();
457       labels = app->real_labels;
458       TS_ASSERT_EQUALS( labels.size(), 0u);
459 
460       _labels.left.insert(std::make_pair(3, "x3"));
461       try {
462         app->real_labels = _labels;
463         TS_FAIL("Expected runtime_error exception");
464       }
465       catch (std::runtime_error& err) { }
466 
467       try {
468         app->setRealLabel(3,"x3");
469         TS_FAIL("Expected runtime_error exception");
470       }
471       catch (std::runtime_error& err) { }
472     }
473 
test_print_summary1()474     void test_print_summary1()
475     {
476     std::ofstream of("print_summary1.out");
477 
478       utilib::BasicArray<double> lower(3);
479       lower << -1.0;
480       utilib::BasicArray<double> upper(3);
481       upper << 1.0;
482       app->real_lower_bounds = lower;
483       app->real_upper_bounds = upper;
484 
485       app->setRealLabel(0,"x0");
486       //app->fix_real_var(1,0.5);
487 
488     app->print_summary(of);
489     of.close();
490 
491     TS_ASSERT_SAME_FILES("print_summary1.out", "print_summary1.txt");
492     }
493 
test_parse_xml1()494     void test_parse_xml1()
495     {
496     TiXmlDocument doc;
497     doc.LoadFile("example1a.xml");
498     XMLProcessor().process(doc.RootElement());
499 
500     std::string name = ApplicationMngr().get_newest_application();
501     std::ofstream of("print_summary2.out");
502     ApplicationMngr().get_application(name)->print_summary(of);
503     of.close();
504     ApplicationMngr().unregister_application(name);
505     TS_ASSERT_SAME_FILES("print_summary2.out", "print_summary2.txt");
506     }
507 
test_parse_xml2()508     void test_parse_xml2()
509     {
510     TiXmlDocument doc;
511     doc.LoadFile("example1b.xml");
512     try {
513         XMLProcessor().process(doc.RootElement());
514         TS_FAIL("Expected runtime_error");
515     }
516     catch (std::runtime_error&) {}
517     }
518 
519 };
520 
521 
522 #if 0
523 class Test_NLP0Problem_Misc : public CxxTest::TestSuite
524 {
525 public:
526 
527    void Xtest_test1a()
528    {
529       TS_TRACE("------------------------------------------------");
530       TS_TRACE("Test1a - simple application setup of NLP0Problem");
531       TS_TRACE("------------------------------------------------");
532       colin::Problem<colin::NLP0_problem> prob;
533       TS_TRACE("Problem set up");
534 
535       std::string foo = "example1";
536       colin::ConfigurableApplication<colin::NLP0_problem>* app
537          = colin::new_application(foo, &fn1);
538       app->num_real_vars = 3;
539       utilib::pvector<double> lower(3);
540       utilib::pvector<double> upper(3);
541       app->real_lower_bounds = lower;
542       app->real_upper_bounds = upper;
543       TS_TRACE("Application set up");
544 
545       prob.set_application(app);
546       TS_TRACE("Application assigned to problem");
547 
548       std::vector<double> vec(3);
549       vec[0] = 1;
550       vec[1] = 2;
551       vec[2] = 4;
552 
553       colin::real ans;
554       prob->EvalF(prob->eval_mngr(), vec, ans);
555       TS_ASSERT_EQUALS(ans, 8.0);
556       colin::AppResponse response;
557       colin::AppRequest request = prob->set_domain(vec);
558       ans = 0.0;
559       prob->Request_F(request, ans);
560       response = prob->eval_mngr().perform_evaluation(request);
561       TS_ASSERT_EQUALS(ans, 8.0);
562       TS_ASSERT_EQUALS(prob->eval_mngr(), 1);
563 
564       TS_TRACE("Deleting application");
565       ApplicationMngr().unregister_application(foo);
566       delete app;
567       TS_TRACE("Done.");
568 
569       ApplicationMngr().clear();
570    }
571 
572 };
573 #endif
574 
575 } // namespace colin
576