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 #include <colin/reformulation/Downcast.h>
14 #include <colin/ConfigurableApplication.h>
15 #include <colin/reformulation/ConstraintPenalty.h>
16 #include <colin/OptApplications.h>
17 #include <colin/Problem.h>
18 #include <colin/real.h>
19 #include <utilib/pvector.h>
20 #include <utilib/Any.h>
21 #include <cxxtest/TestSuite.h>
22 
23 #include "TestApplications.h"
24 
25 namespace colin {
26 namespace unittest { class Test_Reformulation_NLP0_NLP1; }
27 
28 class colin::unittest::Test_Reformulation_NLP0_NLP1 : public CxxTest::TestSuite
29 {
30 public:
31 
32 #if 0
33    void Xtest_traits()
34     {
35     utilib::Ereal<double> foo;
36     foo = 1.0;
37     CxxTest::ValueTraits< utilib::Ereal<double> > bar;
38     CxxTest::ValueTraits< utilib::Ereal<double> > tmp = CxxTest::traits(foo);
39     std::cerr << tmp.asString() << std::endl;
40     }
41 #endif
42 
43 
test_test1b()44    void test_test1b()
45    {
46       TS_TRACE("------------------------------------------------");
47       TS_TRACE("Test1b - Setup NLP1 application and downcast it ");
48       TS_TRACE("         before giving it to a NLP0 problem.");
49       TS_TRACE("------------------------------------------------");
50       colin::Problem<colin::NLP0_problem> prob;
51       TS_TRACE("Problem setup");
52 
53       std::string foo = "example1";
54       TestApplications::singleObj_denseCon<NLP1_problem> app;
55       app.num_linear_constraints = 0;
56       TS_TRACE("Application setup");
57 
58       DowncastApplication<NLP0_problem> dapp(app);
59       TS_TRACE("Application reformulated");
60 
61       prob.set_application(dapp);
62       TS_TRACE("Application assigned to problem");
63 
64       std::vector<double> vec(3);
65       vec[0] = 1;
66       vec[1] = 2;
67       vec[2] = 4;
68 
69       colin::real ans;
70       utilib::BasicArray<colin::real> gradient;
71       utilib::BasicArray<colin::real> constraints;
72 
73       prob->EvalF(prob->eval_mngr(), vec, ans);
74       TS_ASSERT_EQUALS(ans, 8.0);
75 
76       colin::Problem<colin::NLP1_problem> prob2;
77       prob2.set_application(app);
78 
79       prob2->EvalF(prob2->eval_mngr(), vec, ans);
80       TS_ASSERT_EQUALS(ans, 8.0);
81 
82       utilib::BasicArray<colin::real> grad_ans(3);
83       grad_ans[0] = 8.0;
84       grad_ans[1] = 4.0;
85       grad_ans[2] = 2.0;
86       prob2->EvalG(prob2->eval_mngr(), vec, gradient);
87       TS_ASSERT_EQUALS(gradient, grad_ans);
88 
89       utilib::BasicArray<colin::real> con_ans(3);
90       con_ans[0] = 21.0;
91       con_ans[1] = 17.0;
92       con_ans[2] = 7.0;
93       prob2->EvalCF(prob2->eval_mngr(), vec, constraints);
94       TS_ASSERT_EQUALS(constraints, con_ans);
95 
96       //ApplicationMngr().clear();
97       TS_TRACE("Done.");
98    }
99 
100 
test_test1c()101    void test_test1c()
102    {
103       TS_TRACE("------------------------------------------------");
104       TS_TRACE("Test1c - Setup NLP1 application and reformulate ");
105       TS_TRACE("         it to a NLP0 problem.");
106       TS_TRACE("------------------------------------------------");
107       colin::Problem<colin::NLP0_problem> prob;
108       TS_TRACE("Problem setup");
109 
110       std::string foo = "example1";
111       TestApplications::singleObj_denseCon<NLP1_problem> app;
112       app.num_nonlinear_constraints = 0;
113       app.num_linear_constraints = 0;
114       TS_TRACE("Application setup");
115 
116       colin::DowncastApplication<colin::NLP0_problem> reformulated_app(app);
117       TS_TRACE("Application reformulated");
118 
119       prob.set_application(reformulated_app);
120       TS_TRACE("Application assigned to problem");
121 
122       std::vector<double> vec(3);
123       vec[0] = 1;
124       vec[1] = 2;
125       vec[2] = 4;
126 
127       colin::real ans;
128       prob->EvalF(prob->eval_mngr(), vec, ans);
129       TS_ASSERT_EQUALS(ans, 8.0);
130 
131       colin::Problem<colin::NLP1_problem> prob2;
132       prob2.set_application(app);
133 
134       prob2->EvalF(prob2->eval_mngr(), vec, ans);
135       TS_ASSERT_EQUALS(ans, 8.0);
136 
137       utilib::BasicArray<colin::real> grad_ans(3);
138       grad_ans[0] = 8.0;
139       grad_ans[1] = 4.0;
140       grad_ans[2] = 2.0;
141       utilib::BasicArray<colin::real> gradient;
142       prob2->EvalG(prob2->eval_mngr(), vec, gradient);
143       TS_ASSERT_EQUALS(gradient, grad_ans);
144 
145       utilib::BasicArray<colin::real> con_ans(0);
146       utilib::BasicArray<colin::real> constraints;
147       prob2->EvalCF(prob2->eval_mngr(), vec, constraints);
148       TS_ASSERT_EQUALS(constraints, con_ans);
149 
150       //ApplicationMngr().clear();
151       TS_TRACE("Done.");
152    }
153 
154 
test_test1d()155    void test_test1d()
156    {
157       TS_TRACE("------------------------------------------------");
158       TS_TRACE("Test1d - Setup NLP1 application and reformulate ");
159       TS_TRACE("         it to eliminate constraints.");
160       TS_TRACE("------------------------------------------------");
161 
162       std::string foo = "example1";
163 
164       TestApplications::singleObj_denseCon<NLP1_problem> app;
165       app.num_linear_constraints = 0;
166       std::vector<real> clower(3);
167       std::vector<real> cupper(3);
168       clower[0] = 0.0;
169       clower[1] = real::negative_infinity;
170       clower[2] = 0.2;
171       cupper[0] = real::positive_infinity;
172       cupper[1] = 1.1;
173       cupper[2] = 1.2;
174       app.nonlinear_constraint_lower_bounds = clower;
175       app.nonlinear_constraint_upper_bounds = cupper;
176       TS_TRACE("Application setup");
177 
178       std::vector<double> x(3);
179       x[0] = 1;
180       x[1] = 2;
181       x[2] = 4;
182 
183       colin::real scalar;
184       utilib::BasicArray<colin::real> vec;
185       utilib::BasicArray<utilib::BasicArray<double> > mat;
186 
187       utilib::BasicArray<colin::real> con(3);
188       con[0] = 21;
189       con[1] = 17;
190       con[2] = 7;
191 
192       utilib::BasicArray<colin::real> cviol(3);
193       cviol[0] = 0;
194       cviol[1] = 15.9;
195       cviol[2] = 5.8;
196 
197       utilib::BasicArray<colin::real> grad(3);
198       grad[0] = 8;
199       grad[1] = 4;
200       grad[2] = 2;
201 
202       utilib::BasicArray<colin::real> penalty_grad(3);
203       penalty_grad[0] = 51.4; // 8 + 2*0*2 + 2*15.9*1 + 2*5.8*1
204       penalty_grad[1] = 79.2; // 4 + 2*0*4 + 2*15.9*2 + 2*5.8*1
205       penalty_grad[2] = 109;  // 2 + 2*0*8 + 2*15.9*3 + 2*5.8*1
206 
207       try
208       {
209          //std::cout << std::endl;
210          //std::cout << "SUMMARY" << std::endl;
211          //prob2->print_summary(cout);
212          //std::cout << std::endl;
213 
214          app.EvalF(app.eval_mngr(), x, scalar);
215          TS_ASSERT_EQUALS(scalar, 8.0)
216 
217          app.EvalG(app.eval_mngr(), x, vec);
218          TS_ASSERT_EQUALS(vec, grad)
219 
220          app.EvalNLCF(app.eval_mngr(), x, vec);
221          TS_ASSERT_EQUALS(vec, con)
222 
223          app.EvalCFViol(app.eval_mngr(), x, vec);
224          TS_ASSERT_EQUALS(vec, cviol)
225 
226          app.EvalCG(app.eval_mngr(), x, mat);
227          TS_ASSERT_EQUALS(mat[0][0], 2.);
228          TS_ASSERT_EQUALS(mat[0][1], 4.);
229          TS_ASSERT_EQUALS(mat[0][2], 8.);
230          TS_ASSERT_EQUALS(mat[1][0], 1.);
231          TS_ASSERT_EQUALS(mat[1][1], 2.);
232          TS_ASSERT_EQUALS(mat[1][2], 3.);
233          TS_ASSERT_EQUALS(mat[2][0], 1.);
234          TS_ASSERT_EQUALS(mat[2][1], 1.);
235          TS_ASSERT_EQUALS(mat[2][2], 1.);
236 
237          colin::ConstraintPenaltyApplication<colin::UNLP1_problem>
238             penalty_app(app);
239          TS_TRACE("Application reformulated");
240 
241          //std::cout << std::endl;
242          //std::cout << "SUMMARY" << std::endl;
243          //prob->print_summary(cout);
244          //std::cout << std::endl;
245 
246          penalty_app.EvalF(penalty_app.eval_mngr(), x, scalar);
247          TS_ASSERT_EQUALS(scalar, 294.45)
248 
249          penalty_app.EvalG(penalty_app.eval_mngr(), x, vec);
250          // Compare w/ delta because of round-off error...
251          TS_ASSERT_DELTA(vec[0], penalty_grad[0], 1e-10);
252          TS_ASSERT_DELTA(vec[1], penalty_grad[1], 1e-10);
253          TS_ASSERT_DELTA(vec[2], penalty_grad[2], 1e-10);
254       }
255       catch (utilib::bad_lexical_cast& err)
256       {
257          std::cerr << "Exception caught:" << err.what() << std::endl;
258          throw;
259       }
260 
261       //ApplicationMngr().clear();
262       TS_TRACE("Done.");
263    }
264 
265 
test_test1e()266    void test_test1e()
267    {
268       TS_TRACE("------------------------------------------------");
269       TS_TRACE("Test1d - Setup NLP1 application and reformulate ");
270       TS_TRACE("         it to eliminate constraints using .");
271       TS_TRACE("         lexical casts");
272       TS_TRACE("------------------------------------------------");
273 
274       std::string foo = "example1";
275       TestApplications::singleObj_denseCon<NLP1_problem> app;
276       app.num_linear_constraints = 0;
277       std::vector<real> clower(3);
278       std::vector<real> cupper(3);
279       clower[0] = 0.0;
280       clower[1] = real::negative_infinity;
281       clower[2] = 0.2;
282       cupper[0] = real::positive_infinity;
283       cupper[1] = 1.1;
284       cupper[2] = 1.2;
285       app.nonlinear_constraint_lower_bounds = clower;
286       app.nonlinear_constraint_upper_bounds = cupper;
287       TS_TRACE("Application setup");
288 
289       std::vector<double> vec(3);
290       vec[0] = 1;
291       vec[1] = 2;
292       vec[2] = 4;
293       colin::real ans;
294 
295       utilib::BasicArray<colin::real> grad_ans(3);
296       grad_ans[0] = 8.0;
297       grad_ans[1] = 4.0;
298       grad_ans[2] = 2.0;
299 
300       utilib::BasicArray<colin::real> con_ans(3);
301       con_ans[0] = 21;
302       con_ans[1] = 17;
303       con_ans[2] = 7;
304 
305       try
306       {
307          //utilib::exception_mngr::set_mode(utilib::exception_mngr::Exit);
308          colin::Problem<colin::NLP1_problem> prob2;
309          prob2.set_application(app);
310 
311          //std::cout << std::endl;
312          //std::cout << "SUMMARY" << std::endl;
313          //prob2->print_summary(cout);
314          //std::cout << std::endl;
315          prob2->EvalF(prob2->eval_mngr(), vec, ans);
316          TS_ASSERT_EQUALS(ans, 8.0)
317 
318          utilib::BasicArray<colin::real> gradient;
319          prob2->EvalG(prob2->eval_mngr(), vec, gradient);
320          TS_ASSERT_EQUALS(gradient, grad_ans)
321 
322          utilib::BasicArray<colin::real> constraints;
323          prob2->EvalNLCF(prob2->eval_mngr(), vec, constraints);
324          TS_ASSERT_EQUALS(constraints, con_ans)
325 
326          Problem<UNLP0_problem> prob;
327          prob = prob2;
328       TS_TRACE("Application assigned to problem");
329 
330          //std::cout << std::endl;
331          //std::cout << "SUMMARY" << std::endl;
332          //prob->print_summary(cout);
333          //std::cout << std::endl;
334 
335          prob->EvalF(prob->eval_mngr(), vec, ans);
336          TS_ASSERT_EQUALS(ans, 294.45)
337       }
338       catch (utilib::bad_lexical_cast& err)
339       {
340          std::cerr << "Exception caught:" << err.what()
341          << std::endl;
342          throw;
343       }
344 
345       //ApplicationMngr().clear();
346       TS_TRACE("Done");
347    }
348 
349 
350 #if 0
351    void Xtest_test1f()
352    {
353       std::cout << std::endl;
354       std::cout << "Test1f - full test of NLP application" << std::endl;
355 
356       std::string foo = "example1";
357       colin::ConfigurableApplication<colin::NLP1_problem>* app
358       = colin::new_application(foo, &fn4);
359       app->set_num_real_vars(3);
360 
361       utilib::pvector<double> lower(3);
362       utilib::pvector<double> upper(3);
363       app->set_real_bounds(lower, upper);
364       app->set_num_nonlinear_constraints(3);
365       app->set_num_linear_constraints(3);
366 
367       TS_TRACE("Application setup");
368 
369       std::vector<double> vec(3);
370       vec[0] = 1;
371       vec[1] = 2;
372       vec[2] = 4;
373 
374       colin::real ans;
375       app->EvalF(app->eval_mngr(), vec, ans);
376       std::cout << "ANS: f_info = " << ans << std::endl;
377 
378       colin::AppResponse response;
379       colin::AppRequest request = app->set_domain(vec);
380       ans = 0.0;
381       app->Request_F(request, ans);
382       app->eval_mngr().perform_evaluation(request);
383       std::cout << "ANS: f_info = " << ans << std::endl;
384 
385       vector<real> v_ans;
386 
387       v_ans.clear();
388       request = app->set_domain(vec);
389       app->Request_CF(request, v_ans);
390       response = app->eval_mngr().perform_evaluation(request);
391       cout << "cf_info = " << v_ans << endl;
392       cout << "response = " << response;
393       cout << "  (cf) = " << response.get(cf_info) << endl;
394       cout << "  (nlcf) = " << response.get(nlcf_info) << endl;
395 
396       v_ans.clear();
397       app->EvalNLCF(app->eval_mngr(), vec, v_ans);
398       std::cout << "nlcf_info =\t" << v_ans << std::endl;
399 
400       v_ans.clear();
401       app->EvalNLEqCF(app->eval_mngr(), vec, v_ans);
402       std::cout << "nleqcf_info =\t" << v_ans << std::endl;
403 
404       v_ans.clear();
405       app->EvalNLIneqCF(app->eval_mngr(), vec, v_ans);
406       std::cout << "nlineqcf_info =\t" << v_ans << std::endl;
407 
408       v_ans.clear();
409       app->EvalLCF(app->eval_mngr(), vec, v_ans);
410       std::cout << "lcf_info =\t" << v_ans << std::endl;
411 
412       v_ans.clear();
413       app->EvalLEqCF(app->eval_mngr(), vec, v_ans);
414       std::cout << "leqcf_info =\t" << v_ans << std::endl;
415 
416       v_ans.clear();
417       app->EvalLIneqCF(app->eval_mngr(), vec, v_ans);
418       std::cout << "ineqlcf_info =\t" << v_ans << std::endl;
419 
420       v_ans.clear();
421       app->EvalCF(app->eval_mngr(), vec, v_ans);
422       std::cout << "cf_info =\t" << v_ans << std::endl;
423 
424       v_ans.clear();
425       app->EvalEqCF(app->eval_mngr(), vec, v_ans);
426       std::cout << "eqcf_info =\t" << v_ans << std::endl;
427 
428       v_ans.clear();
429       app->EvalIneqCF(app->eval_mngr(), vec, v_ans);
430       std::cout << "ineqcf_info =\t" << v_ans << std::endl;
431 
432       v_ans.clear();
433       app->EvalCFViol(app->eval_mngr(), vec, v_ans);
434       std::cout << "cvf_info =\t" << v_ans << std::endl;
435 
436       std::vector<real> clower(3);
437       std::vector<real> cupper(3);
438       clower[0] = 0.0;
439       clower[1] = real::negative_infinity;
440       clower[2] = 10;
441 
442       cupper[0] = real::positive_infinity;
443       cupper[1] = 1;
444       cupper[2] = 10;
445       app->set_nonlinear_constraint_bounds(clower, cupper);
446       app->set_linear_constraint_bounds(clower, cupper);
447       TS_TRACE("Set constraint bounds");
448 
449       v_ans.clear();
450       app->EvalCF(app->eval_mngr(), vec, v_ans);
451       cout << "cf_info = \t" << v_ans << endl;
452 
453       v_ans.clear();
454       app->EvalNLCF(app->eval_mngr(), vec, v_ans);
455       std::cout << "nlcf_info =\t" << v_ans << std::endl;
456 
457       v_ans.clear();
458       app->EvalNLEqCF(app->eval_mngr(), vec, v_ans);
459       std::cout << "nleqcf_info =\t" << v_ans << std::endl;
460 
461       v_ans.clear();
462       app->EvalNLIneqCF(app->eval_mngr(), vec, v_ans);
463       std::cout << "nlineqcf_info =\t" << v_ans << std::endl;
464 
465       v_ans.clear();
466       app->EvalLCF(app->eval_mngr(), vec, v_ans);
467       std::cout << "lcf_info =\t" << v_ans << std::endl;
468 
469       v_ans.clear();
470       app->EvalLEqCF(app->eval_mngr(), vec, v_ans);
471       std::cout << "leqcf_info =\t" << v_ans << std::endl;
472 
473       v_ans.clear();
474       app->EvalLIneqCF(app->eval_mngr(), vec, v_ans);
475       std::cout << "ineqlcf_info =\t" << v_ans << std::endl;
476 
477       v_ans.clear();
478       app->EvalCF(app->eval_mngr(), vec, v_ans);
479       std::cout << "cf_info =\t" << v_ans << std::endl;
480 
481       v_ans.clear();
482       app->EvalEqCF(app->eval_mngr(), vec, v_ans);
483       std::cout << "eqcf_info =\t" << v_ans << std::endl;
484 
485       v_ans.clear();
486       app->EvalIneqCF(app->eval_mngr(), vec, v_ans);
487       std::cout << "ineqcf_info =\t" << v_ans << std::endl;
488 
489       v_ans.clear();
490       app->EvalCFViol(app->eval_mngr(), vec, v_ans);
491       std::cout << "cvf_info =\t" << v_ans << std::endl;
492 
493 
494       TS_TRACE("Set linear constraint matrix");
495       utilib::RMSparseMatrix<double> mat;
496       int*    itmp = new int[3];
497       double* dtmp = new double[3];
498       *itmp = 0;
499       *dtmp = 1.0;
500       mat.adjoinRow(1, itmp, dtmp);
501       *itmp = 1;
502       *dtmp = 2.0;
503       mat.adjoinRow(1, itmp, dtmp);
504       itmp[0] = 0;
505       dtmp[0] = -1.0;
506       itmp[1] = 2;
507       dtmp[1] = 1.0;
508       mat.adjoinRow(2, itmp, dtmp);
509       app->set_linear_constraint_matrix(mat);
510       //  1 . .
511       //  . 2 .
512       // -1 . 1
513 
514       v_ans.clear();
515       app->EvalLCF(app->eval_mngr(), vec, v_ans);
516       std::cout << "lcf_info =\t" << v_ans << std::endl;
517 
518       v_ans.clear();
519       app->EvalLEqCF(app->eval_mngr(), vec, v_ans);
520       std::cout << "leqcf_info =\t" << v_ans << std::endl;
521 
522       v_ans.clear();
523       app->EvalLIneqCF(app->eval_mngr(), vec, v_ans);
524       std::cout << "ineqlcf_info =\t" << v_ans << std::endl;
525 
526       v_ans.clear();
527       app->EvalCF(app->eval_mngr(), vec, v_ans);
528       cout << "cf_info = \t" << v_ans << endl;
529 
530 
531       TS_TRACE("Deleting Application");
532       ApplicationMngr().unregister_application(foo);
533       delete app;
534 
535       delete [] itmp;
536       delete [] dtmp;
537 
538       ApplicationMngr().clear();
539       TS_TRACE("Done");
540    }
541 #endif
542 
543 };
544 
545 } // namespace colin
546