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
00034 #include <acado/nlp_solver/scp_evaluation.hpp>
00035
00036
00037
00038 BEGIN_NAMESPACE_ACADO
00039
00040
00041
00042
00043
00044
00045 SCPevaluation::SCPevaluation( ) : AlgorithmicBase( )
00046 {
00047 setupOptions( );
00048 setupLogging( );
00049
00050 objective = 0;
00051 dynamicDiscretization = 0;
00052 constraint = 0;
00053
00054 objectiveValue = 0.0;
00055
00056 isCP = BT_FALSE;
00057 areSensitivitiesFrozen = BT_FALSE;
00058 }
00059
00060
00061 SCPevaluation::SCPevaluation( UserInteraction* _userInteraction,
00062 const Objective* const objective_,
00063 const DynamicDiscretization* const dynamic_discretization_,
00064 const Constraint* const constraint_,
00065 BooleanType _isCP
00066 ) : AlgorithmicBase( _userInteraction )
00067 {
00068
00069 if ( _userInteraction == 0 )
00070 {
00071 setupOptions( );
00072 setupLogging( );
00073 }
00074
00075 if( objective_ != 0 ) objective = new Objective( *objective_ );
00076 else objective = 0;
00077
00078 if( dynamic_discretization_ != 0 ) dynamicDiscretization = dynamic_discretization_->clone();
00079 else dynamicDiscretization = 0;
00080
00081 if( constraint_ != 0 ) constraint = new Constraint( *constraint_ );
00082 else constraint = 0;
00083
00084 objectiveValue = 0.0;
00085
00086 isCP = _isCP;
00087 areSensitivitiesFrozen = BT_FALSE;
00088 }
00089
00090
00091 SCPevaluation::SCPevaluation( const SCPevaluation& rhs ) : AlgorithmicBase( rhs )
00092 {
00093 if( rhs.objective != 0 ) objective = new Objective( *rhs.objective );
00094 else objective = 0;
00095
00096 if( rhs.dynamicDiscretization != 0 ) dynamicDiscretization = rhs.dynamicDiscretization->clone();
00097 else dynamicDiscretization = 0;
00098
00099 if( rhs.constraint != 0 ) constraint = new Constraint( *rhs.constraint );
00100 else constraint = 0;
00101
00102 objectiveValue = rhs.objectiveValue;
00103
00104 isCP = rhs.isCP;
00105 areSensitivitiesFrozen = rhs.areSensitivitiesFrozen;
00106 }
00107
00108
00109 SCPevaluation::~SCPevaluation( )
00110 {
00111 if( objective != 0 ) delete objective;
00112 if( dynamicDiscretization != 0 ) delete dynamicDiscretization;
00113 if( constraint != 0 ) delete constraint;
00114 }
00115
00116
00117 SCPevaluation& SCPevaluation::operator=( const SCPevaluation& rhs )
00118 {
00119 if ( this != &rhs )
00120 {
00121 if( objective != 0 ) delete objective;
00122 if( dynamicDiscretization != 0 ) delete dynamicDiscretization;
00123 if( constraint != 0 ) delete constraint;
00124
00125 AlgorithmicBase::operator=( rhs );
00126
00127 if( rhs.objective != 0 ) objective = new Objective( *rhs.objective );
00128 else objective = 0;
00129
00130 if( rhs.dynamicDiscretization != 0 ) dynamicDiscretization = rhs.dynamicDiscretization->clone( );
00131 else dynamicDiscretization = 0;
00132
00133 if( rhs.constraint != 0 ) constraint = new Constraint( *rhs.constraint );
00134 else constraint = 0;
00135
00136 objectiveValue = rhs.objectiveValue;
00137
00138 isCP = rhs.isCP;
00139 areSensitivitiesFrozen = rhs.areSensitivitiesFrozen;
00140 }
00141
00142 return *this;
00143 }
00144
00145
00146 SCPevaluation* SCPevaluation::clone( ) const
00147 {
00148 return new SCPevaluation( *this );
00149 }
00150
00151
00152
00153 returnValue SCPevaluation::init( const OCPiterate& iter
00154 ){
00155
00156 return SUCCESSFUL_RETURN;
00157 }
00158
00159
00160
00161 returnValue SCPevaluation::evaluate( OCPiterate& iter, BandedCP& cp ){
00162
00163
00164
00165 if( dynamicDiscretization != 0 )
00166 ACADO_TRY( dynamicDiscretization->evaluate( iter ) ).changeType( RET_UNABLE_TO_INTEGRATE_SYSTEM );
00167
00168 if( constraint != 0 )
00169 ACADO_TRY( constraint->evaluate( iter ) ).changeType( RET_UNABLE_TO_EVALUATE_CONSTRAINTS );
00170
00171 ACADO_TRY( objective->evaluate(iter) ).changeType( RET_UNABLE_TO_EVALUATE_OBJECTIVE );
00172
00173
00174 objective->getObjectiveValue( objectiveValue );
00175
00176 if( dynamicDiscretization != 0 )
00177 dynamicDiscretization->getResiduum( cp.dynResiduum );
00178
00179 if( constraint != 0 )
00180 {
00181 constraint->getBoundResiduum ( cp.lowerBoundResiduum , cp.upperBoundResiduum );
00182 constraint->getConstraintResiduum( cp.lowerConstraintResiduum, cp.upperConstraintResiduum );
00183 }
00184
00185 if( dynamicDiscretization == 0 ){
00186 cp.lowerBoundResiduum.setZero(0,0);
00187 cp.lowerBoundResiduum.setZero(1,0);
00188 cp.lowerBoundResiduum.setZero(3,0);
00189 cp.lowerBoundResiduum.setZero(4,0);
00190 cp.upperBoundResiduum.setZero(0,0);
00191 cp.upperBoundResiduum.setZero(1,0);
00192 cp.upperBoundResiduum.setZero(3,0);
00193 cp.upperBoundResiduum.setZero(4,0);
00194 }
00195
00196 return SUCCESSFUL_RETURN;
00197 }
00198
00199
00200
00201 returnValue SCPevaluation::evaluateSensitivities( const OCPiterate& iter,
00202 BandedCP& cp
00203 )
00204 {
00205 if ( areSensitivitiesFrozen == BT_TRUE )
00206 return SUCCESSFUL_RETURN;
00207
00208
00209
00210
00211 int hessMode;
00212 get( HESSIAN_APPROXIMATION, hessMode );
00213
00214 int dynHessMode;
00215 get( DYNAMIC_HESSIAN_APPROXIMATION, dynHessMode );
00216 if ( (HessianApproximationMode)dynHessMode == DEFAULT_HESSIAN_APPROXIMATION )
00217 dynHessMode = hessMode;
00218
00219 int dynMode;
00220 get( DYNAMIC_SENSITIVITY, dynMode );
00221
00222 int objMode;
00223 get( OBJECTIVE_SENSITIVITY, objMode );
00224
00225 int conMode;
00226 get( CONSTRAINT_SENSITIVITY, conMode );
00227
00228
00229
00230
00231
00232 objective->setUnitBackwardSeed( );
00233 if( ( (HessianApproximationMode)hessMode == GAUSS_NEWTON ) || ( (HessianApproximationMode)hessMode == GAUSS_NEWTON_WITH_BLOCK_BFGS ) )
00234 objective->evaluateSensitivitiesGN( cp.hessian );
00235 else{
00236 if( (HessianApproximationMode)hessMode == EXACT_HESSIAN ){
00237 cp.hessian.setZero();
00238 objective->evaluateSensitivities( cp.hessian );
00239 }
00240 else objective->evaluateSensitivities();
00241 }
00242
00243
00244 objective->getBackwardSensitivities( cp.objectiveGradient, 1 );
00245
00246
00247
00248
00249
00250 if( dynamicDiscretization != 0 ){
00251
00252 if( (HessianApproximationMode)dynHessMode == EXACT_HESSIAN ){
00253
00254 ACADO_TRY( dynamicDiscretization->setUnitForwardSeed() );
00255 ACADO_TRY( dynamicDiscretization->evaluateSensitivities( cp.lambdaDynamic, cp.hessian ) );
00256 ACADO_TRY( dynamicDiscretization->getForwardSensitivities( cp.dynGradient ) );
00257 }
00258 else{
00259 if( dynMode == BACKWARD_SENSITIVITY ){
00260
00261 ACADO_TRY( dynamicDiscretization->setUnitBackwardSeed() );
00262 ACADO_TRY( dynamicDiscretization->evaluateSensitivities() );
00263 ACADO_TRY( dynamicDiscretization->getBackwardSensitivities( cp.dynGradient ) );
00264 }
00265 if( dynMode == FORWARD_SENSITIVITY ){
00266
00267 ACADO_TRY( dynamicDiscretization->setUnitForwardSeed() );
00268 ACADO_TRY( dynamicDiscretization->evaluateSensitivities() );
00269 ACADO_TRY( dynamicDiscretization->getForwardSensitivities( cp.dynGradient ) );
00270 }
00271 if( dynMode == FORWARD_SENSITIVITY_LIFTED ){
00272
00273 ACADO_TRY( dynamicDiscretization->setUnitForwardSeed() );
00274 ACADO_TRY( dynamicDiscretization->evaluateSensitivitiesLifted() );
00275 ACADO_TRY( dynamicDiscretization->getForwardSensitivities( cp.dynGradient ) );
00276 }
00277 }
00278 }
00279
00280
00281
00282
00283 if( constraint != 0 ){
00284
00285 if( (HessianApproximationMode)hessMode == EXACT_HESSIAN ){
00286
00287 constraint->setUnitBackwardSeed();
00288 constraint->evaluateSensitivities( cp.lambdaConstraint, cp.hessian );
00289 constraint->getBackwardSensitivities( cp.constraintGradient, 1 );
00290 }
00291 else{
00292 if( conMode == BACKWARD_SENSITIVITY ){
00293 constraint->setUnitBackwardSeed();
00294 constraint->evaluateSensitivities( );
00295 constraint->getBackwardSensitivities( cp.constraintGradient, 1 );
00296 }
00297 if( conMode == FORWARD_SENSITIVITY ){
00298 constraint->setUnitForwardSeed();
00299 constraint->evaluateSensitivities( );
00300 constraint->getForwardSensitivities( cp.constraintGradient, 1 );
00301 }
00302 }
00303 }
00304
00305 return SUCCESSFUL_RETURN;
00306 }
00307
00308
00309
00310 returnValue SCPevaluation::evaluateLagrangeGradient( uint N,
00311 const OCPiterate& iter,
00312 const BandedCP& cp,
00313 BlockMatrix &nablaL
00314 )
00315 {
00316 uint run1;
00317 DMatrix tmp1, tmp2;
00318 BlockMatrix aux( 5*N, 1 );
00319
00320 for( run1 = 0; run1 < N-1; run1++ ){
00321
00322 if( run1 < N-1 ) cp.lambdaDynamic.getSubBlock( run1, 0, tmp1, iter.getNX(), 1 );
00323
00324 if( iter.getNX() != 0 ){
00325 cp.dynGradient.getSubBlock( run1, 0, tmp2, iter.getNX(), iter.getNX() );
00326 aux.addDense( run1 , 0, tmp2.transpose() * tmp1 );
00327 aux.setDense( run1+1, 0, -tmp1 );
00328 }
00329 if( iter.getNXA() != 0 ){
00330 cp.dynGradient.getSubBlock( run1, 1, tmp2, iter.getNX(), iter.getNXA() );
00331 aux.setDense( N+run1, 0, tmp2.transpose() * tmp1 );
00332 }
00333 if( iter.getNP() != 0 ){
00334 cp.dynGradient.getSubBlock( run1, 2, tmp2, iter.getNX(), iter.getNP() );
00335 aux.setDense( 2*N+run1, 0, tmp2.transpose() * tmp1 );
00336 }
00337 if( iter.getNU() != 0 ){
00338 cp.dynGradient.getSubBlock( run1, 3, tmp2, iter.getNX(), iter.getNU() );
00339 aux.setDense( 3*N+run1, 0, tmp2.transpose() * tmp1 );
00340 }
00341 if( iter.getNW() != 0 ){
00342 cp.dynGradient.getSubBlock( run1, 4, tmp2, iter.getNX(), iter.getNW() );
00343 aux.setDense( 4*N+run1, 0, tmp2.transpose() * tmp1 );
00344 }
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 if( dynamicDiscretization != 0 ){
00356
00357 BlockMatrix lambdaBoundExpand(5*N,1);
00358 for( run1 = 0; run1 < N; run1++ ){
00359
00360 cp.lambdaBound.getSubBlock(run1,0,tmp1);
00361 if( tmp1.getDim() != 0 )
00362 lambdaBoundExpand.setDense(run1,0,tmp1);
00363
00364 cp.lambdaBound.getSubBlock(N+run1,0,tmp1);
00365 if( tmp1.getDim() != 0 )
00366 lambdaBoundExpand.setDense(N+run1,0,tmp1);
00367
00368 cp.lambdaBound.getSubBlock(2*N,0,tmp1);
00369 if( tmp1.getDim() != 0 )
00370 lambdaBoundExpand.setDense(2*N+run1,0,tmp1);
00371
00372 cp.lambdaBound.getSubBlock(2*N+1+run1,0,tmp1);
00373 if( tmp1.getDim() != 0 )
00374 lambdaBoundExpand.setDense(3*N+run1,0,tmp1);
00375
00376 cp.lambdaBound.getSubBlock(3*N+1+run1,0,tmp1);
00377 if( tmp1.getDim() != 0 )
00378 lambdaBoundExpand.setDense(4*N+run1,0,tmp1);
00379 }
00380
00381 nablaL = cp.objectiveGradient.transpose() - lambdaBoundExpand - (cp.constraintGradient^cp.lambdaConstraint) + aux;
00382 }
00383 else{
00384 BlockMatrix lambdaBoundExpand(5,1);
00385 cp.lambdaBound.getSubBlock(1,0,tmp1);
00386 if( tmp1.getDim() != 0 )
00387 lambdaBoundExpand.setDense(2,0,tmp1);
00388 nablaL = cp.objectiveGradient.transpose() - lambdaBoundExpand - (cp.constraintGradient^cp.lambdaConstraint);
00389 }
00390
00391 return SUCCESSFUL_RETURN;
00392 }
00393
00394
00395
00396 double SCPevaluation::getKKTtolerance( const OCPiterate& iter,
00397 const BandedCP& cp,
00398 double KKTmultiplierRegularisation
00399 )
00400 {
00401
00402
00403
00404 double KKTtol = 0.0;
00405 double eps = 0.0;
00406
00407 DMatrix tmp;
00408
00409
00410
00411
00412
00413
00414
00415 int hessianApproximation;
00416 get( HESSIAN_APPROXIMATION,hessianApproximation );
00417
00418 if ( ( isCP == BT_FALSE ) ||
00419 ( ( (HessianApproximationMode)hessianApproximation != GAUSS_NEWTON ) && ( (HessianApproximationMode)hessianApproximation != GAUSS_NEWTON_WITH_BLOCK_BFGS ) )
00420 )
00421 {
00422 eps = KKTmultiplierRegularisation;
00423
00424 (cp.objectiveGradient*cp.deltaX).getSubBlock( 0, 0, tmp, 1, 1 );
00425
00426 KKTtol = fabs(tmp(0,0));
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 if( dynamicDiscretization != 0 )
00440 {
00441 ( (cp.lambdaDynamic.getAbsolute()).addRegularisation(eps)^cp.dynResiduum.getAbsolute()).getSubBlock( 0, 0, tmp, 1, 1 );
00442 KKTtol += tmp(0,0);
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 ((cp.lambdaBound.getAbsolute()).addRegularisation(eps)^cp.upperBoundResiduum.getNegative()).getSubBlock( 0, 0, tmp, 1, 1 );
00459 KKTtol -= tmp(0,0);
00460
00461 ((cp.lambdaBound.getAbsolute()).addRegularisation(eps)^cp.lowerBoundResiduum.getPositive()).getSubBlock( 0, 0, tmp, 1, 1 );
00462 KKTtol += tmp(0,0);
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 if( ( constraint != 0 ) || ( dynamicDiscretization != 0 ) )
00478 {
00479 ((cp.lambdaConstraint.getAbsolute()).addRegularisation(eps)^cp.upperConstraintResiduum.getNegative()).getSubBlock( 0, 0, tmp, 1, 1 );
00480 KKTtol -= tmp(0,0);
00481
00482 ((cp.lambdaConstraint.getAbsolute()).addRegularisation(eps)^cp.lowerConstraintResiduum.getPositive()).getSubBlock( 0, 0, tmp, 1, 1 );
00483 KKTtol += tmp(0,0);
00484 }
00485
00486
00487
00488
00489
00490 return KKTtol;
00491 }
00492
00493
00494
00495
00496 double SCPevaluation::getObjectiveValue( ) const
00497 {
00498 return objectiveValue;
00499 }
00500
00501
00502
00503 returnValue SCPevaluation::freezeSensitivities( )
00504 {
00505 areSensitivitiesFrozen = BT_TRUE;
00506 return SUCCESSFUL_RETURN;
00507 }
00508
00509
00510 returnValue SCPevaluation::unfreezeSensitivities( )
00511 {
00512 areSensitivitiesFrozen = BT_FALSE;
00513 return SUCCESSFUL_RETURN;
00514 }
00515
00516
00517
00518 returnValue SCPevaluation::setReference( const VariablesGrid &ref )
00519 {
00520 if( objective == 0 )
00521 return ACADOERROR(RET_MEMBER_NOT_INITIALISED);
00522
00523
00524
00525 if( objective->setReference( ref ) != SUCCESSFUL_RETURN )
00526 return ACADOERROR( RET_UNKNOWN_BUG );
00527
00528 return SUCCESSFUL_RETURN;
00529 }
00530
00531
00532
00533 returnValue SCPevaluation::clearDynamicDiscretization( )
00534 {
00535 if( dynamicDiscretization != 0 )
00536 {
00537 dynamicDiscretization->unfreeze( );
00538 dynamicDiscretization->deleteAllSeeds( );
00539 }
00540
00541 return SUCCESSFUL_RETURN;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551 returnValue SCPevaluation::setupOptions( )
00552 {
00553 return SUCCESSFUL_RETURN;
00554 }
00555
00556
00557 returnValue SCPevaluation::setupLogging( )
00558 {
00559 return SUCCESSFUL_RETURN;
00560 }
00561
00562
00563
00564 CLOSE_NAMESPACE_ACADO
00565
00566