irk_lifted_fob_export.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 
27 
36 
37 using namespace std;
38 
40 
41 //
42 // PUBLIC MEMBER FUNCTIONS:
43 //
44 
46  const std::string& _commonHeaderName
47  ) : ForwardLiftedIRKExport( _userInteraction,_commonHeaderName )
48 {
49 }
50 
52 {
53 }
54 
55 
57 {
58  if ( solver )
59  delete solver;
60  solver = 0;
61 
62  clear( );
63 }
64 
65 
67 
68  if( this != &arg ){
69 
71  copy( arg );
72  }
73  return *this;
74 }
75 
76 
78 {
79  ExportVariable max;
80  if( NX1 > 0 ) {
82  }
83  if( NX2 > 0 || NXA > 0 ) {
84  if( rhs.getGlobalExportVariable().getDim() >= max.getDim() ) {
86  }
87  if( diffs_rhs.getGlobalExportVariable().getDim() >= max.getDim() ) {
89  }
92  }
95  }
98  }
99  }
100  if( NX3 > 0 ) {
101  if( rhs3.getGlobalExportVariable().getDim() >= max.getDim() ) {
103  }
104  if( diffs_rhs3.getGlobalExportVariable().getDim() >= max.getDim() ) {
106  }
107  }
108  uint i;
109  for( i = 0; i < outputs.size(); i++ ) {
110  if( outputs[i].getGlobalExportVariable().getDim() >= max.getDim() ) {
111  max = outputs[i].getGlobalExportVariable();
112  }
113  if( diffs_outputs[i].getGlobalExportVariable().getDim() >= max.getDim() ) {
114  max = diffs_outputs[i].getGlobalExportVariable();
115  }
116  }
117  return max;
118 }
119 
120 
122  ExportStruct dataStruct
123  ) const
124 {
125  ForwardLiftedIRKExport::getDataDeclarations( declarations, dataStruct );
126 
127  declarations.addDeclaration( rk_A_traj,dataStruct );
128  declarations.addDeclaration( rk_S_traj,dataStruct );
129  declarations.addDeclaration( rk_xxx_traj,dataStruct );
130 
131  declarations.addDeclaration( rk_b_trans,dataStruct );
132 
133  declarations.addDeclaration( rk_adj_traj,dataStruct );
134 
135  declarations.addDeclaration( rk_adj_diffs_tmp,dataStruct );
136  declarations.addDeclaration( rk_Khat_traj,dataStruct );
137  declarations.addDeclaration( rk_Xhat_traj,dataStruct );
138 
139  declarations.addDeclaration( rk_hess_tmp1,dataStruct );
140  declarations.addDeclaration( rk_hess_tmp2,dataStruct );
141 
142  return SUCCESSFUL_RETURN;
143 }
144 
145 
147  ) const
148 {
150 
151  return SUCCESSFUL_RETURN;
152 }
153 
154 
156 {
157  int sensGen;
158  get( DYNAMIC_SENSITIVITY,sensGen );
159  if( rhs_.getDim() > 0 ) {
160  OnlineData dummy0;
161  Control dummy1;
162  DifferentialState dummy2;
163  AlgebraicState dummy3;
165  dummy0.clearStaticCounters();
166  dummy1.clearStaticCounters();
167  dummy2.clearStaticCounters();
168  dummy3.clearStaticCounters();
169  dummy4.clearStaticCounters();
170 
171  NX2 = rhs_.getDim() - NXA;
172  x = DifferentialState("", NX1+NX2, 1);
173  z = AlgebraicState("", NXA, 1);
174  u = Control("", NU, 1);
175  od = OnlineData("", NOD, 1);
176 
178  f << rhs_;
179 
180  NDX2 = f.getNDX();
181  if( NDX2 > 0 && (NDX2 < NX2 || NDX2 > (NX1+NX2)) ) {
182  return ACADOERROR( RET_INVALID_OPTION );
183  }
184  else if( NDX2 > 0 ) NDX2 = NX1+NX2;
186 
188  for( uint i = 0; i < rhs_.getDim(); i++ ) {
189  g << forwardDerivative( rhs_(i), x );
190  g << forwardDerivative( rhs_(i), z );
191  g << forwardDerivative( rhs_(i), u );
192  g << forwardDerivative( rhs_(i), dx );
193  }
194 
195  // FORWARD SWEEP:
196  DifferentialState sX("", NX,NX+NU);
197  Expression Gx = sX.getCols(0,NX);
198  Expression Gu = sX.getCols(NX,NX+NU);
199  DifferentialEquation forward;
200  for( uint i = 0; i < rhs_.getDim(); i++ ) {
201  // NOT YET IMPLEMENTED FOR DAES OR IMPLICIT ODES
202  if( NDX2 > 0 || NXA > 0 ) return ACADOERROR(RET_NOT_YET_IMPLEMENTED);
203  forward << multipleForwardDerivative( rhs_(i), x, Gx );
204  forward << multipleForwardDerivative( rhs_(i), x, Gu ) + forwardDerivative( rhs_(i), u );
205  }
206 
207  // FIRST ORDER ADJOINT SWEEP:
208  DifferentialState lambda("", NX,1);
209  DifferentialEquation backward, adj_update;
210 // backward << backwardDerivative( rhs_, x, lambda );
211  adj_update << backwardDerivative( rhs_, x, lambda );
212 
213  // SECOND ORDER ADJOINT SWEEP:
214  Expression arg;
215  arg << x;
216  arg << u;
217  Expression S_tmp = sX;
218  S_tmp.appendRows(zeros<double>(NU,NX).appendCols(eye<double>(NU)));
219 
220  if( NDX2 > 0 || NXA > 0 ) return ACADOERROR(RET_NOT_YET_IMPLEMENTED);
221  Expression tmp = backwardDerivative( rhs_, arg, lambda );
222  backward << tmp.getRows(0,NX);
223  backward << multipleForwardDerivative( tmp, arg, S_tmp );
224 
225  // GRADIENT UPDATE:
226  int gradientUp;
227  get( LIFTED_GRADIENT_UPDATE, gradientUp );
228  bool gradientUpdate = (bool) gradientUp;
229 
230  uint nHat = 0;
231  if( gradientUpdate ) {
232  DifferentialState hat("",1,NX);
233  Expression tmp2 = hat*tmp.getRows(0,NX);
234  backward << multipleForwardDerivative( tmp2, arg, S_tmp );
235  nHat = NX;
236  }
237 
238  if( f.getNT() > 0 ) timeDependant = true;
239 
240  return (rhs.init( f,"acado_rhs",NX,NXA,NU,NP,NDX,NOD ) &
241  diffs_rhs.init( g,"acado_diffs",NX,NXA,NU,NP,NDX,NOD ) &
242  forward_sweep.init( forward,"acado_forward",NX*(2+NX+NU)+nHat,NXA,NU,NP,NDX,NOD ) &
243  adjoint_sweep.init( backward,"acado_backward",NX*(2+NX+NU)+nHat,NXA,NU,NP,NDX,NOD ) &
244  diffs_sweep.init( adj_update,"acado_adjoint_update",NX*(2+NX+NU)+nHat,NXA,NU,NP,NDX,NOD ));
245  }
246  return SUCCESSFUL_RETURN;
247 }
248 
249 
251 // std::cout << "returnLowerTriangular with " << expr.getNumRows() << " rows and " << expr.getNumCols() << " columns\n";
252  ASSERT( expr.getNumRows() == expr.getNumCols() );
253 
254  Expression new_expr;
255  for( uint i = 0; i < expr.getNumRows(); i++ ) {
256  for( uint j = 0; j <= i; j++ ) {
257  new_expr << expr(i,j);
258  }
259  }
260  return new_expr;
261 }
262 
263 
265 {
266  int sensGen;
267  get( DYNAMIC_SENSITIVITY, sensGen );
268  int mode;
269  get( IMPLICIT_INTEGRATOR_MODE, mode );
270 // get( LIFTED_INTEGRATOR_MODE, liftMode );
273 // if( liftMode != 1 && liftMode != 4 ) ACADOERROR( RET_NOT_IMPLEMENTED_YET );
275 
276  int gradientUp;
277  get( LIFTED_GRADIENT_UPDATE, gradientUp );
278  bool gradientUpdate = (bool) gradientUp;
279 
280  // NOTE: liftMode == 4 --> inexact Newton based implementation
281 
283 
284  ACADOWARNINGTEXT(RET_INVALID_OPTION, "The FORWARD_OVER_BACKWARD implementation is only for illustrational purposes, since the SYMMETRIC scheme will always outperform this.");
285 
286  int useOMP;
287  get(CG_USE_OPENMP, useOMP);
288  if ( useOMP ) ACADOERROR( RET_NOT_IMPLEMENTED_YET );
289 
291 
292  int linSolver;
293  get( LINEAR_ALGEBRA_SOLVER, linSolver );
294  int liftMode = 1;
295  if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) liftMode = 4;
296  if( exportRhs ) {
297  if( NX2 > 0 || NXA > 0 ) {
298  code.addFunction( rhs );
299  code.addStatement( "\n\n" );
300  code.addFunction( diffs_rhs );
301  code.addStatement( "\n\n" );
302  if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
303  code.addFunction( diffs_sweep );
304  code.addStatement( "\n\n" );
305  }
306  if( liftMode == 4 ) { // ONLY for the inexact Newton based schemes
307  code.addFunction( forward_sweep );
308  code.addStatement( "\n\n" );
309  }
310  code.addFunction( adjoint_sweep );
311  code.addStatement( "\n\n" );
312  }
313 
315 
317  }
318  if( NX2 > 0 || NXA > 0 ) solver->getCode( code );
319  code.addLinebreak(2);
320 
321  int measGrid;
322  get( MEASUREMENT_GRID, measGrid );
323 
324  // export RK scheme
325  uint run5, run6;
326  std::string tempString;
327 
330 
331  double h = (grid.getLastTime() - grid.getFirstTime())/grid.getNumIntervals();
332  DMatrix tmp = AA;
333  ExportVariable Ah( "Ah_mat", tmp*=h, STATIC_CONST_REAL );
334  code.addDeclaration( Ah );
335  code.addLinebreak( 2 );
336  // TODO: Ask Milan why this does NOT work properly !!
338 
339  DVector BB( bb );
340  ExportVariable Bh( "Bh_mat", DMatrix( BB*=h ) );
341 
342  DVector CC( cc );
343  ExportVariable C;
344  if( timeDependant ) {
345  C = ExportVariable( "C_mat", DMatrix( CC*=(1.0/grid.getNumIntervals()) ), STATIC_CONST_REAL );
346  code.addDeclaration( C );
347  code.addLinebreak( 2 );
349  }
350 
351  code.addComment(std::string("Fixed step size:") + toString(h));
352 
353  ExportVariable determinant( "det", 1, 1, REAL, ACADO_LOCAL, true );
354  integrate.addDeclaration( determinant );
355 
356  ExportIndex i( "i" );
357  ExportIndex j( "j" );
358  ExportIndex k( "k" );
359  ExportIndex run( "run" );
360  ExportIndex run1( "run1" );
361  ExportIndex tmp_index1("tmp_index1");
362  ExportIndex tmp_index2("tmp_index2");
363  ExportIndex tmp_index3("tmp_index3");
364  ExportIndex tmp_index4("tmp_index4");
365  ExportIndex k_index("k_index");
366  ExportIndex shooting_index("shoot_index");
367  ExportVariable tmp_meas("tmp_meas", 1, outputGrids.size(), INT, ACADO_LOCAL);
368 
369  ExportVariable numInt( "numInts", 1, 1, INT );
370  if( !equidistantControlGrid() ) {
371  ExportVariable numStepsV( "numSteps", numSteps, STATIC_CONST_INT );
372  code.addDeclaration( numStepsV );
373  code.addLinebreak( 2 );
374  integrate.addStatement( std::string( "int " ) + numInt.getName() + " = " + numStepsV.getName() + "[" + rk_index.getName() + "];\n" );
375  }
376 
377  prepareOutputEvaluation( code );
378 
379  integrate.addIndex( i );
380  integrate.addIndex( j );
381  integrate.addIndex( k );
382  integrate.addIndex( run );
383  integrate.addIndex( run1 );
384  integrate.addIndex( tmp_index1 );
385  integrate.addIndex( tmp_index2 );
386  integrate.addIndex( tmp_index3 );
387  integrate.addIndex( shooting_index );
388  integrate.addIndex( k_index );
389  if( rk_outputs.size() > 0 && (grid.getNumIntervals() > 1 || !equidistantControlGrid()) ) {
390  integrate.addIndex( tmp_index4 );
391  }
392  integrate << shooting_index.getFullName() << " = " << rk_index.getFullName() << ";\n";
394  if( (inputDim-diffsDim) > NX+NXA ) {
398  }
400  if( liftMode == 1 || liftMode == 4 ) {
401  integrate.addStatement( rk_delta.getCols( 0,NX ) == rk_eta.getCols( 0,NX ) - rk_Xprev.getRow(shooting_index) );
402  integrate.addStatement( rk_Xprev.getRow(shooting_index) == rk_eta.getCols( 0,NX ) );
403 
406  }
408 
409  // integrator FORWARD loop:
410  integrate.addComment("------------ Forward loop ------------:");
411  ExportForLoop tmpLoop( run, 0, grid.getNumIntervals() );
412  ExportStatementBlock *loop;
413  if( equidistantControlGrid() ) {
414  loop = &tmpLoop;
415  }
416  else {
417  loop = &integrate;
418  loop->addStatement( std::string("for(") + run.getName() + " = 0; " + run.getName() + " < " + numInt.getName() + "; " + run.getName() + "++ ) {\n" );
419  }
420 
421 // if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) {
422  // Set rk_diffsPrev:
423  loop->addStatement( std::string("if( run > 0 ) {\n") );
424  if( NX2 > 0 ) {
425  ExportForLoop loopTemp2( i,0,NX2 );
426  loopTemp2.addStatement( rk_diffsPrev2.getSubMatrix( i,i+1,0,NX1+NX2 ) == rk_eta.getCols( i*NX+2*NX+NXA+NX1*NX,i*NX+2*NX+NXA+NX1*NX+NX1+NX2 ) );
427  if( NU > 0 ) loopTemp2.addStatement( rk_diffsPrev2.getSubMatrix( i,i+1,NX1+NX2,NX1+NX2+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1)+NX1*NU+NX,i*NU+(NX+NXA)*(NX+1)+NX1*NU+NU+NX ) );
428  loop->addStatement( loopTemp2 );
429  }
430  loop->addStatement( std::string("}\nelse{\n") );
431  DMatrix eyeM = eye<double>(NX);
432  eyeM.appendCols(zeros<double>(NX,NU));
433  loop->addStatement( rk_diffsPrev2 == eyeM );
434  loop->addStatement( std::string("}\n") );
435 // }
436 
437  // SAVE rk_diffsPrev2 in the rk_S_traj variable:
438  loop->addStatement( rk_S_traj.getRows(run*NX,(run+1)*NX) == rk_diffsPrev2 );
439 
440  loop->addStatement( k_index == (shooting_index*grid.getNumIntervals()+run)*(NX+NXA) );
441 
442  // FIRST update using term from optimization variables:
443  if( liftMode == 1 || liftMode == 4 ) {
444  ExportForLoop loopTemp1( i,0,NX+NXA );
445  loopTemp1.addStatement( j == k_index+i );
446  loopTemp1.addStatement( tmp_index1 == j*(NX+NU) );
447  ExportForLoop loopTemp2( run1,0,numStages );
448  loopTemp2.addStatement( rk_kkk.getElement( j,run1 ) += rk_delta*rk_diffK.getSubMatrix( tmp_index1,tmp_index1+NX+NU,run1,run1+1 ) );
449  loopTemp1.addStatement( loopTemp2 );
450  loop->addStatement( loopTemp1 );
451  }
452 
453  // Evaluate all stage values for reuse:
454  evaluateAllStatesImplicitSystem( loop, k_index, Ah, C, run1, j, tmp_index1 );
455 
456  // SAVE rk_stageValues in the rk_xxx_traj variable:
457  loop->addStatement( rk_xxx_traj.getCols(run*numStages*(NX2+NXA),(run+1)*numStages*(NX2+NXA)) == rk_stageValues );
458 
459  solveImplicitSystem( loop, i, run1, j, tmp_index1, k_index, Ah, C, determinant, true );
460 
461  // NEW: UPDATE RK_B WITH THE CONSTANT COMING FROM THE PREVIOUS INTEGRATION STEP
462  if( (LinearAlgebraSolver) linSolver != SIMPLIFIED_IRK_NEWTON && (LinearAlgebraSolver) linSolver != SINGLE_IRK_NEWTON && gradientUpdate) { // EXACT LIFTING with GRADIENT UPDATE
463  loop->addStatement( std::string("if( run > 0 ) {\n") );
464  loop->addStatement( rk_Xhat_traj.getRows(run*NX,(run+1)*NX) == rk_Xhat_traj.getRows((run-1)*NX,run*NX) );
465  for( run5 = 0; run5 < numStages; run5++ ) {
466  loop->addStatement( rk_Xhat_traj.getRows(run*NX,(run+1)*NX) += rk_Khat_traj.getSubMatrix( run-1,run,run5*(NX2+NXA),(run5+1)*(NX2+NXA) ).getTranspose()*Bh.getElement(run5,0) );
467  }
468  ExportForLoop deltaLoop( i,0,numStages );
469  ExportForLoop deltaLoop2( j,0,NX );
470  deltaLoop2.addStatement( tmp_index1 == i*(NX2+NXA)+j );
471  deltaLoop2.addStatement( rk_b.getElement(tmp_index1,0) -= rk_diffsTemp2.getSubMatrix(i,i+1,j*NVARS2,j*NVARS2+NX)*rk_Xhat_traj.getRows(run*NX,(run+1)*NX) );
472  deltaLoop.addStatement( deltaLoop2 );
473  loop->addStatement( deltaLoop );
474  loop->addStatement( std::string("}\nelse{\n") );
475  loop->addStatement( rk_Xhat_traj.getRows(0,NX) == zeros<double>(NX,1) );
476  loop->addStatement( std::string("}\n") );
477  }
478 
479  // SAVE rk_A in the rk_A_traj variable:
480  if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
481  loop->addStatement( rk_A_traj.getRows(run*(NX2+NXA),(run+1)*(NX2+NXA)) == rk_A );
482  }
483  else {
484  loop->addStatement( rk_A_traj.getRows(run*numStages*(NX2+NXA),(run+1)*numStages*(NX2+NXA)) == rk_A );
485  }
486 
487  if( liftMode == 1 ) {
488  // Evaluate sensitivities:
489 // // !! NEW !! Let us propagate the forward sensitivities as in a VDE system
490 // loop->addStatement( rk_seed.getCols(NX,NX+NX*(NX+NU)) == rk_diffsPrev2.makeRowVector() );
491 // ExportForLoop loop_sens( i,0,numStages );
492 // loop_sens.addStatement( rk_seed.getCols(0,NX) == rk_stageValues.getCols(i*(NX+NXA),i*(NX+NXA)+NX) );
493 // loop_sens.addFunctionCall( forward_sweep.getName(), rk_seed, rk_diffsTemp2.getAddress(i,0) );
494 // loop->addStatement( loop_sens );
495 
496  // In FOB, we reuse the derivatives computed to form the linear system (in rk_diffsTemp2) !!
497 
498  evaluateRhsSensitivities( loop, run1, i, j, tmp_index1, tmp_index2 );
499  allSensitivitiesImplicitSystem( loop, run1, i, j, tmp_index1, tmp_index2, tmp_index3, k_index, Bh, false );
500  }
501  else if( liftMode == 4 ) {
502  evaluateRhsInexactSensitivities( loop, run1, i, j, tmp_index1, tmp_index2, tmp_index3, k_index, Ah );
503  allSensitivitiesImplicitSystem( loop, run1, i, j, tmp_index1, tmp_index2, tmp_index3, k_index, Bh, true );
504  }
505  else return ACADOERROR( RET_NOT_IMPLEMENTED_YET );
506 
507  // !!! update rk_xxx_lin (YOU NEED TO UPDATE THE LINEARIZATION POINT BEFORE YOU UPDATE RK_KKK): !!!
508  for( run5 = 0; run5 < NX; run5++ ) {
509  loop->addStatement( rk_xxx_lin.getCol( run5 ) += rk_kkk.getRow( k_index+run5 )*Bh );
510  }
511 
512  // update rk_kkk:
513  ExportForLoop loopTemp( j,0,numStages );
514  for( run5 = 0; run5 < NX2; run5++ ) {
515  if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
516  loopTemp.addStatement( rk_kkk.getElement( k_index+NX1+run5,j ) += rk_b.getElement( j*(NX2+NXA)+run5,0 ) ); // differential states
517  }
518  else {
519  loopTemp.addStatement( rk_kkk.getElement( k_index+NX1+run5,j ) += rk_b.getElement( j*NX2+run5,0 ) ); // differential states
520  }
521  }
522  for( run5 = 0; run5 < NXA; run5++ ) {
523  if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
524  loopTemp.addStatement( rk_kkk.getElement( k_index+NX+run5,j ) += rk_b.getElement( j*(NX2+NXA)+NX2+run5,0 ) ); // algebraic states
525  }
526  else {
527  loopTemp.addStatement( rk_kkk.getElement( k_index+NX+run5,j ) += rk_b.getElement( numStages*NX2+j*NXA+run5,0 ) ); // algebraic states
528  }
529  }
530  loop->addStatement( loopTemp );
531  if( gradientUpdate ) { // save the rk_b first column results:
532  loop->addStatement( rk_Khat_traj.getRow(run) == rk_b.getCol(0).getTranspose() );
533  }
534 
535  // update rk_eta:
536  for( run5 = 0; run5 < NX; run5++ ) {
537  loop->addStatement( rk_eta.getCol( run5 ) += rk_kkk.getRow( k_index+run5 )*Bh );
538  }
539  if( NXA > 0) {
540  DMatrix tempCoefs( evaluateDerivedPolynomial( 0.0 ) );
541  if( !equidistantControlGrid() || grid.getNumIntervals() > 1 ) {
542  loop->addStatement( std::string("if( run == 0 ) {\n") );
543  }
544  for( run5 = 0; run5 < NXA; run5++ ) {
545  loop->addStatement( rk_eta.getCol( NX+run5 ) == rk_kkk.getRow( k_index+NX+run5 )*tempCoefs );
546  }
547  if( !equidistantControlGrid() || grid.getNumIntervals() > 1 ) {
548  loop->addStatement( std::string("}\n") );
549  }
550  }
551 
552  // Computation of the sensitivities using the CHAIN RULE:
553  updateImplicitSystem(loop, i, j, tmp_index2);
554 
555 // loop->addStatement( std::string( reset_int.get(0,0) ) + " = 0;\n" );
556 
557  loop->addStatement( rk_ttt += DMatrix(1.0/grid.getNumIntervals()) );
558 
559  // end of the forward integrator loop.
560  if( !equidistantControlGrid() ) {
561  loop->addStatement( "}\n" );
562  }
563  else {
564  integrate.addStatement( *loop );
565  }
566 
567  // integrator BACKWARD loop:
568  integrate.addComment("------------ BACKWARD loop ------------:");
569  // set current Hessian to zero
570  DMatrix zeroM;
571  if( !gradientUpdate ) zeroM = zeros<double>(1,NX*(NX+NU)+NU*NU);
572  else zeroM = zeros<double>(1,NX*(NX+NU)+NU*NU+NX+NU);
573  integrate.addStatement( rk_eta.getCols(NX*(2+NX+NU),NX+diffsDim) == zeroM );
574  ExportForLoop tmpLoop2( run, grid.getNumIntervals()-1, -1, -1 );
575  ExportStatementBlock *loop2;
576  if( equidistantControlGrid() ) {
577  loop2 = &tmpLoop2;
578  }
579  else {
581  }
582 
583  loop2->addStatement( k_index == (shooting_index*grid.getNumIntervals()+run)*(NX+NXA)*(NX+NU) );
584 
585  // Compute \hat{lambda}:
586  // vec(j*NX+1:j*NX+NX) = -Bh_vec(j+1)*dir_tmp;
587  for( run5 = 0; run5 < numStages; run5++ ) {
588  DMatrix zeroV = zeros<double>(1,NX);
589  loop2->addStatement( rk_b_trans.getCols(run5*NX,(run5+1)*NX) == zeroV );
590  loop2->addStatement( rk_b_trans.getCols(run5*NX,(run5+1)*NX) -= Bh.getRow(run5)*rk_eta.getCols(NX,2*NX) );
591  }
592  if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
593  loop2->addStatement( tmp_index1 == shooting_index*grid.getNumIntervals()+run );
594  for( run5 = 0; run5 < numStages; run5++ ) {
595  loop2->addStatement( rk_seed.getCols(0,NX) == rk_xxx_traj.getCols((run*numStages+run5)*(NX2+NXA),(run*numStages+run5+1)*(NX2+NXA)) );
596  loop2->addStatement( rk_seed.getCols(NX*(1+NX+NU),NX*(2+NX+NU)) == rk_adj_traj.getSubMatrix(tmp_index1,tmp_index1+1,run5*(NX+NXA),(run5+1)*(NX+NXA)) );
597  loop2->addFunctionCall( diffs_sweep.getName(), rk_seed, rk_adj_diffs_tmp );
598  for( run6 = 0; run6 < numStages; run6++ ) {
599  loop2->addStatement( rk_b_trans.getCols(run6*NX,(run6+1)*NX) -= Ah.getElement(run5,run6)*rk_adj_diffs_tmp.getCols(0,NX) );
600  }
601  loop2->addStatement( rk_b_trans.getCols(run5*NX,(run5+1)*NX) += rk_adj_traj.getSubMatrix(tmp_index1,tmp_index1+1,run5*(NX+NXA),(run5+1)*(NX+NXA)) ); // BECAUSE EXPLICIT ODE
602  }
603  loop2->addFunctionCall( solver->getNameSolveTransposeReuseFunction(),rk_A_traj.getAddress(run*(NX2+NXA),0),rk_b_trans.getAddress(0,0),rk_auxSolver.getAddress(0,0) );
604  loop2->addStatement( rk_adj_traj.getRow(tmp_index1) += rk_b_trans );
605  loop2->addStatement( rk_b_trans == rk_adj_traj.getRow(tmp_index1) );
606  }
607  else {
608  loop2->addFunctionCall( solver->getNameSolveTransposeReuseFunction(),rk_A_traj.getAddress(run*numStages*(NX2+NXA),0),rk_b_trans.getAddress(0,0),rk_auxSolver.getAddress(0,0) );
609  }
610 
611  zeroM = zeros<double>(NX+NU,NX+NU);
612  loop2->addStatement( rk_hess_tmp1 == zeroM );
613  for( run5 = 0; run5 < numStages; run5++ ) {
614  loop2->addStatement( rk_seed.getCols(0,NX) == rk_xxx_traj.getCols((run*numStages+run5)*(NX2+NXA),(run*numStages+run5+1)*(NX2+NXA)) );
615  loop2->addStatement( rk_diffsPrev2 == rk_S_traj.getRows(run*NX,(run+1)*NX) );
616 
617  ExportForLoop diffLoop1( i, 0, NX );
618  diffLoop1.addStatement( tmp_index1 == k_index+i*(NX+NU) );
619  ExportForLoop diffLoop2( j, 0, NX+NU );
620  diffLoop2.addStatement( tmp_index2 == tmp_index1+j );
621  for( run6 = 0; run6 < numStages; run6++ ) {
622  diffLoop2.addStatement( rk_diffsPrev2.getElement(i,j) += Ah.getElement(run5,run6)*rk_diffK.getElement( tmp_index2,run6 ) );
623  }
624  diffLoop1.addStatement( diffLoop2 );
625  loop2->addStatement( diffLoop1 );
626 
627  loop2->addStatement( rk_seed.getCols(NX,NX*(1+NX+NU)) == rk_diffsPrev2.makeRowVector() );
628  loop2->addStatement( rk_seed.getCols(NX*(1+NX+NU),NX*(2+NX+NU)) == rk_b_trans.getCols(run5*NX,(run5+1)*NX) );
629  if( gradientUpdate ) {
630  loop2->addStatement( rk_seed.getCols(NX*(2+NX+NU),NX*(3+NX+NU)) == rk_Xhat_traj.getRows(run*NX,(run+1)*NX).getTranspose() );
631  ExportForLoop gradLoop( i, 0, numStages );
632  gradLoop.addStatement( rk_seed.getCols(NX*(2+NX+NU),NX*(3+NX+NU)) += Ah.getElement(run5,i)*rk_Khat_traj.getSubMatrix( run,run+1,i*(NX2+NXA),(i+1)*(NX2+NXA) ) );
633  loop2->addStatement( gradLoop );
634  }
635  loop2->addFunctionCall( adjoint_sweep.getName(), rk_seed, rk_adj_diffs_tmp.getAddress(0,0) );
636  loop2->addStatement( rk_eta.getCols(NX,2*NX) += rk_adj_diffs_tmp.getCols(0,NX) );
637  for( run6 = 0; run6 < NX+NU; run6++ ) {
638  loop2->addStatement( rk_hess_tmp2.getRow(run6) == rk_adj_diffs_tmp.getCols(NX+run6*(NX+NU),NX+(run6+1)*(NX+NU)) );
639  }
640  if( gradientUpdate ) {
641  loop2->addStatement( rk_eta.getCols(NX+diffsDim-NX-NU,NX+diffsDim) += rk_adj_diffs_tmp.getCols(NX+(NX+NU)*(NX+NU),NX+(NX+NU)*(NX+NU)+NX+NU) );
642  }
643 
644  // compute the local derivatives in rk_diffsPrev2
645  loop2->addStatement( rk_diffsPrev2 == eyeM );
646  ExportForLoop diffLoop3( i, 0, NX );
647  diffLoop3.addStatement( tmp_index1 == k_index+i*(NX+NU) );
648  ExportForLoop diffLoop4( j, 0, NX+NU );
649  diffLoop4.addStatement( tmp_index2 == tmp_index1+j );
650  for( run6 = 0; run6 < numStages; run6++ ) {
651  diffLoop4.addStatement( rk_diffsPrev2.getElement(i,j) += Ah.getElement(run5,run6)*rk_diffK_local.getElement( tmp_index2,run6 ) );
652  }
653  diffLoop3.addStatement( diffLoop4 );
654  loop2->addStatement( diffLoop3 );
655 
656  // update of rk_hess_tmp2 from the left and add it to rk_hess_tmp1
657  updateHessianTerm( loop2, i, j );
658  }
659 
660 
661  for( run6 = 0; run6 < NX; run6++ ) { // NX_NX
662  loop2->addStatement( rk_hess_tmp2.getSubMatrix(run6,run6+1,0,NX) == rk_eta.getCols(NX*(2+NX+NU)+run6*NX,NX*(2+NX+NU)+(run6+1)*NX) );
663  }
664  for( run6 = 0; run6 < NX; run6++ ) { // NX_NU
665  loop2->addStatement( rk_hess_tmp2.getSubMatrix(run6,run6+1,NX,NX+NU) == rk_eta.getCols(NX*(2+NX+NU)+NX*NX+run6*NU,NX*(2+NX+NU)+NX*NX+(run6+1)*NU) );
666  loop2->addStatement( rk_hess_tmp2.getSubMatrix(NX,NX+NU,run6,run6+1) == rk_hess_tmp2.getSubMatrix(run6,run6+1,NX,NX+NU).getTranspose() );
667  }
668  for( run6 = 0; run6 < NU; run6++ ) { // NU_NU
669  loop2->addStatement( rk_hess_tmp2.getSubMatrix(NX+run6,NX+run6+1,NX,NX+NU) == rk_eta.getCols(NX*(2+NX+NU)+NX*(NX+NU)+run6*NU,NX*(2+NX+NU)+NX*(NX+NU)+(run6+1)*NU) );
670  }
671 
672  // compute the local result derivatives in rk_diffsPrev2
673  loop2->addStatement( rk_diffsPrev2 == eyeM );
674  ExportForLoop diffLoop5( i, 0, NX );
675  diffLoop5.addStatement( tmp_index1 == k_index+i*(NX+NU) );
676  ExportForLoop diffLoop6( j, 0, NX+NU );
677  diffLoop6.addStatement( tmp_index2 == tmp_index1+j );
678  diffLoop6.addStatement( rk_diffsPrev2.getElement(i,j) += rk_diffK_local.getRow( tmp_index2 )*Bh );
679  diffLoop5.addStatement( diffLoop6 );
680  loop2->addStatement( diffLoop5 );
681  updateHessianTerm( loop2, i, j );
682 
683  // UPDATE HESSIAN RESULT
684  for( run6 = 0; run6 < NX; run6++ ) { // NX_NX
685  loop2->addStatement( rk_eta.getCols(NX*(2+NX+NU)+run6*NX,NX*(2+NX+NU)+(run6+1)*NX) == rk_hess_tmp1.getSubMatrix(run6,run6+1,0,NX) );
686  }
687  for( run6 = 0; run6 < NX; run6++ ) { // NX_NU
688  loop2->addStatement( rk_eta.getCols(NX*(2+NX+NU)+NX*NX+run6*NU,NX*(2+NX+NU)+NX*NX+(run6+1)*NU) == rk_hess_tmp1.getSubMatrix(run6,run6+1,NX,NX+NU) );
689  }
690  for( run6 = 0; run6 < NU; run6++ ) { // NU_NU
691  loop2->addStatement( rk_eta.getCols(NX*(2+NX+NU)+NX*(NX+NU)+run6*NU,NX*(2+NX+NU)+NX*(NX+NU)+(run6+1)*NU) == rk_hess_tmp1.getSubMatrix(NX+run6,NX+run6+1,NX,NX+NU) );
692  }
693 
694  loop2->addStatement( rk_ttt -= DMatrix(1.0/grid.getNumIntervals()) );
695  // end of the backward integrator loop.
696  if( !equidistantControlGrid() ) {
698  }
699  else {
700  integrate.addStatement( *loop2 );
701  }
702 
703 // integrate.addStatement( std::string( "if( " ) + determinant.getFullName() + " < 1e-12 ) {\n" );
704 // integrate.addStatement( error_code == 2 );
705 // integrate.addStatement( std::string( "} else if( " ) + determinant.getFullName() + " < 1e-6 ) {\n" );
706 // integrate.addStatement( error_code == 1 );
707 // integrate.addStatement( std::string( "} else {\n" ) );
709 // integrate.addStatement( std::string( "}\n" ) );
710 
711  code.addFunction( integrate );
712  code.addLinebreak( 2 );
713 
714  return SUCCESSFUL_RETURN;
715 }
716 
717 
719 {
720  ExportForLoop loop0( stage,0,numStages );
721  ExportForLoop loop1( i, 0, NX1+NX2 );
722  loop1.addStatement( rk_stageValues.getCol( stage*(NX+NXA)+i ) == rk_xxx_lin.getCol( i ) );
723  loop1.addStatement( tmp_index == k_index + i );
724  for( uint j = 0; j < numStages; j++ ) {
725  loop1.addStatement( rk_stageValues.getCol( stage*(NX+NXA)+i ) += Ah.getElement(stage,j)*rk_kkk.getElement( tmp_index,j ) );
726  }
727  loop0.addStatement( loop1 );
728 
729  ExportForLoop loop3( i, 0, NXA );
730  loop3.addStatement( tmp_index == k_index + i + NX );
731  loop3.addStatement( rk_stageValues.getCol( stage*(NX+NXA)+NX+i ) == rk_kkk.getElement( tmp_index,stage ) );
732  loop0.addStatement( loop3 );
733  block->addStatement( loop0 );
734 
735  return SUCCESSFUL_RETURN;
736 }
737 
738 
740 {
741  if( NX2 > 0 ) {
742  ExportForLoop loop01( index1,NX1,NX1+NX2 );
743  ExportForLoop loop02( index2,0,NX1+NX2 );
744  loop02.addStatement( tmp_index == index2+index1*NX );
745  loop02.addStatement( rk_eta.getCol( tmp_index+2*NX+NXA ) == rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,index2,index2+1 ) );
746  loop01.addStatement( loop02 );
747 
748  if( NU > 0 ) {
749  ExportForLoop loop03( index2,0,NU );
750  loop03.addStatement( tmp_index == index2+index1*NU );
751  loop03.addStatement( rk_eta.getCol( tmp_index+(NX+NXA)*(1+NX)+NX ) == rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,NX1+NX2+index2,NX1+NX2+index2+1 ) );
752  loop01.addStatement( loop03 );
753  }
754  block->addStatement( loop01 );
755  }
756  // ALGEBRAIC STATES
757  if( NXA > 0 ) {
759  }
760 
761  return SUCCESSFUL_RETURN;
762 }
763 
764 
766  ExportForLoop loop1( i, 0, NX );
767  ExportForLoop loop2( j, 0, NX+NU );
768  for( uint index = 0; index < NX; index++ ) {
770  }
771  loop1.addStatement( loop2 );
772  block->addStatement( loop1 );
773 
774  ExportForLoop loop3( i, 0, NU );
775  ExportForLoop loop4( j, 0, NX+NU );
776  loop4.addStatement( rk_hess_tmp1.getElement(NX+i,j) += rk_hess_tmp2.getElement(NX+i,j) );
777  for( uint index = 0; index < NX; index++ ) {
778  loop4.addStatement( rk_hess_tmp1.getElement(NX+i,j) += rk_diffsPrev2.getElement(index,NX+i)*rk_hess_tmp2.getElement(index,j) );
779  }
780  loop3.addStatement( loop4 );
781  block->addStatement( loop3 );
782 
783  return SUCCESSFUL_RETURN;
784 }
785 
786 
787 returnValue ForwardBackwardLiftedIRKExport::allSensitivitiesImplicitSystem( ExportStatementBlock* block, const ExportIndex& index1, const ExportIndex& index2, const ExportIndex& index3, const ExportIndex& tmp_index1, const ExportIndex& tmp_index2, const ExportIndex& tmp_index3, const ExportIndex& k_index, const ExportVariable& Bh, bool update )
788 {
789  if( NX2 > 0 ) {
790  int linSolver;
791  get( LINEAR_ALGEBRA_SOLVER, linSolver );
792  DMatrix tempCoefs( evaluateDerivedPolynomial( 0.0 ) ); // We compute the algebraic variables at the beginning of the shooting interval !
793 
794  // call the linear solver:
795  if( NDX2 > 0 ) {
797  }
798  else {
800  }
801 
802  // update rk_diffK_local with the new sensitivities:
803  ExportForLoop loop20( index2,0,numStages );
804  ExportForLoop loop21( index3,0,NX2 );
805  loop21.addStatement( tmp_index1 == (k_index + NX1 + index3)*(NX+NU) );
806  loop21.addStatement( tmp_index3 == index2*NX2+index3 );
807  ExportForLoop loop22( index1,0,NX2 );
808  loop22.addStatement( tmp_index2 == tmp_index1+index1 );
809  if( update ) {
810  loop22.addStatement( rk_diffK_local.getElement(tmp_index2,index2) += rk_b.getElement(tmp_index3,1+index1) );
811  }
812  else {
813  loop22.addStatement( rk_diffK_local.getElement(tmp_index2,index2) == rk_b.getElement(tmp_index3,1+index1) );
814  }
815  loop21.addStatement( loop22 );
816 
817  ExportForLoop loop23( index1,0,NU );
818  loop23.addStatement( tmp_index2 == tmp_index1+NX+index1 );
819  if( update ) {
820  loop23.addStatement( rk_diffK_local.getElement(tmp_index2,index2) += rk_b.getElement(tmp_index3,1+NX+index1) );
821  }
822  else {
823  loop23.addStatement( rk_diffK_local.getElement(tmp_index2,index2) == rk_b.getElement(tmp_index3,1+NX+index1) );
824  }
825  loop21.addStatement( loop23 );
826  loop20.addStatement( loop21 );
827  block->addStatement( loop20 );
828 
829  // update rk_diffK USING RK_DIFFK_LOCAL !! (PROPAGATION OF SENSITIVITIES)
830  ExportForLoop loop40( index2,0,numStages );
831  ExportForLoop loop41( index3,0,NX2 );
832  loop41.addStatement( tmp_index1 == (k_index + NX1 + index3)*(NX+NU) );
833  ExportForLoop loop42( index1,0,NX );
834  loop42.addStatement( tmp_index2 == tmp_index1+index1 );
835  loop42.addStatement( rk_diffK.getElement(tmp_index2,index2) == 0.0 );
836  for( uint loop_i = 0; loop_i < NX; loop_i++ ) {
837  loop42.addStatement( rk_diffK.getElement(tmp_index2,index2) += rk_diffK_local.getElement(tmp_index1+loop_i,index2)*rk_diffsPrev2.getElement(loop_i,index1) );
838  }
839  loop41.addStatement( loop42 );
840  ExportForLoop loop43( index1,0,NU );
841  loop43.addStatement( tmp_index2 == tmp_index1+NX+index1 );
842  loop43.addStatement( rk_diffK.getElement(tmp_index2,index2) == rk_diffK_local.getElement(tmp_index2,index2) );
843  for( uint loop_i = 0; loop_i < NX; loop_i++ ) {
844  loop43.addStatement( rk_diffK.getElement(tmp_index2,index2) += rk_diffK_local.getElement(tmp_index1+loop_i,index2)*rk_diffsPrev2.getElement(loop_i,NX+index1) );
845  }
846  loop41.addStatement( loop43 );
847  loop40.addStatement( loop41 );
848  block->addStatement( loop40 );
849 
850  // update rk_diffsNew with the new sensitivities:
851  ExportForLoop loop3( index2,0,NX2 );
852  loop3.addStatement( tmp_index1 == (k_index + NX1 + index2)*(NX+NU) );
853  ExportForLoop loop31( index1,0,NX2 );
854  loop31.addStatement( tmp_index2 == tmp_index1+index1 );
855  loop31.addStatement( rk_diffsNew2.getElement( index2,index1 ) == rk_diffsPrev2.getElement( index2,index1 ) );
856  loop31.addStatement( rk_diffsNew2.getElement( index2,index1 ) += rk_diffK.getRow( tmp_index2 )*Bh );
857  loop3.addStatement( loop31 );
858 
859  ExportForLoop loop32( index1,0,NU );
860  loop32.addStatement( tmp_index2 == tmp_index1+NX+index1 );
861  loop32.addStatement( rk_diffsNew2.getElement( index2,NX+index1 ) == rk_diffsPrev2.getElement( index2,NX+index1 ) );
862  loop32.addStatement( rk_diffsNew2.getElement( index2,NX+index1 ) += rk_diffK.getRow( tmp_index2 )*Bh );
863  loop3.addStatement( loop32 );
864  block->addStatement( loop3 );
865  if( NXA > 0 ) {
867  }
868  }
869 
870  return SUCCESSFUL_RETURN;
871 }
872 
873 
874 returnValue ForwardBackwardLiftedIRKExport::evaluateRhsInexactSensitivities( ExportStatementBlock* block, const ExportIndex& index1, const ExportIndex& index2, const ExportIndex& index3, const ExportIndex& tmp_index1, const ExportIndex& tmp_index2, const ExportIndex& tmp_index3, const ExportIndex& k_index, const ExportVariable& Ah )
875 {
876  if( NX2 > 0 ) {
877  uint j;
878 
879  ExportForLoop loop1( index2,0,numStages );
880  loop1.addStatement( rk_seed.getCols(0,NX) == rk_stageValues.getCols(index2*(NX+NXA),index2*(NX+NXA)+NX) );
881  DMatrix eyeM = eye<double>(NX);
882  eyeM.appendCols(zeros<double>(NX,NU));
883  loop1.addStatement( rk_seed.getCols(NX,NX+NX*(NX+NU)) == eyeM.makeVector().transpose() );
884 
885  ExportForLoop loop2( index3,0,NX2 );
886  loop2.addStatement( tmp_index1 == k_index + index3 );
887  ExportForLoop loop3( index1,0,NX2 );
888  loop3.addStatement( tmp_index2 == tmp_index1*(NX+NU) + index1 );
889  for( j = 0; j < numStages; j++ ) {
890  loop3.addStatement( rk_seed.getCol( NX+index3*(NX+NU)+index1 ) += Ah.getElement(index2,j)*rk_diffK_local.getElement(tmp_index2,j) );
891  }
892  loop2.addStatement( loop3 );
893 
894  ExportForLoop loop4( index1,0,NU );
895  loop4.addStatement( tmp_index2 == tmp_index1*(NX+NU) + NX + index1 );
896  for( j = 0; j < numStages; j++ ) {
897  loop4.addStatement( rk_seed.getCol( NX+index3*(NX+NU)+NX+index1 ) += Ah.getElement(index2,j)*rk_diffK_local.getElement(tmp_index2,j) );
898  }
899  loop2.addStatement( loop4 );
900  loop1.addStatement( loop2 );
901 
902  if( NDX2 > 0 ) {
904 
905 // ExportForLoop loop5( index3,0,NDX2 );
906 // loop5.addStatement( tmp_index1 == k_index + index3 );
907 // ExportForLoop loop51( index1,0,NX2 );
908 // loop51.addStatement( tmp_index2 == tmp_index1*(NX+NU) + index1 );
909 // loop51.addStatement( rk_seed.getCol( NX+(NX+index3)*(NX+NU)+index1 ) == rk_diffK.getElement(tmp_index2,index2) );
910 // loop5.addStatement( loop51 );
911 //
912 // ExportForLoop loop52( index1,0,NU );
913 // loop52.addStatement( tmp_index2 == tmp_index1*(NX+NU) + NX + index1 );
914 // loop52.addStatement( rk_seed.getCol( NX+(NX+index3)*(NX+NU)+NX+index1 ) == rk_diffK.getElement(tmp_index2,index2) );
915 // loop5.addStatement( loop52 );
916 // loop1.addStatement( loop5 );
917 //
918 // loop1.addStatement( rk_seed.getCols(NX+(NX+NDX2+NXA)*(NX+NU)+NXA+NU+NOD,rk_seed.getNumCols()) == rk_kkk.getSubMatrix( k_index,k_index+NX,index2,index2+1 ).getTranspose() );
919  }
920 
921  if( NXA > 0 ) {
923 
924 // ExportForLoop loop6( index3,0,NXA );
925 // loop6.addStatement( tmp_index1 == k_index + NX + index3 );
926 // ExportForLoop loop61( index1,0,NX2 );
927 // loop61.addStatement( tmp_index2 == tmp_index1*(NX+NU) + index1 );
928 // loop61.addStatement( rk_seed.getCol( NX+(NX+NDX2+index3)*(NX+NU)+index1 ) == rk_diffK.getElement(tmp_index2,index2) );
929 // loop6.addStatement( loop61 );
930 //
931 // ExportForLoop loop62( index1,0,NU );
932 // loop62.addStatement( tmp_index2 == tmp_index1*(NX+NU) + NX + index1 );
933 // loop62.addStatement( rk_seed.getCol( NX+(NX+NDX2+index3)*(NX+NU)+NX+index1 ) == rk_diffK.getElement(tmp_index2,index2) );
934 // loop6.addStatement( loop62 );
935 // loop1.addStatement( loop6 );
936 //
937 // loop1.addStatement( rk_seed.getCols(NX+(NX+NDX2+NXA)*(NX+NU),NX+(NX+NDX2+NXA)*(NX+NU)+NXA) == rk_stageValues.getCols(index2*(NX+NXA)+NX,index2*(NX+NXA)+NX+NXA) );
938  }
939 
941 
942  ExportForLoop loop02( index3,0,NX2+NXA );
943  loop02.addStatement( tmp_index1 == k_index + index3 );
944  loop02.addStatement( tmp_index3 == index2*(NX2+NXA)+index3 );
945  ExportForLoop loop03( index1,0,NX2 );
946  loop03.addStatement( tmp_index2 == tmp_index1*(NX+NU) + index1 );
947  loop03.addStatement( rk_b.getElement( tmp_index3,1+index1 ) == 0.0 - rk_diffsTemp2.getElement( index3,index1 ) );
948  if( NDX2 == 0 ) loop03.addStatement( rk_b.getElement( tmp_index3,1+index1 ) += rk_diffK_local.getElement(tmp_index2,index2) );
949  else return ACADOERROR( RET_NOT_IMPLEMENTED_YET );
950  loop02.addStatement( loop03 );
951 
952  ExportForLoop loop04( index1,0,NU );
953  loop04.addStatement( tmp_index2 == tmp_index1*(NX+NU) + NX + index1 );
954  loop04.addStatement( rk_b.getElement( tmp_index3,1+NX+index1 ) == 0.0 - rk_diffsTemp2.getElement( index3,NX+index1 ) );
955  if( NDX2 == 0 ) loop04.addStatement( rk_b.getElement( tmp_index3,1+NX+index1 ) += rk_diffK_local.getElement(tmp_index2,index2) );
956  else return ACADOERROR( RET_NOT_IMPLEMENTED_YET );
957  loop02.addStatement( loop04 );
958  loop1.addStatement( loop02 );
959  block->addStatement( loop1 );
960  }
961 
962  return SUCCESSFUL_RETURN;
963 }
964 
965 
967 {
969 
970  int gradientUp;
971  get( LIFTED_GRADIENT_UPDATE, gradientUp );
972  bool gradientUpdate = (bool) gradientUp;
973 
974  diffsDim = NX + NX*(NX+NU) + NX*(NX+NU)+NU*NU;
975  if( gradientUpdate ) diffsDim += NX+NU;
976  inputDim = NX + diffsDim + NU + NOD;
977 
978  int useOMP;
979  get(CG_USE_OPENMP, useOMP);
980  ExportStruct structWspace;
981  structWspace = useOMP ? ACADO_LOCAL : ACADO_WORKSPACE;
982 
983  uint timeDep = 0;
984  if( timeDependant ) timeDep = 1;
985 
986  rk_diffsPrev2 = ExportVariable( "rk_diffsPrev2", NX, NX+NU, REAL, structWspace );
987 
988  rk_eta = ExportVariable( "rk_eta", 1, inputDim, REAL );
989  rk_xxx_lin = ExportVariable( "rk_xxx_lin", 1, NX, REAL, structWspace );
990 
991  rk_b_trans = ExportVariable( "rk_b_trans", 1, numStages*(NX+NXA), REAL, structWspace );
992 
993  rk_adj_diffs_tmp = ExportVariable( "rk_adjoint", 1, NX + (NX+NU)*(NX+NU), REAL, structWspace );
994  if( gradientUpdate ) {
995  rk_adj_diffs_tmp = ExportVariable( "rk_adjoint", 1, NX + (NX+NU)*(NX+NU) + NX+NU, REAL, structWspace );
996  rk_Khat_traj = ExportVariable( "rk_Khat", grid.getNumIntervals(), numStages*(NX+NXA), REAL, structWspace );
997 
998  rk_Xhat_traj = ExportVariable( "rk_Xhat", grid.getNumIntervals()*NX, 1, REAL, structWspace );
999  }
1000 
1001  rk_seed = ExportVariable( "rk_seed", 1, NX+NX*(NX+NU)+NX+NU+NOD+timeDep, REAL, structWspace );
1002  if( gradientUpdate ) rk_seed = ExportVariable( "rk_seed", 1, NX+NX*(NX+NU)+2*NX+NU+NOD+timeDep, REAL, structWspace );
1003  rk_Xprev = ExportVariable( "rk_Xprev", N, NX, REAL, ACADO_VARIABLES );
1004  rk_A_traj = ExportVariable( "rk_A_traj", grid.getNumIntervals()*numStages*(NX2+NXA), numStages*(NX2+NXA), REAL, structWspace );
1005  rk_xxx_traj = ExportVariable( "rk_stageV_traj", 1, grid.getNumIntervals()*numStages*(NX+NXA), REAL, structWspace );
1006  rk_S_traj = ExportVariable( "rk_S_traj", grid.getNumIntervals()*NX, NX+NU, REAL, structWspace );
1007 
1008  int linSolver;
1009  get( LINEAR_ALGEBRA_SOLVER, linSolver );
1010  if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
1011 // rk_A = ExportVariable( "rk_J", NX2+NXA, NX2+NXA, REAL, structWspace );
1012 // if(NDX2 > 0) rk_I = ExportVariable( "rk_I", NX2+NXA, NX2+NXA, REAL, structWspace );
1013  rk_A_traj = ExportVariable( "rk_J_traj", grid.getNumIntervals()*(NX2+NXA), NX2+NXA, REAL, structWspace );
1014  rk_diffsTemp2 = ExportVariable( "rk_diffsTemp2", NX2+NXA, NVARS2, REAL, structWspace );
1015 
1017  }
1018 
1019  rk_hess_tmp1 = ExportVariable( "rk_hess1", NX+NU, NX+NU, REAL, structWspace );
1020  rk_hess_tmp2 = ExportVariable( "rk_hess2", NX+NU, NX+NU, REAL, structWspace );
1021  rk_diffK_local = ExportVariable( "rk_diffKtraj_aux", N*grid.getNumIntervals()*(NX+NXA)*(NX+NU), numStages, REAL, structWspace );
1022 
1023  return SUCCESSFUL_RETURN;
1024 }
1025 
1026 
1027 
1028 // PROTECTED:
1029 
1030 
1032 
1033 // end of file.
virtual returnValue getDataDeclarations(ExportStatementBlock &declarations, ExportStruct dataStruct=ACADO_ANY) const
Allows to export a tailored lifted implicit Runge-Kutta integrator with forward sensitivity generatio...
ExportVariable getRow(const ExportIndex &idx) const
ExportVariable rk_diffK
Definition: irk_export.hpp:571
Expression backwardDerivative(const Expression &arg1, const Expression &arg2)
const std::string getNameSolveTransposeReuseFunction()
returnValue initializeDDMatrix()
Definition: irk_export.cpp:864
ExportVariable getGlobalExportVariable() const
double getFirstTime() const
LinearAlgebraSolver
ExportVariable getTranspose() const
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
GenericMatrix & appendCols(const GenericMatrix &_arg)
Definition: matrix.cpp:83
std::vector< Grid > outputGrids
ExportAcadoFunction diffs_rhs
int getNDX() const
Definition: function.cpp:217
virtual returnValue solveImplicitSystem(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2, const ExportIndex &index3, const ExportIndex &tmp_index, const ExportIndex &k_index, const ExportVariable &Ah, const ExportVariable &C, const ExportVariable &det, bool DERIVATIVES=false)
ExportVariable getAuxVariable() const
ExportVariable rk_index
std::vector< ExportAcadoFunction > outputs
ForwardBackwardLiftedIRKExport(UserInteraction *_userInteraction=0, const std::string &_commonHeaderName="")
Allows to pass back messages to the calling function.
ExportVariable rk_kkk
Definition: rk_export.hpp:189
GenericMatrix & makeVector()
Definition: matrix.cpp:124
DifferentialState x
virtual returnValue getCode(ExportStatementBlock &code)
returnValue initializeCoefficients()
Definition: irk_export.cpp:883
Expression forwardDerivative(const Expression &arg1, const Expression &arg2)
ExportLinearSolver * solver
Definition: irk_export.hpp:530
uint getNumCols() const
uint getNumRows() const
returnValue addComment(const std::string &_comment)
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
returnValue updateHessianTerm(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2)
std::vector< ExportAcadoFunction > diffs_outputs
ExportVariable rk_diffsPrev2
Allows to export a tailored lifted implicit Runge-Kutta integrator with forward-over-adjoint second o...
Allows to export code of a for-loop.
Expression getCols(const uint &colIdx1, const uint &colIdx2) const
Definition: expression.cpp:582
string toString(T const &value)
ImplicitIntegratorMode
ExportVariable getElement(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
ExportVariable rk_diffsTemp2
#define CLOSE_NAMESPACE_ACADO
virtual returnValue evaluateRhsSensitivities(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2, const ExportIndex &index3, const ExportIndex &tmp_index1, const ExportIndex &tmp_index2)
ExportVariable getSubMatrix(const ExportIndex &rowIdx1, const ExportIndex &rowIdx2, const ExportIndex &colIdx1, const ExportIndex &colIdx2) const
GenericMatrix< double > DMatrix
Definition: matrix.hpp:457
Defines a scalar-valued index variable to be used for exporting code.
Expression returnLowerTriangular(const Expression &expr)
ExportAcadoFunction rhs3
virtual returnValue copy(const ImplicitRungeKuttaExport &arg)
Base class for all variables within the symbolic expressions family.
Definition: expression.hpp:56
ExportVariable rk_eta
ExportAcadoFunction diffs_rhs3
ExportStruct
virtual returnValue updateImplicitSystem(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2, const ExportIndex &tmp_index)
DVector evaluateDerivedPolynomial(double time)
ExportVariable getCols(const ExportIndex &idx1, const ExportIndex &idx2) const
Expression multipleForwardDerivative(const Expression &arg1, const Expression &arg2, const Expression &seed)
ExportVariable rk_auxSolver
Definition: irk_export.hpp:563
ExportVariable makeRowVector() const
const std::string getNameSolveReuseFunction()
virtual returnValue evaluateAllStatesImplicitSystem(ExportStatementBlock *block, const ExportIndex &k_index, const ExportVariable &Ah, const ExportVariable &C, const ExportIndex &stage, const ExportIndex &i, const ExportIndex &tmp_index)
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
Expression & appendRows(const Expression &arg)
Definition: expression.cpp:141
Encapsulates all user interaction for setting options, logging data and plotting results.
virtual returnValue setDifferentialEquation(const Expression &rhs)
virtual uint getDim() const
returnValue addStatement(const ExportStatement &_statement)
int getNT() const
Definition: function.cpp:251
ExportFunction integrate
std::string getFullName() const
returnValue addLinebreak(uint num=1)
ForwardBackwardLiftedIRKExport & operator=(const ForwardBackwardLiftedIRKExport &arg)
#define ASSERT(x)
#define ACADOWARNINGTEXT(retval, text)
ExportVariable rk_diffsNew2
uint getNumIntervals() const
returnValue prepareOutputEvaluation(ExportStatementBlock &code)
ExportVariable rk_xxx
DifferentialStateDerivative dx
std::string getName() const
ExportVariable getRows(const ExportIndex &idx1, const ExportIndex &idx2) const
returnValue addDeclaration(const ExportVariable &_data, ExportStruct _dataStruct=ACADO_ANY)
ExportAcadoFunction lin_input
double getLastTime() const
ExportVariable rk_ttt
std::vector< ExportVariable > rk_outputs
Definition: irk_export.hpp:552
#define BEGIN_NAMESPACE_ACADO
ExportVariable error_code
returnValue clearStaticCounters()
Definition: expression.hpp:398
returnValue addFunction(const ExportFunction &_function)
virtual returnValue clear()
virtual returnValue allSensitivitiesImplicitSystem(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2, const ExportIndex &index3, const ExportIndex &tmp_index1, const ExportIndex &tmp_index2, const ExportIndex &tmp_index3, const ExportIndex &k_index, const ExportVariable &Bh, bool update)
virtual returnValue getCode(ExportStatementBlock &code)=0
virtual returnValue evaluateRhsInexactSensitivities(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2, const ExportIndex &index3, const ExportIndex &tmp_index1, const ExportIndex &tmp_index2, const ExportIndex &tmp_index3, const ExportIndex &k_index, const ExportVariable &Ah)
Allows to export code for a block of statements.
Expression getRows(const uint &rowIdx1, const uint &rowIdx2) const
Definition: expression.cpp:548
ExportArgument getAddress(const ExportIndex &_rowIdx, const ExportIndex &_colIdx=emptyConstExportIndex) const
ExportVariable getCol(const ExportIndex &idx) const
returnValue init(const Function &_f, const std::string &_name="acadoFcn", const uint _numX=0, const uint _numXA=0, const uint _numU=0, const uint _numP=0, const uint _numDX=0, const uint _numOD=0)
ExportFunction & addIndex(const ExportIndex &_index)
#define ACADOERROR(retval)
virtual bool equidistantControlGrid() const
ForwardLiftedIRKExport & operator=(const ForwardLiftedIRKExport &arg)
Defines a matrix-valued variable to be used for exporting code.
ExportAcadoFunction rhs
returnValue addFunctionCall(const std::string &_fName, const ExportArgument &_argument1=emptyConstExportArgument, const ExportArgument &_argument2=emptyConstExportArgument, const ExportArgument &_argument3=emptyConstExportArgument, const ExportArgument &_argument4=emptyConstExportArgument, const ExportArgument &_argument5=emptyConstExportArgument, const ExportArgument &_argument6=emptyConstExportArgument, const ExportArgument &_argument7=emptyConstExportArgument, const ExportArgument &_argument8=emptyConstExportArgument, const ExportArgument &_argument9=emptyConstExportArgument)
virtual returnValue getDataDeclarations(ExportStatementBlock &declarations, ExportStruct dataStruct=ACADO_ANY) const
Allows to setup and evaluate differential equations (ODEs and DAEs) based on SymbolicExpressions.
std::string getName() const
Definition: export_data.cpp:86
uint getDim() const


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