bfgs_update.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ACADO Toolkit.
3  *
4  * ACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.
5  * Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,
6  * Milan Vukov, Rien Quirynen, KU Leuven.
7  * Developed within the Optimization in Engineering Center (OPTEC)
8  * under supervision of Moritz Diehl. All rights reserved.
9  *
10  * ACADO Toolkit is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 3 of the License, or (at your option) any later version.
14  *
15  * ACADO Toolkit is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with ACADO Toolkit; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  *
24  */
25 
26 
35 
36 
37 
39 
40 
41 //
42 // PUBLIC MEMBER FUNCTIONS:
43 //
44 
46 {
48  nBlocks = 0;
49 }
50 
51 
53  uint _nBlocks
54  ) : ConstantHessian( _userInteraction )
55 {
57  nBlocks = _nBlocks;
58 }
59 
60 
62 {
64  nBlocks = rhs.nBlocks;
65 }
66 
67 
69 {
70 }
71 
72 
74 {
75  if ( this != &rhs )
76  {
78 
80  nBlocks = rhs.nBlocks;
81  }
82 
83  return *this;
84 }
85 
86 
88 {
89  return new BFGSupdate( *this );
90 }
91 
92 
93 
95  uint N,
96  const OCPiterate& iter
97  )
98 {
99  return ConstantHessian::initHessian( B,N,iter );
100 }
101 
102 
104  const BlockMatrix& x,
105  const BlockMatrix& y
106  )
107 {
108  return ConstantHessian::initScaling( B,x,y );
109 }
110 
111 
112 
114  const BlockMatrix &x,
115  const BlockMatrix &y
116  )
117 {
118  if ( performsBlockUpdates( ) == BT_TRUE )
119  return applyBlockDiagonalUpdate( B,x,y );
120  else
121  return applyUpdate( B,x,y );
122 }
123 
124 
125 
126 //
127 // PROTECTED MEMBER FUNCTIONS:
128 //
129 
131  const BlockMatrix &x,
132  const BlockMatrix &y
133  )
134 {
135  // CONSTANTS FOR POWELL'S STRATEGY:
136  // --------------------------------
137  const double epsilon = 0.2; // constant epsilon for a positive curvature
138  // check of the form x^T y > epsilon x^T B x
139  double theta = 1.0; // constant theta for Powell's strategy.
140 
141 
142  // OTHER CONSTANTS:
143  // ----------------
144  const double regularisation = 100.0*EPS; // safe-guard constant for devisions
145  // (to avoid numerical devision by 0).
146 
147 
148  // DEFINITTIONS:
149  // -------------- -------------------------------------------------------
150  BlockMatrix Bx ; // the vector B*x.
151  BlockMatrix BxxB; // the matrix B*x*x^T*B
152  DMatrix xBx ; // the scalar x^T B x
153  DMatrix xy ; // the scalar x^T y
154  BlockMatrix z ; // the modified "gradient" y (needed for Powell's strategy)
155  double xz = 0.0; // the scalar x^T z
156  BlockMatrix zz ; // the matrix z*z^T
157 
158 
159  // COMPUTATION OF Bx, xBx, xy AND BxxB:
160  // -------------------------------------
161  Bx = B*x;
162  (x^Bx).getSubBlock( 0, 0, xBx, 1, 1 );
163  (y^x ).getSubBlock( 0, 0, xy , 1, 1 );
164  BxxB = Bx*Bx.transpose();
165 
166 
167  // CURVATURE CHECK:
168  // -------------------------------------
169  if( xy(0,0) > epsilon*xBx(0,0) ){
170 
171  z = y ; // do not modify z if x^T y > epsilon x^T B x
172  xz = xy(0,0); // in this case we have x^T z = x^T y.
173  }
174  else{
175 
176  switch( modification ){
177 
178  case MOD_NO_MODIFICATION : // In this case no modification is applied
179  // and B might become indefinite after the update
180  z = y ;
181  xz = xy(0,0);
182  break;
183 
184 
185  case MOD_NOCEDALS_MODIFICATION: // just skip the update
186 
187  return SUCCESSFUL_RETURN;
188 
189 
190  case MOD_POWELLS_MODIFICATION: // apply Powell's modification of y
191 
192  theta = (1.0-epsilon)*xBx(0,0)/
193  (xBx(0,0)-xy(0,0)+regularisation);
194 
195  z = y ;
196  z *= theta ;
197  Bx *= (1.0-theta) ;
198  z += Bx ;
199  xz = epsilon*xBx(0,0);
200  break;
201  }
202  }
203 
204  zz = z*z.transpose();
205 
206  BxxB *= 1.0/(xBx(0,0) + regularisation);
207  zz *= 1.0/(xz + regularisation);
208 
209 
210  // PERFORM THE UPDATE:
211  // -------------------
212 
213  B += zz - BxxB;
214 
215  return SUCCESSFUL_RETURN;
216 }
217 
218 
220  const BlockMatrix &x,
221  const BlockMatrix &y
222  )
223 {
224  int run1;
225  BlockMatrix a(5,1), b(5,1);
226  BlockMatrix block(5,5);
227 
228  for( run1 = 0; run1 < (int)nBlocks; run1++ ){
229 
230  a.setZero();
231  b.setZero();
232  block.setZero();
233 
234  getSubBlockLine( nBlocks, 0, 0, run1, x, a );
235  getSubBlockLine( nBlocks, 0, 0, run1, y, b );
236 
237  getSubBlockLine( nBlocks, run1, 0, run1, B, block );
238  getSubBlockLine( nBlocks, nBlocks+run1, 1, run1, B, block );
239  getSubBlockLine( nBlocks, 2*nBlocks+run1, 2, run1, B, block );
240  getSubBlockLine( nBlocks, 3*nBlocks+run1, 3, run1, B, block );
241  getSubBlockLine( nBlocks, 4*nBlocks+run1, 4, run1, B, block );
242 
243  applyUpdate( block, a, b );
244 
245  setSubBlockLine( nBlocks, run1, 0, run1, B, block );
246  setSubBlockLine( nBlocks, nBlocks+run1, 1, run1, B, block );
247  setSubBlockLine( nBlocks, 2*nBlocks+run1, 2, run1, B, block );
248  setSubBlockLine( nBlocks, 3*nBlocks+run1, 3, run1, B, block );
249  setSubBlockLine( nBlocks, 4*nBlocks+run1, 4, run1, B, block );
250  }
251 
252  return SUCCESSFUL_RETURN;
253 }
254 
255 
256 
258  const int &line1 ,
259  const int &line2 ,
260  const int &offset,
261  const BlockMatrix &M ,
262  BlockMatrix &O )
263 {
264  DMatrix tmp;
265 
266  M.getSubBlock( offset, line1, tmp );
267  if( tmp.getDim() != 0 ) O.setDense(0,line2,tmp);
268 
269  M.getSubBlock( N+offset, line1, tmp );
270  if( tmp.getDim() != 0 ) O.setDense(1,line2,tmp);
271 
272  M.getSubBlock( 2*N+offset, line1, tmp );
273  if( tmp.getDim() != 0 ) O.setDense(2,line2,tmp);
274 
275  M.getSubBlock( 3*N+offset, line1, tmp );
276  if( tmp.getDim() != 0 ) O.setDense(3,line2,tmp);
277 
278  M.getSubBlock( 4*N+offset, line1, tmp );
279  if( tmp.getDim() != 0 ) O.setDense(4,line2,tmp);
280 
281  return SUCCESSFUL_RETURN;
282 }
283 
284 
286  const int &line1 ,
287  const int &line2 ,
288  const int &offset,
289  BlockMatrix &M ,
290  const BlockMatrix &O )
291 {
292  DMatrix tmp;
293 
294  O.getSubBlock( 0, line2, tmp );
295 
296  if( tmp.getDim() != 0 ) M.setDense( offset, line1, tmp );
297  O.getSubBlock( 1, line2, tmp );
298  if( tmp.getDim() != 0 ) M.setDense( N+offset, line1, tmp );
299 
300  O.getSubBlock(2,line2,tmp);
301  if( tmp.getDim() != 0 ) M.setDense( 2*N+offset, line1, tmp );
302 
303  O.getSubBlock(3,line2,tmp);
304  if( tmp.getDim() != 0 ) M.setDense( 3*N+offset, line1, tmp );
305 
306  O.getSubBlock(4,line2,tmp);
307  if( tmp.getDim() != 0 ) M.setDense( 4*N+offset, line1, tmp );
308 
309  return SUCCESSFUL_RETURN;
310 }
311 
312 
313 
314 
315 
316 //
317 // PROTECTED MEMBER FUNCTIONS:
318 //
319 
320 
321 
322 
323 
325 
326 // end of file.
#define N
Data class for storing generic optimization variables.
Definition: ocp_iterate.hpp:57
virtual returnValue initScaling(BlockMatrix &B, const BlockMatrix &x, const BlockMatrix &y)
Implements a very rudimentary block sparse matrix class.
BFGSupdate & operator=(const BFGSupdate &rhs)
Definition: bfgs_update.cpp:73
virtual ~BFGSupdate()
Definition: bfgs_update.cpp:68
virtual NLPderivativeApproximation * clone() const
Definition: bfgs_update.cpp:87
BlockMatrix transpose() const
BEGIN_NAMESPACE_ACADO const double EPS
returnValue setDense(uint rowIdx, uint colIdx, const DMatrix &value)
Allows to pass back messages to the calling function.
virtual returnValue apply(BlockMatrix &B, const BlockMatrix &x, const BlockMatrix &y)
Block< Derived > block(Index startRow, Index startCol, Index blockRows, Index blockCols)
Definition: BlockMethods.h:56
BEGIN_NAMESPACE_ACADO typedef unsigned int uint
Definition: acado_types.hpp:42
#define CLOSE_NAMESPACE_ACADO
returnValue setSubBlockLine(const int &N, const int &line1, const int &line2, const int &offset, BlockMatrix &M, const BlockMatrix &x)
Implements a constant Hessian as approximation of second-order derivatives within NLPsolvers...
returnValue getSubBlock(uint rowIdx, uint colIdx, DMatrix &value) const
unsigned getDim() const
Definition: matrix.hpp:181
ConstantHessian & operator=(const ConstantHessian &rhs)
virtual returnValue initScaling(BlockMatrix &B, const BlockMatrix &x, const BlockMatrix &y)
virtual returnValue initHessian(BlockMatrix &B, uint N, const OCPiterate &iter)
Definition: bfgs_update.cpp:94
Encapsulates all user interaction for setting options, logging data and plotting results.
void rhs(const real_t *x, real_t *f)
Implements BFGS updates for approximating second-order derivatives within NLPsolvers.
Definition: bfgs_update.hpp:67
#define BT_TRUE
Definition: acado_types.hpp:47
virtual returnValue initHessian(BlockMatrix &B, uint N, const OCPiterate &iter)
returnValue setZero(uint rowIdx, uint colIdx)
#define BEGIN_NAMESPACE_ACADO
BFGSModificationType modification
BooleanType performsBlockUpdates() const
virtual returnValue applyUpdate(BlockMatrix &B, const BlockMatrix &x, const BlockMatrix &y)
virtual returnValue applyBlockDiagonalUpdate(BlockMatrix &B, const BlockMatrix &x, const BlockMatrix &y)
returnValue getSubBlockLine(const int &N, const int &line1, const int &line2, const int &offset, const BlockMatrix &M, BlockMatrix &x)
Base class for techniques of approximating second-order derivatives within NLPsolvers.


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Mon Jun 10 2019 12:34:28