MittelmannParaCntrl.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. // Copyright (C) 2005, 2006 International Business Machines and others.
  2. // All Rights Reserved.
  3. // This code is published under the Eclipse Public License.
  4. //
  5. // $Id: MittelmannParaCntrl.hpp 2005 2011-06-06 12:55:16Z stefan $
  6. //
  7. // Authors: Andreas Waechter IBM 2005-10-18
  8. #ifndef __MITTELMANNPARACNTRL_HPP__
  9. #define __MITTELMANNPARACNTRL_HPP__
  10. #include "RegisteredTNLP.hpp"
  11. #ifdef HAVE_CONFIG_H
  12. #include "config.h"
  13. #else
  14. #include "configall_system.h"
  15. #endif
  16. #ifdef HAVE_CMATH
  17. # include <cmath>
  18. #else
  19. # ifdef HAVE_MATH_H
  20. # include <math.h>
  21. # else
  22. # error "don't have header file for math"
  23. # endif
  24. #endif
  25. using namespace Ipopt;
  26. /** Base class for parabolic and elliptic control problems, as
  27. * formulated by Hans Mittelmann as problem (P) in "Sufficient
  28. * Optimality for Discretized Parabolic and Elliptic Control
  29. * Problems"
  30. */
  31. template<class T>
  32. class MittelmannParaCntrlBase : public RegisteredTNLP
  33. {
  34. public:
  35. /** Constructor. */
  36. MittelmannParaCntrlBase();
  37. /** Default destructor */
  38. virtual ~MittelmannParaCntrlBase();
  39. /**@name Overloaded from TNLP */
  40. //@{
  41. /** Method to return some info about the nlp */
  42. virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
  43. Index& nnz_h_lag, IndexStyleEnum& index_style);
  44. /** Method to return the bounds for my problem */
  45. virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
  46. Index m, Number* g_l, Number* g_u);
  47. /** Method to return the starting point for the algorithm */
  48. virtual bool get_starting_point(Index n, bool init_x, Number* x,
  49. bool init_z, Number* z_L, Number* z_U,
  50. Index m, bool init_lambda,
  51. Number* lambda);
  52. /** Method to return the objective value */
  53. virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value);
  54. /** Method to return the gradient of the objective */
  55. virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f);
  56. /** Method to return the constraint residuals */
  57. virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g);
  58. /** Method to return:
  59. * 1) The structure of the jacobian (if "values" is NULL)
  60. * 2) The values of the jacobian (if "values" is not NULL)
  61. */
  62. virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
  63. Index m, Index nele_jac, Index* iRow, Index *jCol,
  64. Number* values);
  65. /** Method to return:
  66. * 1) The structure of the hessian of the lagrangian (if "values" is NULL)
  67. * 2) The values of the hessian of the lagrangian (if "values" is not NULL)
  68. */
  69. virtual bool eval_h(Index n, const Number* x, bool new_x,
  70. Number obj_factor, Index m, const Number* lambda,
  71. bool new_lambda, Index nele_hess, Index* iRow,
  72. Index* jCol, Number* values);
  73. //@}
  74. /** Method for returning scaling parameters */
  75. virtual bool get_scaling_parameters(Number& obj_scaling,
  76. bool& use_x_scaling, Index n,
  77. Number* x_scaling,
  78. bool& use_g_scaling, Index m,
  79. Number* g_scaling);
  80. /** @name Solution Methods */
  81. //@{
  82. /** This method is called after the optimization, and could write an
  83. * output file with the optimal profiles */
  84. virtual void finalize_solution(SolverReturn status,
  85. Index n, const Number* x, const Number* z_L, const Number* z_U,
  86. Index m, const Number* g, const Number* lambda,
  87. Number obj_value,
  88. const IpoptData* ip_data,
  89. IpoptCalculatedQuantities* ip_cq);
  90. //@}
  91. virtual bool InitializeProblem(Index N);
  92. private:
  93. /**@name Methods to block default compiler methods.
  94. * The compiler automatically generates the following three methods.
  95. * Since the default compiler implementation is generally not what
  96. * you want (for all but the most simple classes), we usually
  97. * put the declarations of these methods in the private section
  98. * and never implement them. This prevents the compiler from
  99. * implementing an incorrect "default" behavior without us
  100. * knowing. (See Scott Meyers book, "Effective C++")
  101. *
  102. */
  103. //@{
  104. MittelmannParaCntrlBase(const MittelmannParaCntrlBase<T>&);
  105. MittelmannParaCntrlBase& operator=(const MittelmannParaCntrlBase<T>&);
  106. //@}
  107. /**@name Problem specification */
  108. //@{
  109. /** Upper bound on t */
  110. Number T_;
  111. /** Upper bound on x */
  112. Number l_;
  113. /** Number of mesh points in t direction */
  114. Index Nt_;
  115. /** Number of mesh points in x direction */
  116. Index Nx_;
  117. /** Step size in t direction*/
  118. Number dt_;
  119. /** Step size in x direction*/
  120. Number dx_;
  121. /** overall lower bound on y */
  122. Number lb_y_;
  123. /** overall upper bound on y */
  124. Number ub_y_;
  125. /** overall lower bound on u */
  126. Number lb_u_;
  127. /** overall upper bound on u */
  128. Number ub_u_;
  129. /** Weighting parameter for the control target deviation functional
  130. * in the objective */
  131. Number alpha_;
  132. /** Weighting parameter in PDE */
  133. Number beta_;
  134. /** Array for the target profile for y in objective */
  135. Number* y_T_;
  136. /** Array for weighting function a_y in objective */
  137. Number* a_y_;
  138. /** Array for weighting function a_u in objective */
  139. Number* a_u_;
  140. //@}
  141. /**@name Auxilliary methods */
  142. //@{
  143. /** Translation of mesh point indices to NLP variable indices for
  144. * y(x_ij) */
  145. inline Index y_index(Index jx, Index it) const
  146. {
  147. return jx + (Nx_+1)*it;
  148. }
  149. inline Index u_index(Index it) const
  150. {
  151. return (Nt_+1)*(Nx_+1) + it - 1;
  152. }
  153. /** Compute the grid coordinate for given index in t direction */
  154. inline Number t_grid(Index i) const
  155. {
  156. return dt_*(Number)i;
  157. }
  158. /** Compute the grid coordinate for given index in x direction */
  159. inline Number x_grid(Index j) const
  160. {
  161. return dx_*(Number)j;
  162. }
  163. //@}
  164. };
  165. template <class T>
  166. MittelmannParaCntrlBase<T>::MittelmannParaCntrlBase()
  167. :
  168. y_T_(NULL),
  169. a_y_(NULL),
  170. a_u_(NULL)
  171. {}
  172. template <class T>
  173. MittelmannParaCntrlBase<T>::~MittelmannParaCntrlBase()
  174. {
  175. delete [] y_T_;
  176. delete [] a_y_;
  177. delete [] a_u_;
  178. }
  179. template <class T>
  180. bool MittelmannParaCntrlBase<T>::
  181. InitializeProblem(Index N)
  182. {
  183. typename T::ProblemSpecs p;
  184. if (N<1) {
  185. printf("N has to be at least 1.");
  186. return false;
  187. }
  188. T_ = p.T();
  189. l_ = p.l();
  190. Nt_ = N;
  191. Nx_ = N;
  192. dt_ = T_/Nt_;
  193. dx_ = l_/Nx_;
  194. lb_y_ = p.lb_y();
  195. ub_y_ = p.ub_y();
  196. lb_u_ = p.lb_u();
  197. ub_u_ = p.ub_u();
  198. alpha_ = p.alpha();
  199. beta_ = p.beta();
  200. y_T_ = new Number[Nx_+1];
  201. for (Index j=0; j<=Nx_; j++) {
  202. y_T_[j] = p.y_T(x_grid(j));
  203. }
  204. a_y_ = new Number[Nt_];
  205. for (Index i=1; i<=Nt_; i++) {
  206. a_y_[i-1] = p.a_y(t_grid(i));
  207. }
  208. a_u_ = new Number[Nt_];
  209. for (Index i=1; i<=Nt_; i++) {
  210. a_u_[i-1] = p.a_u(t_grid(i));
  211. }
  212. return true;
  213. }
  214. template <class T>
  215. bool MittelmannParaCntrlBase<T>::
  216. get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
  217. Index& nnz_h_lag, IndexStyleEnum& index_style)
  218. {
  219. typename T::ProblemSpecs p;
  220. n = (Nt_+1)*(Nx_+1) + Nt_;
  221. m = Nt_*(Nx_-1) + Nt_ + Nt_;
  222. nnz_jac_g = 6*Nt_*(Nx_-1) + 3*Nt_ + 4*Nt_;
  223. nnz_h_lag = Nx_+1 + Nt_;
  224. if (!p.phi_dydy_always_zero()) {
  225. nnz_h_lag += Nt_;
  226. }
  227. index_style = C_STYLE;
  228. return true;
  229. }
  230. template <class T>
  231. bool MittelmannParaCntrlBase<T>::
  232. get_bounds_info(Index n, Number* x_l, Number* x_u,
  233. Index m, Number* g_l, Number* g_u)
  234. {
  235. typename T::ProblemSpecs p;
  236. // Set overall bounds on the variables
  237. for (Index jx=0; jx<=Nx_; jx++) {
  238. for (Index it=1; it<=Nt_; it++) {
  239. Index iy = y_index(jx,it);
  240. x_l[iy] = lb_y_;
  241. x_u[iy] = ub_y_;
  242. }
  243. }
  244. for (Index i=1; i<=Nt_; i++) {
  245. Index iu = u_index(i);
  246. x_l[iu] = lb_u_;
  247. x_u[iu] = ub_u_;
  248. }
  249. /*
  250. // Boundary condition for t=0
  251. for (Index it=0; it<=Nt_; it++) {
  252. Index iy = y_index(0,it);
  253. x_u[iy] = x_l[iy] = p.a(t_grid(it));
  254. }
  255. */
  256. // Boundary condition for t=0
  257. for (Index jx=0; jx<=Nx_; jx++) {
  258. Index iy = y_index(jx,0);
  259. x_u[iy] = x_l[iy] = p.a(x_grid(jx));
  260. }
  261. // all discretized PDE constraints have right hand side zero
  262. for (Index i=0; i<Nt_*(Nx_-1) + Nt_; i++) {
  263. g_l[i] = 0.;
  264. g_u[i] = 0.;
  265. }
  266. // but we put b on the right hand side for the x=L boundary condition
  267. for (Index i=0; i<Nt_; i++) {
  268. g_l[Nt_*(Nx_-1) + Nt_ + i]
  269. = g_u[Nt_*(Nx_-1) + Nt_ + i]
  270. = p.b(t_grid(i+1));
  271. }
  272. return true;
  273. }
  274. template <class T>
  275. bool MittelmannParaCntrlBase<T>::
  276. get_starting_point(Index n, bool init_x, Number* x,
  277. bool init_z, Number* z_L, Number* z_U,
  278. Index m, bool init_lambda,
  279. Number* lambda)
  280. {
  281. DBG_ASSERT(init_x==true && init_z==false && init_lambda==false);
  282. // Set starting point for y
  283. for (Index jx=0; jx<=Nx_; jx++) {
  284. for (Index it=0; it<=Nt_; it++) {
  285. x[y_index(jx,it)] = 0.;
  286. }
  287. }
  288. // for u
  289. for (Index i=1; i<=Nt_; i++) {
  290. x[u_index(i)] = (ub_u_+lb_u_)/2.;
  291. }
  292. /*
  293. // DELETEME
  294. for (Index i=0; i<n; i++) {
  295. x[i] += 0.01*i;
  296. }
  297. */
  298. return true;
  299. }
  300. template <class T>
  301. bool MittelmannParaCntrlBase<T>::
  302. get_scaling_parameters(Number& obj_scaling,
  303. bool& use_x_scaling,
  304. Index n, Number* x_scaling,
  305. bool& use_g_scaling,
  306. Index m, Number* g_scaling)
  307. {
  308. obj_scaling = 1./Min(dx_,dt_);
  309. use_x_scaling = false;
  310. use_g_scaling = false;
  311. return true;
  312. }
  313. template <class T>
  314. bool MittelmannParaCntrlBase<T>::
  315. eval_f(Index n, const Number* x,
  316. bool new_x, Number& obj_value)
  317. {
  318. // Deviation of y from target
  319. Number a = x[y_index(0,Nt_)] - y_T_[0];
  320. Number sum = 0.5*a*a;
  321. for (Index jx=1; jx<Nx_; jx++) {
  322. a = x[y_index(jx,Nt_)] - y_T_[jx];
  323. sum += a*a;
  324. }
  325. a = x[y_index(Nx_,Nt_)] - y_T_[Nx_];
  326. sum += 0.5*a*a;
  327. obj_value = 0.5*dx_*sum;
  328. // smoothing for control
  329. if (alpha_!=.0) {
  330. sum = 0.5*x[u_index(Nt_)]*x[u_index(Nt_)];
  331. for (Index it=1; it < Nt_; it++) {
  332. sum += x[u_index(it)]*x[u_index(it)];
  333. }
  334. obj_value += 0.5*alpha_*dt_*sum;
  335. }
  336. // third term
  337. sum = 0.;
  338. for (Index it=1; it<Nt_; it++) {
  339. sum += a_y_[it-1]*x[y_index(Nx_,it)] + a_u_[it-1]*x[u_index(it)];
  340. }
  341. sum += 0.5*(a_y_[Nt_-1]*x[y_index(Nx_,Nt_)] + a_u_[Nt_-1]*x[u_index(Nt_)]);
  342. obj_value += dt_*sum;
  343. return true;
  344. }
  345. template <class T>
  346. bool MittelmannParaCntrlBase<T>::
  347. eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
  348. {
  349. // First set all y entries to zero
  350. for (Index jx=0; jx<=Nx_; jx++) {
  351. for (Index it=0; it<=Nt_; it++) {
  352. grad_f[y_index(jx,it)] = 0.;
  353. }
  354. }
  355. // y entries from y target
  356. grad_f[y_index(0,Nt_)] = 0.5*dx_*(x[y_index(0,Nt_)] - y_T_[0]);
  357. for (Index jx=1; jx<Nx_; jx++) {
  358. grad_f[y_index(jx,Nt_)] = dx_*(x[y_index(jx,Nt_)] - y_T_[jx]);
  359. }
  360. grad_f[y_index(Nx_,Nt_)] = 0.5*dx_*(x[y_index(Nx_,Nt_)] - y_T_[Nx_]);
  361. // y entries from thrid term
  362. for (Index it=1; it<Nt_; it++) {
  363. grad_f[y_index(Nx_,it)] = dt_*a_y_[it-1];
  364. }
  365. grad_f[y_index(Nx_,Nt_)] += 0.5*dt_*a_y_[Nt_-1];
  366. // u entries from smoothing and third term
  367. for (Index it=1; it<Nt_; it++) {
  368. grad_f[u_index(it)] = alpha_*dt_*x[u_index(it)] + dt_*a_u_[it-1];
  369. }
  370. grad_f[u_index(Nt_)] = 0.5*dt_*(alpha_*x[u_index(Nt_)] + a_u_[Nt_-1]);
  371. return true;
  372. }
  373. template <class T>
  374. bool MittelmannParaCntrlBase<T>::
  375. eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
  376. {
  377. typename T::ProblemSpecs p;
  378. Index ig=0;
  379. Number f = 1./(2.*dx_*dx_);
  380. for (Index jx=1; jx<Nx_; jx++) {
  381. for (Index it=0; it<Nt_; it++) {
  382. g[ig] = (x[y_index(jx,it)]-x[y_index(jx,it+1)])/dt_
  383. + f*(x[y_index(jx-1,it)] - 2.*x[y_index(jx,it)]
  384. + x[y_index(jx+1,it)] + x[y_index(jx-1,it+1)]
  385. - 2.*x[y_index(jx,it+1)] + x[y_index(jx+1,it+1)]);
  386. ig++;
  387. }
  388. }
  389. for (Index it=1; it<=Nt_; it++) {
  390. g[ig] = (x[y_index(2,it)] - 4.*x[y_index(1,it)] + 3.*x[y_index(0,it)]);
  391. ig++;
  392. }
  393. f = 1./(2.*dx_);
  394. for (Index it=1; it<=Nt_; it++) {
  395. g[ig] =
  396. f*(x[y_index(Nx_-2,it)] - 4.*x[y_index(Nx_-1,it)]
  397. + 3.*x[y_index(Nx_,it)]) + beta_*x[y_index(Nx_,it)]
  398. - x[u_index(it)] + p.phi(x[y_index(Nx_,it)]);
  399. ig++;
  400. }
  401. DBG_ASSERT(ig == m);
  402. return true;
  403. }
  404. template <class T>
  405. bool MittelmannParaCntrlBase<T>::
  406. eval_jac_g(Index n, const Number* x, bool new_x,
  407. Index m, Index nele_jac, Index* iRow, Index *jCol,
  408. Number* values)
  409. {
  410. typename T::ProblemSpecs p;
  411. Index ijac = 0;
  412. if (values == NULL) {
  413. Index ig = 0;
  414. for (Index jx=1; jx<Nx_; jx++) {
  415. for (Index it=0; it<Nt_; it++) {
  416. iRow[ijac] = ig;
  417. jCol[ijac] = y_index(jx-1,it);
  418. ijac++;
  419. iRow[ijac] = ig;
  420. jCol[ijac] = y_index(jx,it);
  421. ijac++;
  422. iRow[ijac] = ig;
  423. jCol[ijac] = y_index(jx+1,it);
  424. ijac++;
  425. iRow[ijac] = ig;
  426. jCol[ijac] = y_index(jx-1,it+1);
  427. ijac++;
  428. iRow[ijac] = ig;
  429. jCol[ijac] = y_index(jx,it+1);
  430. ijac++;
  431. iRow[ijac] = ig;
  432. jCol[ijac] = y_index(jx+1,it+1);
  433. ijac++;
  434. ig++;
  435. }
  436. }
  437. for (Index it=1; it<=Nt_; it++) {
  438. iRow[ijac] = ig;
  439. jCol[ijac] = y_index(0,it);
  440. ijac++;
  441. iRow[ijac] = ig;
  442. jCol[ijac] = y_index(1,it);
  443. ijac++;
  444. iRow[ijac] = ig;
  445. jCol[ijac] = y_index(2,it);
  446. ijac++;
  447. ig++;
  448. }
  449. for (Index it=1; it<=Nt_; it++) {
  450. iRow[ijac] = ig;
  451. jCol[ijac] = y_index(Nx_-2,it);
  452. ijac++;
  453. iRow[ijac] = ig;
  454. jCol[ijac] = y_index(Nx_-1,it);
  455. ijac++;
  456. iRow[ijac] = ig;
  457. jCol[ijac] = y_index(Nx_,it);
  458. ijac++;
  459. iRow[ijac] = ig;
  460. jCol[ijac] = u_index(it);
  461. ijac++;
  462. ig++;
  463. }
  464. DBG_ASSERT(ig == m);
  465. }
  466. else {
  467. Number f = 1./(2.*dx_*dx_);
  468. Number f2 = 1./dt_;
  469. for (Index jx=1; jx<Nx_; jx++) {
  470. for (Index it=0; it<Nt_; it++) {
  471. values[ijac++] = f;
  472. values[ijac++] = f2 - 2.*f;
  473. values[ijac++] = f;
  474. values[ijac++] = f;
  475. values[ijac++] = -f2 - 2.*f;
  476. values[ijac++] = f;
  477. }
  478. }
  479. for (Index it=1; it<=Nt_; it++) {
  480. values[ijac++] = 3.;
  481. values[ijac++] = -4.;
  482. values[ijac++] = 1.;
  483. }
  484. f = 1./(2.*dx_);
  485. for (Index it=1; it<=Nt_; it++) {
  486. values[ijac++] = f;
  487. values[ijac++] = -4.*f;
  488. values[ijac++] = 3.*f + beta_ + p.phi_dy(x[y_index(Nx_,it)]);
  489. values[ijac++] = -1.;
  490. }
  491. }
  492. return true;
  493. }
  494. template <class T>
  495. bool MittelmannParaCntrlBase<T>::
  496. eval_h(Index n, const Number* x, bool new_x,
  497. Number obj_factor, Index m, const Number* lambda,
  498. bool new_lambda, Index nele_hess, Index* iRow,
  499. Index* jCol, Number* values)
  500. {
  501. typename T::ProblemSpecs p;
  502. Index ihes = 0;
  503. if (values == NULL) {
  504. // y values from objective
  505. for (Index jx=0; jx<= Nx_; jx++) {
  506. iRow[ihes] = y_index(jx,Nt_);
  507. jCol[ihes] = y_index(jx,Nt_);
  508. ihes++;
  509. }
  510. // u from objective
  511. for (Index it=1; it<=Nt_; it++) {
  512. iRow[ihes] = u_index(it);
  513. jCol[ihes] = u_index(it);
  514. ihes++;
  515. }
  516. // constraint
  517. if (!p.phi_dydy_always_zero()) {
  518. for (Index it=1; it<=Nt_; it++) {
  519. iRow[ihes] = y_index(Nx_,it);
  520. jCol[ihes] = y_index(Nx_,it);
  521. ihes++;
  522. }
  523. }
  524. }
  525. else {
  526. // y values from objective
  527. values[ihes++] = obj_factor*0.5*dx_;
  528. for (Index jx=1; jx<Nx_; jx++) {
  529. values[ihes++] = obj_factor*dx_;
  530. }
  531. values[ihes++] = obj_factor*0.5*dx_;
  532. // u from objective
  533. for (Index it=1; it<Nt_; it++) {
  534. values[ihes++] = obj_factor*alpha_*dt_;
  535. }
  536. values[ihes++] = obj_factor*0.5*alpha_*dt_;
  537. // constrainT
  538. if (!p.phi_dydy_always_zero()) {
  539. Index ig = (Nx_-1)*Nt_ + Nt_;
  540. for (Index it=1; it<=Nt_; it++) {
  541. values[ihes++] = lambda[ig++]*p.phi_dydy(x[y_index(Nx_,it)]);
  542. }
  543. }
  544. }
  545. DBG_ASSERT(ihes==nele_hess);
  546. return true;
  547. }
  548. template <class T>
  549. void MittelmannParaCntrlBase<T>::
  550. finalize_solution(SolverReturn status,
  551. Index n, const Number* x, const Number* z_L,
  552. const Number* z_U,
  553. Index m, const Number* g, const Number* lambda,
  554. Number obj_value,
  555. const IpoptData* ip_data,
  556. IpoptCalculatedQuantities* ip_cq)
  557. {}
  558. class MittelmannParaCntrl5_1
  559. {
  560. public:
  561. class ProblemSpecs
  562. {
  563. public:
  564. ProblemSpecs ()
  565. :
  566. pi_(4.*atan(1.)),
  567. exp13_(exp(1./3.)),
  568. exp23_(exp(2./3.)),
  569. exp1_(exp(1.)),
  570. expm1_(exp(-1.)),
  571. sqrt2_(sqrt(2.))
  572. {}
  573. Number T()
  574. {
  575. return 1.;
  576. }
  577. Number l()
  578. {
  579. return pi_/4.;
  580. }
  581. Number lb_y()
  582. {
  583. return -1e20;
  584. }
  585. Number ub_y()
  586. {
  587. return 1e20;
  588. }
  589. Number lb_u()
  590. {
  591. return 0.;
  592. }
  593. Number ub_u()
  594. {
  595. return 1.;
  596. }
  597. Number alpha()
  598. {
  599. return sqrt2_/2.*(exp23_-exp13_);
  600. }
  601. Number beta()
  602. {
  603. return 1.;
  604. }
  605. inline Number y_T(Number x)
  606. {
  607. return (exp1_ + expm1_)*cos(x);
  608. }
  609. inline Number a(Number x)
  610. {
  611. return cos(x);
  612. }
  613. inline Number a_y(Number t)
  614. {
  615. return -exp(-2.*t);
  616. }
  617. inline Number a_u(Number t)
  618. {
  619. return sqrt2_/2.*exp13_;
  620. }
  621. inline Number b(Number t)
  622. {
  623. return exp(-4.*t)/4.
  624. - Min(1.,Max(0.,(exp(t)-exp13_)/(exp23_-exp13_)));
  625. }
  626. inline Number phi(Number y)
  627. {
  628. return y*pow(fabs(y),3);
  629. }
  630. inline Number phi_dy(Number y)
  631. {
  632. return 4.*pow(fabs(y),3);
  633. }
  634. inline Number phi_dydy(Number y)
  635. {
  636. return 12.*y*y;
  637. }
  638. inline bool phi_dydy_always_zero()
  639. {
  640. return false;
  641. }
  642. private:
  643. const Number pi_;
  644. const Number exp13_;
  645. const Number exp23_;
  646. const Number exp1_;
  647. const Number expm1_;
  648. const Number sqrt2_;
  649. };
  650. };
  651. class MittelmannParaCntrl5_2_1
  652. {
  653. public:
  654. class ProblemSpecs
  655. {
  656. public:
  657. ProblemSpecs ()
  658. {}
  659. Number T()
  660. {
  661. return 1.58;
  662. }
  663. Number l()
  664. {
  665. return 1.;
  666. }
  667. Number lb_y()
  668. {
  669. return -1e20;
  670. }
  671. Number ub_y()
  672. {
  673. return 1e20;
  674. }
  675. Number lb_u()
  676. {
  677. return -1.;
  678. }
  679. Number ub_u()
  680. {
  681. return 1.;
  682. }
  683. Number alpha()
  684. {
  685. return 0.001;
  686. }
  687. Number beta()
  688. {
  689. return 1.;
  690. }
  691. inline Number y_T(Number x)
  692. {
  693. return .5*(1.-x*x);
  694. }
  695. inline Number a(Number x)
  696. {
  697. return 0.;
  698. }
  699. inline Number a_y(Number t)
  700. {
  701. return 0.;
  702. }
  703. inline Number a_u(Number t)
  704. {
  705. return 0.;
  706. }
  707. inline Number b(Number t)
  708. {
  709. return 0.;
  710. }
  711. inline Number phi(Number y)
  712. {
  713. return 0.;
  714. }
  715. inline Number phi_dy(Number y)
  716. {
  717. return 0.;
  718. }
  719. inline Number phi_dydy(Number y)
  720. {
  721. DBG_ASSERT(false);
  722. return 0.;
  723. }
  724. inline bool phi_dydy_always_zero()
  725. {
  726. return true;
  727. }
  728. };
  729. };
  730. class MittelmannParaCntrl5_2_2
  731. {
  732. public:
  733. class ProblemSpecs
  734. {
  735. public:
  736. ProblemSpecs ()
  737. {}
  738. Number T()
  739. {
  740. return 1.58;
  741. }
  742. Number l()
  743. {
  744. return 1.;
  745. }
  746. Number lb_y()
  747. {
  748. return -1e20;
  749. }
  750. Number ub_y()
  751. {
  752. return 1e20;
  753. }
  754. Number lb_u()
  755. {
  756. return -1.;
  757. }
  758. Number ub_u()
  759. {
  760. return 1.;
  761. }
  762. Number alpha()
  763. {
  764. return 0.001;
  765. }
  766. Number beta()
  767. {
  768. return 0.;
  769. }
  770. inline Number y_T(Number x)
  771. {
  772. return .5*(1.-x*x);
  773. }
  774. inline Number a(Number x)
  775. {
  776. return 0.;
  777. }
  778. inline Number a_y(Number t)
  779. {
  780. return 0.;
  781. }
  782. inline Number a_u(Number t)
  783. {
  784. return 0.;
  785. }
  786. inline Number b(Number t)
  787. {
  788. return 0.;
  789. }
  790. inline Number phi(Number y)
  791. {
  792. return y*y;
  793. }
  794. inline Number phi_dy(Number y)
  795. {
  796. return 2.*y;
  797. }
  798. inline Number phi_dydy(Number y)
  799. {
  800. return 2.;
  801. }
  802. inline bool phi_dydy_always_zero()
  803. {
  804. return false;
  805. }
  806. };
  807. };
  808. class MittelmannParaCntrl5_2_3
  809. {
  810. public:
  811. class ProblemSpecs
  812. {
  813. public:
  814. ProblemSpecs ()
  815. {}
  816. Number T()
  817. {
  818. return 1.58;
  819. }
  820. Number l()
  821. {
  822. return 1.;
  823. }
  824. Number lb_y()
  825. {
  826. return 0.;
  827. }
  828. Number ub_y()
  829. {
  830. return 0.675;
  831. }
  832. Number lb_u()
  833. {
  834. return -1.;
  835. }
  836. Number ub_u()
  837. {
  838. return 1.;
  839. }
  840. Number alpha()
  841. {
  842. return 0.001;
  843. }
  844. Number beta()
  845. {
  846. return 0.;
  847. }
  848. inline Number y_T(Number x)
  849. {
  850. return .5*(1.-x*x);
  851. }
  852. inline Number a(Number x)
  853. {
  854. return 0.;
  855. }
  856. inline Number a_y(Number t)
  857. {
  858. return 0.;
  859. }
  860. inline Number a_u(Number t)
  861. {
  862. return 0.;
  863. }
  864. inline Number b(Number t)
  865. {
  866. return 0.;
  867. }
  868. inline Number phi(Number y)
  869. {
  870. return y*y;
  871. }
  872. inline Number phi_dy(Number y)
  873. {
  874. return 2.*y;
  875. }
  876. inline Number phi_dydy(Number y)
  877. {
  878. return 2.;
  879. }
  880. inline bool phi_dydy_always_zero()
  881. {
  882. return false;
  883. }
  884. };
  885. };
  886. class MittelmannParaCntrl5_try
  887. {
  888. public:
  889. class ProblemSpecs
  890. {
  891. public:
  892. ProblemSpecs ()
  893. :
  894. pi_(4.*atan(1.)),
  895. exp13_(exp(1./3.)),
  896. exp23_(exp(2./3.)),
  897. exp1_(exp(1.)),
  898. expm1_(exp(-1.)),
  899. sqrt2_(sqrt(2.))
  900. {}
  901. Number T()
  902. {
  903. return 1.;
  904. }
  905. Number l()
  906. {
  907. return pi_/4.;
  908. }
  909. Number lb_y()
  910. {
  911. return -1e20;
  912. }
  913. Number ub_y()
  914. {
  915. return 1e20;
  916. }
  917. Number lb_u()
  918. {
  919. return 0.;
  920. }
  921. Number ub_u()
  922. {
  923. return 1.;
  924. }
  925. Number alpha()
  926. {
  927. return sqrt2_/2.*(exp23_-exp13_);
  928. }
  929. Number beta()
  930. {
  931. return 1.;
  932. }
  933. inline Number y_T(Number x)
  934. {
  935. return (exp1_ + expm1_)*cos(x);
  936. }
  937. inline Number a(Number x)
  938. {
  939. return cos(x);
  940. }
  941. inline Number a_y(Number t)
  942. {
  943. return -exp(-2.*t);
  944. }
  945. inline Number a_u(Number t)
  946. {
  947. return sqrt2_/2.*exp13_;
  948. }
  949. inline Number b(Number t)
  950. {
  951. return exp(-4.*t)/4.
  952. - Min(1.,Max(0.,(exp(t)-exp13_)/(exp23_-exp13_)));
  953. }
  954. inline Number phi(Number y)
  955. {
  956. return -y*sin(y/10.);
  957. }
  958. inline Number phi_dy(Number y)
  959. {
  960. return -y*cos(y/10.)/10. - sin(y/10.);
  961. }
  962. inline Number phi_dydy(Number y)
  963. {
  964. return y*sin(y/10.)/100.;
  965. }
  966. inline bool phi_dydy_always_zero()
  967. {
  968. return false;
  969. }
  970. private:
  971. const Number pi_;
  972. const Number exp13_;
  973. const Number exp23_;
  974. const Number exp1_;
  975. const Number expm1_;
  976. const Number sqrt2_;
  977. };
  978. };
  979. #endif