00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00034 #include <acado/objective/mayer_term.hpp>
00035
00036
00037
00038 BEGIN_NAMESPACE_ACADO
00039
00040
00041
00042
00043
00044
00045
00046
00047 MayerTerm::MayerTerm( ){ }
00048
00049
00050 MayerTerm::MayerTerm( const Grid &grid_, const Expression& arg )
00051 :ObjectiveElement(grid_){
00052
00053 fcn << arg;
00054 }
00055
00056 MayerTerm::MayerTerm( const Grid &grid_, const Function& arg )
00057 :ObjectiveElement(grid_){
00058
00059 fcn = arg;
00060 }
00061
00062 MayerTerm::MayerTerm( const MayerTerm& rhs )
00063 :ObjectiveElement(rhs){ }
00064
00065 MayerTerm::~MayerTerm( ){ }
00066
00067
00068 MayerTerm& MayerTerm::operator=( const MayerTerm& rhs ){
00069
00070 if( this != &rhs ){
00071
00072 ObjectiveElement::operator=(rhs);
00073 }
00074 return *this;
00075 }
00076
00077
00078
00079 returnValue MayerTerm::evaluate( const OCPiterate &x ){
00080
00081 ObjectiveElement::init( x );
00082
00083 z.setZ( grid.getLastIndex(), x );
00084
00085 DVector objective = fcn.evaluate( z );
00086
00087 obj = objective(0);
00088
00089 return SUCCESSFUL_RETURN;
00090 }
00091
00092
00093 returnValue MayerTerm::evaluateSensitivities( BlockMatrix *hessian ){
00094
00095 int run1, run2;
00096 const int N = grid.getNumPoints();
00097
00098 if( (bSeed != 0) & (hessian == 0) ){
00099
00100 DMatrix bseed_;
00101 bSeed->getSubBlock( 0, 0, bseed_);
00102
00103 fcn.AD_backward( bseed_.getRow(0), JJ );
00104
00105 dBackward.init( 1, 5*N );
00106
00107 DMatrix tmp1 = JJ.getX(); tmp1.transposeInPlace();
00108 if( nx > 0 ) dBackward.setDense( 0, N-1, tmp1 );
00109 DMatrix tmp2 = JJ.getXA(); tmp2.transposeInPlace();
00110 if( na > 0 ) dBackward.setDense( 0, 2*N-1, tmp2 );
00111 DMatrix tmp3 = JJ.getP(); tmp3.transposeInPlace();
00112 if( np > 0 ) dBackward.setDense( 0, 3*N-1, tmp3 );
00113 DMatrix tmp4 = JJ.getU(); tmp4.transposeInPlace();
00114 if( nu > 0 ) dBackward.setDense( 0, 4*N-1, tmp4 );
00115 DMatrix tmp5 = JJ.getW(); tmp5.transposeInPlace();
00116 if( nw > 0 ) dBackward.setDense( 0, 5*N-1, tmp5 );
00117
00118 return SUCCESSFUL_RETURN;
00119 }
00120
00121 if( hessian != 0 ){
00122
00123 double bseed1 = 1.0;
00124 double bseed2 = 0.0;
00125 double *J = new double[fcn.getNumberOfVariables() +1];
00126 double *H = new double[fcn.getNumberOfVariables() +1];
00127 double *fseed = new double[fcn.getNumberOfVariables() +1];
00128
00129 for( run1 = 0; run1 < fcn.getNumberOfVariables()+1; run1++ )
00130 fseed[run1] = 0.0;
00131
00132 dBackward.init( 1, 5*N );
00133
00134 DMatrix Dx ( 1, nx );
00135 DMatrix Dxa( 1, na );
00136 DMatrix Dp ( 1, np );
00137 DMatrix Du ( 1, nu );
00138 DMatrix Dw ( 1, nw );
00139
00140 DMatrix Hx ( nx, nx );
00141 DMatrix Hxa( nx, na );
00142 DMatrix Hp ( nx, np );
00143 DMatrix Hu ( nx, nu );
00144 DMatrix Hw ( nx, nw );
00145
00146 for( run2 = 0; run2 < nx; run2++ ){
00147
00148
00149
00150 fseed[y_index[run2]] = 1.0;
00151 fcn.AD_forward( 0, fseed, J );
00152 Dx( 0, run2 ) = J[0];
00153 fseed[y_index[run2]] = 0.0;
00154
00155
00156
00157 for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
00158 J[run1] = 0.0;
00159 H[run1] = 0.0;
00160 }
00161
00162 fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );
00163
00164 for( run1 = 0; run1 < nx; run1++ ){
00165 Hx( run2, run1 ) = H[y_index[run1]];
00166 }
00167 for( run1 = nx; run1 < nx+na; run1++ ){
00168 Hxa( run2, run1-nx ) = H[y_index[run1]];
00169 }
00170 for( run1 = nx+na; run1 < nx+na+np; run1++ ){
00171 Hp( run2, run1-nx-na ) = H[y_index[run1]];
00172 }
00173 for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
00174 Hu( run2, run1-nx-na-np ) = H[y_index[run1]];
00175 }
00176 for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
00177 Hw( run2, run1-nx-na-np-nu ) = H[y_index[run1]];
00178 }
00179 }
00180
00181 if( nx > 0 ){
00182
00183 dBackward.setDense( 0, N-1, Dx );
00184
00185 if( nx > 0 ) hessian->setDense( N-1, N-1, Hx );
00186 if( na > 0 ) hessian->setDense( N-1, 2*N-1, Hxa );
00187 if( np > 0 ) hessian->setDense( N-1, 3*N-1, Hp );
00188 if( nu > 0 ) hessian->setDense( N-1, 4*N-1, Hu );
00189 if( nw > 0 ) hessian->setDense( N-1, 5*N-1, Hw );
00190 }
00191
00192 Hx.init ( na, nx );
00193 Hxa.init( na, na );
00194 Hp.init ( na, np );
00195 Hu.init ( na, nu );
00196 Hw.init ( na, nw );
00197
00198 for( run2 = nx; run2 < nx+na; run2++ ){
00199
00200
00201
00202 fseed[y_index[run2]] = 1.0;
00203 fcn.AD_forward( 0, fseed, J );
00204 Dxa( 0, run2-nx ) = J[0];
00205 fseed[y_index[run2]] = 0.0;
00206
00207
00208
00209 for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
00210 J[run1] = 0.0;
00211 H[run1] = 0.0;
00212 }
00213
00214 fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );
00215
00216 for( run1 = 0; run1 < nx; run1++ ){
00217 Hx( run2-nx, run1 ) = H[y_index[run1]];
00218 }
00219 for( run1 = nx; run1 < nx+na; run1++ ){
00220 Hxa( run2-nx, run1-nx ) = H[y_index[run1]];
00221 }
00222 for( run1 = nx+na; run1 < nx+na+np; run1++ ){
00223 Hp( run2-nx, run1-nx-na ) = H[y_index[run1]];
00224 }
00225 for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
00226 Hu( run2-nx, run1-nx-na-np ) = H[y_index[run1]];
00227 }
00228 for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
00229 Hw( run2-nx, run1-nx-na-np-nu ) = H[y_index[run1]];
00230 }
00231 }
00232
00233 if( na > 0 ){
00234
00235 dBackward.setDense( 0, 2*N-1, Dxa );
00236
00237 if( nx > 0 ) hessian->setDense( 2*N-1, N-1, Hx );
00238 if( na > 0 ) hessian->setDense( 2*N-1, 2*N-1, Hxa );
00239 if( np > 0 ) hessian->setDense( 2*N-1, 3*N-1, Hp );
00240 if( nu > 0 ) hessian->setDense( 2*N-1, 4*N-1, Hu );
00241 if( nw > 0 ) hessian->setDense( 2*N-1, 5*N-1, Hw );
00242 }
00243
00244 Hx.init ( np, nx );
00245 Hxa.init( np, na );
00246 Hp.init ( np, np );
00247 Hu.init ( np, nu );
00248 Hw.init ( np, nw );
00249
00250 for( run2 = nx+na; run2 < nx+na+np; run2++ ){
00251
00252
00253
00254 fseed[y_index[run2]] = 1.0;
00255 fcn.AD_forward( 0, fseed, J );
00256 Dp( 0, run2-nx-na ) = J[0];
00257 fseed[y_index[run2]] = 0.0;
00258
00259
00260
00261 for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
00262 J[run1] = 0.0;
00263 H[run1] = 0.0;
00264 }
00265
00266 fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );
00267
00268 for( run1 = 0; run1 < nx; run1++ ){
00269 Hx( run2-nx-na, run1 ) = H[y_index[run1]];
00270 }
00271 for( run1 = nx; run1 < nx+na; run1++ ){
00272 Hxa( run2-nx-na, run1-nx ) = H[y_index[run1]];
00273 }
00274 for( run1 = nx+na; run1 < nx+na+np; run1++ ){
00275 Hp( run2-nx-na, run1-nx-na ) = H[y_index[run1]];
00276 }
00277 for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
00278 Hu( run2-nx-na, run1-nx-na-np ) = H[y_index[run1]];
00279 }
00280 for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
00281 Hw( run2-nx-na, run1-nx-na-np-nu ) = H[y_index[run1]];
00282 }
00283 }
00284
00285 if( np > 0 ){
00286
00287 dBackward.setDense( 0, 3*N-1, Dp );
00288
00289 if( nx > 0 ) hessian->setDense( 3*N-1, N-1, Hx );
00290 if( na > 0 ) hessian->setDense( 3*N-1, 2*N-1, Hxa );
00291 if( np > 0 ) hessian->setDense( 3*N-1, 3*N-1, Hp );
00292 if( nu > 0 ) hessian->setDense( 3*N-1, 4*N-1, Hu );
00293 if( nw > 0 ) hessian->setDense( 3*N-1, 5*N-1, Hw );
00294 }
00295
00296
00297 Hx.init ( nu, nx );
00298 Hxa.init( nu, na );
00299 Hp.init ( nu, np );
00300 Hu.init ( nu, nu );
00301 Hw.init ( nu, nw );
00302
00303 for( run2 = nx+na+np; run2 < nx+na+np+nu; run2++ ){
00304
00305
00306
00307 fseed[y_index[run2]] = 1.0;
00308 fcn.AD_forward( 0, fseed, J );
00309 Du( 0, run2-nx-na-np ) = J[0];
00310 fseed[y_index[run2]] = 0.0;
00311
00312
00313
00314 for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
00315 J[run1] = 0.0;
00316 H[run1] = 0.0;
00317 }
00318
00319 fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );
00320
00321 for( run1 = 0; run1 < nx; run1++ ){
00322 Hx( run2-nx-na-np, run1 ) = H[y_index[run1]];
00323 }
00324 for( run1 = nx; run1 < nx+na; run1++ ){
00325 Hxa( run2-nx-na-np, run1-nx ) = H[y_index[run1]];
00326 }
00327 for( run1 = nx+na; run1 < nx+na+np; run1++ ){
00328 Hp( run2-nx-na-np, run1-nx-na ) = H[y_index[run1]];
00329 }
00330 for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
00331 Hu( run2-nx-na-np, run1-nx-na-np ) = H[y_index[run1]];
00332 }
00333 for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
00334 Hw( run2-nx-na-np, run1-nx-na-np-nu ) = H[y_index[run1]];
00335 }
00336 }
00337
00338 if( nu > 0 ){
00339
00340 dBackward.setDense( 0, 4*N-1, Du );
00341
00342 if( nx > 0 ) hessian->setDense( 4*N-1, N-1, Hx );
00343 if( na > 0 ) hessian->setDense( 4*N-1, 2*N-1, Hxa );
00344 if( np > 0 ) hessian->setDense( 4*N-1, 3*N-1, Hp );
00345 if( nu > 0 ) hessian->setDense( 4*N-1, 4*N-1, Hu );
00346 if( nw > 0 ) hessian->setDense( 4*N-1, 5*N-1, Hw );
00347 }
00348
00349
00350 Hx.init ( nw, nx );
00351 Hxa.init( nw, na );
00352 Hp.init ( nw, np );
00353 Hu.init ( nw, nu );
00354 Hw.init ( nw, nw );
00355
00356 for( run2 = nx+na+np+nu; run2 < nx+na+np+nu+nw; run2++ ){
00357
00358
00359
00360 fseed[y_index[run2]] = 1.0;
00361 fcn.AD_forward( 0, fseed, J );
00362 Dw( 0, run2-nx-na-np-nu ) = J[0];
00363 fseed[y_index[run2]] = 0.0;
00364
00365
00366
00367 for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
00368 J[run1] = 0.0;
00369 H[run1] = 0.0;
00370 }
00371
00372 fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );
00373
00374 for( run1 = 0; run1 < nx; run1++ ){
00375 Hx( run2-nx-na-np-nu, run1 ) = H[y_index[run1]];
00376 }
00377 for( run1 = nx; run1 < nx+na; run1++ ){
00378 Hxa( run2-nx-na-np-nu, run1-nx ) = H[y_index[run1]];
00379 }
00380 for( run1 = nx+na; run1 < nx+na+np; run1++ ){
00381 Hp( run2-nx-na-np-nu, run1-nx-na ) = H[y_index[run1]];
00382 }
00383 for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
00384 Hu( run2-nx-na-np-nu, run1-nx-na-np ) = H[y_index[run1]];
00385 }
00386 for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
00387 Hw( run2-nx-na-np-nu, run1-nx-na-np-nu ) = H[y_index[run1]];
00388 }
00389 }
00390
00391 if( nw > 0 ){
00392
00393 dBackward.setDense( 0, 5*N-1, Dw );
00394
00395 if( nx > 0 ) hessian->setDense( 5*N-1, N-1, Hx );
00396 if( na > 0 ) hessian->setDense( 5*N-1, 2*N-1, Hxa );
00397 if( np > 0 ) hessian->setDense( 5*N-1, 3*N-1, Hp );
00398 if( nu > 0 ) hessian->setDense( 5*N-1, 4*N-1, Hu );
00399 if( nw > 0 ) hessian->setDense( 5*N-1, 5*N-1, Hw );
00400 }
00401
00402 delete[] J;
00403 delete[] H;
00404 delete[] fseed;
00405
00406 return SUCCESSFUL_RETURN;
00407 }
00408
00409 return ACADOERROR(RET_NOT_IMPLEMENTED_YET);
00410 }
00411
00412
00413
00414
00415
00416 CLOSE_NAMESPACE_ACADO
00417
00418