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_derivative_approximation/bfgs_update.hpp>
00035
00036
00037
00038 BEGIN_NAMESPACE_ACADO
00039
00040
00041
00042
00043
00044
00045 BFGSupdate::BFGSupdate( ) : ConstantHessian( )
00046 {
00047 modification = MOD_POWELLS_MODIFICATION;
00048 nBlocks = 0;
00049 }
00050
00051
00052 BFGSupdate::BFGSupdate( UserInteraction* _userInteraction,
00053 uint _nBlocks
00054 ) : ConstantHessian( _userInteraction )
00055 {
00056 modification = MOD_POWELLS_MODIFICATION;
00057 nBlocks = _nBlocks;
00058 }
00059
00060
00061 BFGSupdate::BFGSupdate( const BFGSupdate& rhs ) : ConstantHessian( rhs )
00062 {
00063 modification = rhs.modification;
00064 nBlocks = rhs.nBlocks;
00065 }
00066
00067
00068 BFGSupdate::~BFGSupdate( )
00069 {
00070 }
00071
00072
00073 BFGSupdate& BFGSupdate::operator=( const BFGSupdate& rhs )
00074 {
00075 if ( this != &rhs )
00076 {
00077 ConstantHessian::operator=( rhs );
00078
00079 modification = rhs.modification;
00080 nBlocks = rhs.nBlocks;
00081 }
00082
00083 return *this;
00084 }
00085
00086
00087 NLPderivativeApproximation* BFGSupdate::clone( ) const
00088 {
00089 return new BFGSupdate( *this );
00090 }
00091
00092
00093
00094 returnValue BFGSupdate::initHessian( BlockMatrix& B,
00095 uint N,
00096 const OCPiterate& iter
00097 )
00098 {
00099 return ConstantHessian::initHessian( B,N,iter );
00100 }
00101
00102
00103 returnValue BFGSupdate::initScaling( BlockMatrix& B,
00104 const BlockMatrix& x,
00105 const BlockMatrix& y
00106 )
00107 {
00108 return ConstantHessian::initScaling( B,x,y );
00109 }
00110
00111
00112
00113 returnValue BFGSupdate::apply( BlockMatrix &B,
00114 const BlockMatrix &x,
00115 const BlockMatrix &y
00116 )
00117 {
00118 if ( performsBlockUpdates( ) == BT_TRUE )
00119 return applyBlockDiagonalUpdate( B,x,y );
00120 else
00121 return applyUpdate( B,x,y );
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 returnValue BFGSupdate::applyUpdate( BlockMatrix &B,
00131 const BlockMatrix &x,
00132 const BlockMatrix &y
00133 )
00134 {
00135
00136
00137 const double epsilon = 0.2;
00138
00139 double theta = 1.0;
00140
00141
00142
00143
00144 const double regularisation = 100.0*EPS;
00145
00146
00147
00148
00149
00150 BlockMatrix Bx ;
00151 BlockMatrix BxxB;
00152 DMatrix xBx ;
00153 DMatrix xy ;
00154 BlockMatrix z ;
00155 double xz = 0.0;
00156 BlockMatrix zz ;
00157
00158
00159
00160
00161 Bx = B*x;
00162 (x^Bx).getSubBlock( 0, 0, xBx, 1, 1 );
00163 (y^x ).getSubBlock( 0, 0, xy , 1, 1 );
00164 BxxB = Bx*Bx.transpose();
00165
00166
00167
00168
00169 if( xy(0,0) > epsilon*xBx(0,0) ){
00170
00171 z = y ;
00172 xz = xy(0,0);
00173 }
00174 else{
00175
00176 switch( modification ){
00177
00178 case MOD_NO_MODIFICATION :
00179
00180 z = y ;
00181 xz = xy(0,0);
00182 break;
00183
00184
00185 case MOD_NOCEDALS_MODIFICATION:
00186
00187 return SUCCESSFUL_RETURN;
00188
00189
00190 case MOD_POWELLS_MODIFICATION:
00191
00192 theta = (1.0-epsilon)*xBx(0,0)/
00193 (xBx(0,0)-xy(0,0)+regularisation);
00194
00195 z = y ;
00196 z *= theta ;
00197 Bx *= (1.0-theta) ;
00198 z += Bx ;
00199 xz = epsilon*xBx(0,0);
00200 break;
00201 }
00202 }
00203
00204 zz = z*z.transpose();
00205
00206 BxxB *= 1.0/(xBx(0,0) + regularisation);
00207 zz *= 1.0/(xz + regularisation);
00208
00209
00210
00211
00212
00213 B += zz - BxxB;
00214
00215 return SUCCESSFUL_RETURN;
00216 }
00217
00218
00219 returnValue BFGSupdate::applyBlockDiagonalUpdate( BlockMatrix &B,
00220 const BlockMatrix &x,
00221 const BlockMatrix &y
00222 )
00223 {
00224 int run1;
00225 BlockMatrix a(5,1), b(5,1);
00226 BlockMatrix block(5,5);
00227
00228 for( run1 = 0; run1 < (int)nBlocks; run1++ ){
00229
00230 a.setZero();
00231 b.setZero();
00232 block.setZero();
00233
00234 getSubBlockLine( nBlocks, 0, 0, run1, x, a );
00235 getSubBlockLine( nBlocks, 0, 0, run1, y, b );
00236
00237 getSubBlockLine( nBlocks, run1, 0, run1, B, block );
00238 getSubBlockLine( nBlocks, nBlocks+run1, 1, run1, B, block );
00239 getSubBlockLine( nBlocks, 2*nBlocks+run1, 2, run1, B, block );
00240 getSubBlockLine( nBlocks, 3*nBlocks+run1, 3, run1, B, block );
00241 getSubBlockLine( nBlocks, 4*nBlocks+run1, 4, run1, B, block );
00242
00243 applyUpdate( block, a, b );
00244
00245 setSubBlockLine( nBlocks, run1, 0, run1, B, block );
00246 setSubBlockLine( nBlocks, nBlocks+run1, 1, run1, B, block );
00247 setSubBlockLine( nBlocks, 2*nBlocks+run1, 2, run1, B, block );
00248 setSubBlockLine( nBlocks, 3*nBlocks+run1, 3, run1, B, block );
00249 setSubBlockLine( nBlocks, 4*nBlocks+run1, 4, run1, B, block );
00250 }
00251
00252 return SUCCESSFUL_RETURN;
00253 }
00254
00255
00256
00257 returnValue BFGSupdate::getSubBlockLine( const int &N ,
00258 const int &line1 ,
00259 const int &line2 ,
00260 const int &offset,
00261 const BlockMatrix &M ,
00262 BlockMatrix &O )
00263 {
00264 DMatrix tmp;
00265
00266 M.getSubBlock( offset, line1, tmp );
00267 if( tmp.getDim() != 0 ) O.setDense(0,line2,tmp);
00268
00269 M.getSubBlock( N+offset, line1, tmp );
00270 if( tmp.getDim() != 0 ) O.setDense(1,line2,tmp);
00271
00272 M.getSubBlock( 2*N+offset, line1, tmp );
00273 if( tmp.getDim() != 0 ) O.setDense(2,line2,tmp);
00274
00275 M.getSubBlock( 3*N+offset, line1, tmp );
00276 if( tmp.getDim() != 0 ) O.setDense(3,line2,tmp);
00277
00278 M.getSubBlock( 4*N+offset, line1, tmp );
00279 if( tmp.getDim() != 0 ) O.setDense(4,line2,tmp);
00280
00281 return SUCCESSFUL_RETURN;
00282 }
00283
00284
00285 returnValue BFGSupdate::setSubBlockLine( const int &N ,
00286 const int &line1 ,
00287 const int &line2 ,
00288 const int &offset,
00289 BlockMatrix &M ,
00290 const BlockMatrix &O )
00291 {
00292 DMatrix tmp;
00293
00294 O.getSubBlock( 0, line2, tmp );
00295
00296 if( tmp.getDim() != 0 ) M.setDense( offset, line1, tmp );
00297 O.getSubBlock( 1, line2, tmp );
00298 if( tmp.getDim() != 0 ) M.setDense( N+offset, line1, tmp );
00299
00300 O.getSubBlock(2,line2,tmp);
00301 if( tmp.getDim() != 0 ) M.setDense( 2*N+offset, line1, tmp );
00302
00303 O.getSubBlock(3,line2,tmp);
00304 if( tmp.getDim() != 0 ) M.setDense( 3*N+offset, line1, tmp );
00305
00306 O.getSubBlock(4,line2,tmp);
00307 if( tmp.getDim() != 0 ) M.setDense( 4*N+offset, line1, tmp );
00308
00309 return SUCCESSFUL_RETURN;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 CLOSE_NAMESPACE_ACADO
00325
00326