scp_evaluation.cpp
Go to the documentation of this file.
00001 /*
00002  *    This file is part of ACADO Toolkit.
00003  *
00004  *    ACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.
00005  *    Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,
00006  *    Milan Vukov, Rien Quirynen, KU Leuven.
00007  *    Developed within the Optimization in Engineering Center (OPTEC)
00008  *    under supervision of Moritz Diehl. All rights reserved.
00009  *
00010  *    ACADO Toolkit is free software; you can redistribute it and/or
00011  *    modify it under the terms of the GNU Lesser General Public
00012  *    License as published by the Free Software Foundation; either
00013  *    version 3 of the License, or (at your option) any later version.
00014  *
00015  *    ACADO Toolkit is distributed in the hope that it will be useful,
00016  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  *    Lesser General Public License for more details.
00019  *
00020  *    You should have received a copy of the GNU Lesser General Public
00021  *    License along with ACADO Toolkit; if not, write to the Free Software
00022  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023  *
00024  */
00025 
00026 
00034 #include <acado/nlp_solver/scp_evaluation.hpp>
00035 
00036 
00037 
00038 BEGIN_NAMESPACE_ACADO
00039 
00040 
00041 //
00042 // PUBLIC MEMBER FUNCTIONS:
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         // setup options and loggings for stand-alone instances
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     // EVALUATE THE OBJECTIVE AND CONSTRAINTS:
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     // DETERMINE THE HESSIAN APPROXIMATION MODE:
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     // COMPUTE THE 1st ORDER DERIVATIVES:
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 //      printf("cp.hessian = \n");
00248 //     cp.hessian.print();
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 //      printf("cp.dynGradient = \n");
00281 // (cp.dynGradient).print();
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 //     printf("aux = \n");
00348 //     aux.print();
00349 //
00350 //    cp.objectiveGradient.print();
00351 //     (cp.objectiveGradient.transpose()).print();
00352 //     lambdaBound.print();
00353 //     (cp.constraintGradient^cp.lambdaConstraint).print();
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 //     printf("get KKT tolerance. \n \n");
00403 
00404     double KKTtol = 0.0;
00405         double eps = 0.0;
00406 
00407     DMatrix tmp;
00408 
00409 //     printf("obj Gradient \n");
00410 //     cp.objectiveGradient.print();
00411 // 
00412 //     printf("cp.deltaX \n");
00413 //     cp.deltaX.print();
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 //              (cp.objectiveGradient*cp.deltaX).print();
00426                 KKTtol = fabs(tmp(0,0));
00427         }
00428 
00429     // --------
00430 
00431 //     printf("lambda Dynamic \n");
00432 //     cp.lambdaDynamic.print();
00433 // 
00434 //     printf("dynamic residuum \n");
00435 //     cp.dynResiduum.print();
00436 //       printf("interm. = %.16e \n", KKTtol );
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 //     printf("cp.lowerBoundResiduum \n");
00448 //     cp.lowerBoundResiduum.print();
00449 // 
00450 //     printf("cp.upperBoundResiduum \n");
00451 //     cp.upperBoundResiduum.print();
00452 
00453 //     printf("cp.lambdaBound \n");
00454 //     cp.lambdaBound.print();
00455 // 
00456 //        printf("interm. = %.16e \n", KKTtol );
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 //     printf("cp.lowerConstraintResiduum \n");
00468 //     cp.lowerConstraintResiduum.print();
00469 // 
00470 //     printf("cp.upperConstraintResiduum \n");
00471 //     cp.upperConstraintResiduum.print();
00472 // 
00473 //     printf("cp.lambdaConstraint = \n");
00474 //     cp.lambdaConstraint.print();
00475 //       printf("interm. = %.16e \n", KKTtol );
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 //         printf("interm. = %.16e \n", KKTtol );
00487 
00488 //ASSERT( 1 == 0 );
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 //      ref.print("ref");
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 // PROTECTED MEMBER FUNCTIONS:
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 // end of file.


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Thu Aug 27 2015 11:59:57