irk_symmetric_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  ) : ForwardIRKExport( _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  }
93 // if( forward_sweep.getGlobalExportVariable().getDim() >= max.getDim() ) {
94 // max = forward_sweep.getGlobalExportVariable();
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  ForwardIRKExport::getDataDeclarations( declarations, dataStruct );
126 
127  declarations.addDeclaration( rk_A_traj,dataStruct );
128  declarations.addDeclaration( rk_aux_traj,dataStruct );
129  declarations.addDeclaration( rk_S_traj,dataStruct );
130  declarations.addDeclaration( rk_xxx_traj,dataStruct );
131 
132  declarations.addDeclaration( rk_b_trans,dataStruct );
133  declarations.addDeclaration( rk_seed,dataStruct );
134  declarations.addDeclaration( rk_adj_diffs_tmp,dataStruct );
135 
136  declarations.addDeclaration( rk_hess_tmp1,dataStruct );
137  declarations.addDeclaration( rk_hess_tmp2,dataStruct );
138 
139 // declarations.addDeclaration( rk_adj_traj,dataStruct );
140 
141 // declarations.addDeclaration( rk_diff_mu,dataStruct );
142 // declarations.addDeclaration( rk_diff_lam,dataStruct );
143 //
144 // declarations.addDeclaration( rk_lambda,dataStruct );
145 // declarations.addDeclaration( rk_b_mu,dataStruct );
146 
147  return SUCCESSFUL_RETURN;
148 }
149 
150 
152  ) const
153 {
155 
156  return SUCCESSFUL_RETURN;
157 }
158 
159 
161 {
162  int sensGen;
163  get( DYNAMIC_SENSITIVITY,sensGen );
164  if( rhs_.getDim() > 0 ) {
165  OnlineData dummy0;
166  Control dummy1;
167  DifferentialState dummy2;
168  AlgebraicState dummy3;
170  dummy0.clearStaticCounters();
171  dummy1.clearStaticCounters();
172  dummy2.clearStaticCounters();
173  dummy3.clearStaticCounters();
174  dummy4.clearStaticCounters();
175 
176  NX2 = rhs_.getDim() - NXA;
177  x = DifferentialState("", NX1+NX2, 1);
178  z = AlgebraicState("", NXA, 1);
179  u = Control("", NU, 1);
180  od = OnlineData("", NOD, 1);
181 
183  f << rhs_;
184 
185  NDX2 = f.getNDX();
186  if( NDX2 > 0 && (NDX2 < NX2 || NDX2 > (NX1+NX2)) ) {
187  return ACADOERROR( RET_INVALID_OPTION );
188  }
189  else if( NDX2 > 0 ) NDX2 = NX1+NX2;
191 
193  for( uint i = 0; i < rhs_.getDim(); i++ ) {
194  g << forwardDerivative( rhs_(i), x );
195  g << forwardDerivative( rhs_(i), z );
196  g << forwardDerivative( rhs_(i), u );
197  g << forwardDerivative( rhs_(i), dx );
198  }
199 
200  // FORWARD SWEEP:
201  DifferentialState sX("", NX,NX+NU);
202  Expression Gx = sX.getCols(0,NX);
203  Expression Gu = sX.getCols(NX,NX+NU);
204 // DifferentialEquation forward;
205 // for( uint i = 0; i < rhs_.getDim(); i++ ) {
206 // // NOT YET IMPLEMENTED FOR DAES OR IMPLICIT ODES
207 // if( NDX2 > 0 || NXA > 0 ) return ACADOERROR(RET_NOT_YET_IMPLEMENTED);
208 // forward << multipleForwardDerivative( rhs_(i), x, Gx );
209 // forward << multipleForwardDerivative( rhs_(i), x, Gu ) + forwardDerivative( rhs_(i), u );
210 // }
211 
212  // FIRST ORDER ADJOINT SWEEP:
213  DifferentialState lambda("", NX,1);
214  DifferentialEquation backward;
215 // , adj_update;
216 // backward << backwardDerivative( rhs_, x, lambda );
217 // adj_update << backwardDerivative( rhs_, x, lambda );
218 
219  // SECOND ORDER ADJOINT SWEEP:
220  Expression arg;
221  arg << x;
222  arg << u;
223  Expression S_tmp = sX;
224  S_tmp.appendRows(zeros<double>(NU,NX).appendCols(eye<double>(NU)));
225 
226  if( NDX2 > 0 || NXA > 0 ) return ACADOERROR(RET_NOT_YET_IMPLEMENTED);
227  if( (ExportSensitivityType)sensGen == SYMMETRIC ) {
228  Expression dfS, dfL;
229  Expression symmetric = symmetricDerivative( rhs_, arg, S_tmp, lambda, &dfS, &dfL );
230  backward << dfL.getRows(0,NX);
231  backward << returnLowerTriangular( symmetric );
232  }
233  else if( (ExportSensitivityType)sensGen == FORWARD_OVER_BACKWARD ) {
234  Expression tmp = backwardDerivative( rhs_, arg, lambda );
235  backward << tmp.getRows(0,NX);
236  backward << multipleForwardDerivative( tmp, arg, S_tmp );
237  }
238  else {
240  }
241 
242  // GRADIENT UPDATE:
243 // int gradientUp;
244 // get( LIFTED_GRADIENT_UPDATE, gradientUp );
245 // bool gradientUpdate = (bool) gradientUp;
246 
247  uint nHat = 0;
248 // if( gradientUpdate ) {
249 // DifferentialState hat("",1,NX);
250 // Expression tmp = hat.getCols(0,NX)*dfL.getRows(0,NX);
251 // backward << multipleForwardDerivative( tmp, arg, S_tmp );
252 // nHat = hat.getNumCols();
253 // }
254 
255 // int linSolver;
256 // get( LINEAR_ALGEBRA_SOLVER, linSolver );
257 // if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
258 // adj_update << dfL.getRows(0,NX);
259 // }
260 // else if( gradientUpdate ) {
261 // adj_update << (forwardDerivative( dfL, x )).transpose();
262 // }
263 
264  if( f.getNT() > 0 ) timeDependant = true;
265 
266  return (rhs.init( f,"acado_rhs",NX,NXA,NU,NP,NDX,NOD ) &
267  diffs_rhs.init( g,"acado_diffs",NX,NXA,NU,NP,NDX,NOD ) &
268 // forward_sweep.init( forward,"acado_forward",NX*(2+NX+NU)+nHat,NXA,NU,NP,NDX,NOD ) &
269  adjoint_sweep.init( backward,"acado_backward",NX*(2+NX+NU)+nHat,NXA,NU,NP,NDX,NOD ));
270 // diffs_sweep.init( adj_update,"acado_adjoint_update",NX*(2+NX+NU)+nHat,NXA,NU,NP,NDX,NOD ));
271  }
272  return SUCCESSFUL_RETURN;
273 }
274 
275 
277 // std::cout << "returnLowerTriangular with " << expr.getNumRows() << " rows and " << expr.getNumCols() << " columns\n";
278  ASSERT( expr.getNumRows() == expr.getNumCols() );
279 
280  Expression new_expr;
281  for( uint i = 0; i < expr.getNumRows(); i++ ) {
282  for( uint j = 0; j <= i; j++ ) {
283  new_expr << expr(i,j);
284  }
285  }
286  return new_expr;
287 }
288 
289 
291 {
292  int sensGen;
293  get( DYNAMIC_SENSITIVITY, sensGen );
294  int mode;
295  get( IMPLICIT_INTEGRATOR_MODE, mode );
296 // int liftMode;
297 // get( LIFTED_INTEGRATOR_MODE, liftMode );
300 // if( liftMode != 1 && liftMode != 4 ) ACADOERROR( RET_NOT_IMPLEMENTED_YET );
302 
303 // int gradientUp;
304 // get( LIFTED_GRADIENT_UPDATE, gradientUp );
305 // bool gradientUpdate = (bool) gradientUp;
306 
307  // NOTE: liftMode == 4 --> inexact Newton based implementation
308 
310 
311  int useOMP;
312  get(CG_USE_OPENMP, useOMP);
313  if ( useOMP ) ACADOERROR( RET_NOT_IMPLEMENTED_YET );
314 
316 
317  int linSolver;
318  get( LINEAR_ALGEBRA_SOLVER, linSolver );
319  if( exportRhs ) {
320  if( NX2 > 0 || NXA > 0 ) {
321  code.addFunction( rhs );
322  code.addStatement( "\n\n" );
323  code.addFunction( diffs_rhs );
324  code.addStatement( "\n\n" );
325 // if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
326  code.addFunction( diffs_sweep );
327  code.addStatement( "\n\n" );
328 // }
329 // if( liftMode == 4 ) { // ONLY for the inexact Newton based schemes
330 // code.addFunction( forward_sweep );
331 // code.addStatement( "\n\n" );
332 // }
333  code.addFunction( adjoint_sweep );
334  code.addStatement( "\n\n" );
335  }
336 
338 
340  }
341  if( NX2 > 0 || NXA > 0 ) solver->getCode( code );
342  code.addLinebreak(2);
343 
344  int measGrid;
345  get( MEASUREMENT_GRID, measGrid );
346 
347  // export RK scheme
348  uint run5, run6;
349  std::string tempString;
350 
353 
354  double h = (grid.getLastTime() - grid.getFirstTime())/grid.getNumIntervals();
355  DMatrix tmp = AA;
356  ExportVariable Ah( "Ah_mat", tmp*=h, STATIC_CONST_REAL );
357  code.addDeclaration( Ah );
358  code.addLinebreak( 2 );
359  // TODO: Ask Milan why this does NOT work properly !!
361 
362  DVector BB( bb );
363  ExportVariable Bh( "Bh_mat", DMatrix( BB*=h ) );
364 
365  DVector CC( cc );
366  ExportVariable C;
367  if( timeDependant ) {
368  C = ExportVariable( "C_mat", DMatrix( CC*=(1.0/grid.getNumIntervals()) ), STATIC_CONST_REAL );
369  code.addDeclaration( C );
370  code.addLinebreak( 2 );
372  }
373 
374  code.addComment(std::string("Fixed step size:") + toString(h));
375 
376  ExportVariable determinant( "det", 1, 1, REAL, ACADO_LOCAL, true );
377  integrate.addDeclaration( determinant );
378 
379  ExportIndex i( "i" );
380  ExportIndex j( "j" );
381  ExportIndex k( "k" );
382  ExportIndex run( "run" );
383  ExportIndex run1( "run1" );
384  ExportIndex tmp_index1("tmp_index1");
385  ExportIndex tmp_index2("tmp_index2");
386 // ExportIndex tmp_index3("tmp_index3");
387 // ExportIndex tmp_index4("tmp_index4");
388 // ExportIndex shooting_index("shoot_index");
389  ExportVariable tmp_meas("tmp_meas", 1, outputGrids.size(), INT, ACADO_LOCAL);
390 
391  ExportVariable numInt( "numInts", 1, 1, INT );
392  if( !equidistantControlGrid() ) {
393  ExportVariable numStepsV( "numSteps", numSteps, STATIC_CONST_INT );
394  code.addDeclaration( numStepsV );
395  code.addLinebreak( 2 );
396  integrate.addStatement( std::string( "int " ) + numInt.getName() + " = " + numStepsV.getName() + "[" + rk_index.getName() + "];\n" );
397  }
398 
399  prepareOutputEvaluation( code );
400 
401  integrate.addIndex( i );
402  integrate.addIndex( j );
403  integrate.addIndex( k );
404  integrate.addIndex( run );
405  integrate.addIndex( run1 );
406  integrate.addIndex( tmp_index1 );
407  integrate.addIndex( tmp_index2 );
408 // integrate.addIndex( tmp_index3 );
409 // integrate.addIndex( shooting_index );
410 // if( rk_outputs.size() > 0 && (grid.getNumIntervals() > 1 || !equidistantControlGrid()) ) {
411 // integrate.addIndex( tmp_index4 );
412 // }
413 // integrate << shooting_index.getFullName() << " = " << rk_index.getFullName() << ";\n";
415  if( (inputDim-diffsDim) > NX+NXA ) {
417 // if( !gradientUpdate )
419 // else integrate.addStatement( rk_seed.getCols( 3*NX+NX*(NX+NU),2*NX+NX*(NX+NU)+inputDim-diffsDim ) == rk_eta.getCols( NX+NXA+diffsDim,inputDim ) );
420  }
422 
423  // integrator FORWARD loop:
424  integrate.addComment("------------ Forward loop ------------:");
425  ExportForLoop tmpLoop( run, 0, grid.getNumIntervals() );
426  ExportStatementBlock *loop;
427  if( equidistantControlGrid() ) {
428  loop = &tmpLoop;
429  }
430  else {
431  loop = &integrate;
432  loop->addStatement( std::string("for(") + run.getName() + " = 0; " + run.getName() + " < " + numInt.getName() + "; " + run.getName() + "++ ) {\n" );
433  }
434 
435  // Set rk_diffsPrev:
436  loop->addStatement( std::string("if( run > 0 ) {\n") );
437  if( NX2 > 0 ) {
438  ExportForLoop loopTemp2( i,0,NX2 );
439  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 ) );
440  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 ) );
441  loop->addStatement( loopTemp2 );
442  }
443  loop->addStatement( std::string("}\nelse{\n") );
444  DMatrix eyeM = eye<double>(NX);
445  eyeM.appendCols(zeros<double>(NX,NU));
446  loop->addStatement( rk_diffsPrev2 == eyeM );
447  loop->addStatement( std::string("}\n") );
448 
449  // SAVE rk_diffsPrev2 in the rk_S_traj variable:
450  loop->addStatement( rk_S_traj.getRows(run*NX,(run+1)*NX) == rk_diffsPrev2 );
451 
452  // PART 2: The fully implicit system
453  loop->addStatement( tmp_index2 == run*(NX+NXA) );
454  solveImplicitSystem( loop, i, run1, j, tmp_index1, tmp_index2, Ah, C, determinant, true );
455 
456  // Evaluate all stage values for reuse:
457  evaluateAllStatesImplicitSystem( loop, tmp_index2, Ah, C, run1, j, tmp_index1, i );
458 
459  // DERIVATIVES wrt the states (IFT):
460  if( NX2 > 0 ) {
461  ExportForLoop loop4( run1,NX1,NX1+NX2 );
462  // PART 2: The fully implicit system
463  sensitivitiesImplicitSystem( &loop4, run1, i, j, tmp_index1, tmp_index2, run, Ah, Bh, determinant, true, 2 );
464  loop->addStatement( loop4 );
465  }
466 
467  // DERIVATIVES wrt the control inputs (IFT):
468  if( NU > 0 ) {
469  ExportForLoop loop5( run1,0,NU );
470  // PART 2: The fully implicit system
471  sensitivitiesImplicitSystem( &loop5, run1, i, j, tmp_index1, tmp_index2, run, Ah, Bh, determinant, false, 0 );
472  loop->addStatement( loop5 );
473  }
474 
475  // SAVE rk_A in the rk_A_traj variable:
476  loop->addStatement( rk_A_traj.getRows(run*numStages*(NX2+NXA),(run+1)*numStages*(NX2+NXA)) == rk_A );
477  loop->addStatement( rk_aux_traj.getRow(run) == rk_auxSolver.makeRowVector() );
478 
479 // // update rk_diffsNew with the new sensitivities:
480 // ExportForLoop loop3( i,0,NX2 );
481 // loop3.addStatement( tmp_index1 == (run*(NX+NXA) + NX1 + i)*(NX+NU) );
482 // ExportForLoop loop31( j,0,NX2+NU );
483 // loop31.addStatement( tmp_index2 == tmp_index1+j );
484 // loop31.addStatement( rk_diffsNew2.getElement( i,j ) == rk_diffsPrev2.getElement( i,j ) );
485 // loop31.addStatement( rk_diffsNew2.getElement( i,j ) += rk_diffK.getRow( tmp_index2 )*Bh );
486 // loop3.addStatement( loop31 );
487 // loop->addStatement( loop3 );
488 //
489 // if( NXA > 0 ) {
490 // DMatrix tempCoefs( evaluateDerivedPolynomial( 0.0 ) );
491 // if( !equidistantControlGrid() || grid.getNumIntervals() > 1 ) {
492 // loop->addStatement( std::string("if( run == 0 ) {\n") );
493 // }
494 // ExportForLoop loop5( i,0,NXA );
495 // loop5.addStatement( tmp_index1 == (run*(NX+NXA) + NX + i)*(NX+NU) );
496 // ExportForLoop loop51( j,0,NX2+NU );
497 // loop51.addStatement( tmp_index2 == tmp_index1+j );
498 // loop51.addStatement( rk_diffsNew2.getElement( i+NX2,j ) == rk_diffK.getRow( tmp_index2 )*tempCoefs );
499 // loop5.addStatement( loop51 );
500 // loop->addStatement( loop5 );
501 // if( !equidistantControlGrid() || grid.getNumIntervals() > 1 ) {
502 // loop->addStatement( std::string("}\n") );
503 // }
504 // }
505 
506  // update rk_eta:
507  for( run5 = 0; run5 < NX; run5++ ) {
508  loop->addStatement( rk_eta.getCol( run5 ) += rk_kkk.getRow( run*(NX+NXA)+run5 )*Bh );
509  }
510  if( NXA > 0) {
511  DMatrix tempCoefs( evaluateDerivedPolynomial( 0.0 ) );
512  if( !equidistantControlGrid() || grid.getNumIntervals() > 1 ) {
513  loop->addStatement( std::string("if( run == 0 ) {\n") );
514  }
515  for( run5 = 0; run5 < NXA; run5++ ) {
516  loop->addStatement( rk_eta.getCol( NX+run5 ) == rk_kkk.getRow( run*(NX+NXA)+NX+run5 )*tempCoefs );
517  }
518  if( !equidistantControlGrid() || grid.getNumIntervals() > 1 ) {
519  loop->addStatement( std::string("}\n") );
520  }
521  }
522 
523  // Computation of the sensitivities using the CHAIN RULE:
524  if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) {
525  loop->addStatement( std::string( "if( run == 0 ) {\n" ) );
526  }
527  // PART 2
528  updateImplicitSystem(loop, i, j, tmp_index2);
529 
530  if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) {
531  loop->addStatement( std::string( "}\n" ) );
532  loop->addStatement( std::string( "else {\n" ) );
533  // PART 2
534  propagateImplicitSystem(loop, i, j, k, tmp_index2);
535  }
536 
537  if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) {
538  loop->addStatement( std::string( "}\n" ) );
539  }
540 
541  loop->addStatement( std::string( reset_int.get(0,0) ) + " = 0;\n" );
542 
543  loop->addStatement( rk_ttt += DMatrix(1.0/grid.getNumIntervals()) );
544 
545  // end of the forward integrator loop.
546  if( !equidistantControlGrid() ) {
547  loop->addStatement( "}\n" );
548  }
549  else {
550  integrate.addStatement( *loop );
551  }
552 
553  // integrator BACKWARD loop:
554  integrate.addComment("------------ BACKWARD loop ------------:");
555  // set current Hessian to zero
556  uint numX = NX*(NX+1)/2.0;
557  uint numU = NU*(NU+1)/2.0;
558  DMatrix zeroM;
559  if( (ExportSensitivityType)sensGen == SYMMETRIC ) {
560  zeroM = zeros<double>(1,numX+numU+NX*NU);
561  }
562  else {
563  zeroM = zeros<double>(1,NX*(NX+NU)+NU*NU);
564  }
565  integrate.addStatement( rk_eta.getCols(NX*(2+NX+NU),NX+diffsDim) == zeroM );
566  ExportForLoop tmpLoop2( run, grid.getNumIntervals()-1, -1, -1 );
567  ExportStatementBlock *loop2;
568  if( equidistantControlGrid() ) {
569  loop2 = &tmpLoop2;
570  }
571  else {
573  }
574 
575 
576  // Compute \hat{lambda}:
577  // vec(j*NX+1:j*NX+NX) = -Bh_vec(j+1)*dir_tmp;
578  for( run5 = 0; run5 < numStages; run5++ ) {
579  DMatrix zeroV = zeros<double>(1,NX);
580  loop2->addStatement( rk_b_trans.getCols(run5*NX,(run5+1)*NX) == zeroV );
581  loop2->addStatement( rk_b_trans.getCols(run5*NX,(run5+1)*NX) -= Bh.getRow(run5)*rk_eta.getCols(NX,2*NX) );
582  }
583  loop2->addFunctionCall( solver->getNameSolveTransposeReuseFunction(),rk_A_traj.getAddress(run*numStages*(NX+NXA),0),rk_b_trans.getAddress(0,0),rk_aux_traj.getAddress(run,0) );
584 
585  if( (ExportSensitivityType)sensGen == FORWARD_OVER_BACKWARD ) {
586  zeroM = zeros<double>(NX+NU,NX+NU);
587  loop2->addStatement( rk_hess_tmp1 == zeroM );
588  }
589  for( run5 = 0; run5 < numStages; run5++ ) {
590  loop2->addStatement( rk_seed.getCols(0,NX) == rk_xxx_traj.getCols((run*numStages+run5)*(NX2+NXA),(run*numStages+run5+1)*(NX2+NXA)) );
591  loop2->addStatement( rk_diffsPrev2 == rk_S_traj.getRows(run*NX,(run+1)*NX) );
592 
593  ExportForLoop diffLoop1( i, 0, NX );
594  diffLoop1.addStatement( tmp_index1 == (run*(NX+NXA)+i)*(NX+NU) );
595  ExportForLoop diffLoop2( j, 0, NX+NU );
596  diffLoop2.addStatement( tmp_index2 == tmp_index1+j );
597  for( run6 = 0; run6 < numStages; run6++ ) {
598  diffLoop2.addStatement( rk_diffsPrev2.getElement(i,j) += Ah.getElement(run5,run6)*rk_diffK.getElement( tmp_index2,run6 ) );
599  }
600  diffLoop1.addStatement( diffLoop2 );
601  loop2->addStatement( diffLoop1 );
602 
603  loop2->addStatement( rk_seed.getCols(NX,NX*(1+NX+NU)) == rk_diffsPrev2.makeRowVector() );
604  loop2->addStatement( rk_seed.getCols(NX*(1+NX+NU),NX*(2+NX+NU)) == rk_b_trans.getCols(run5*NX,(run5+1)*NX) );
605  loop2->addFunctionCall( adjoint_sweep.getName(), rk_seed, rk_adj_diffs_tmp.getAddress(0,0) );
606  loop2->addStatement( rk_eta.getCols(NX,2*NX) += rk_adj_diffs_tmp.getCols(0,NX) );
607  if( (ExportSensitivityType)sensGen == SYMMETRIC ) {
608  loop2->addStatement( rk_eta.getCols(NX*(2+NX+NU),NX+diffsDim) += rk_adj_diffs_tmp.getCols(NX,NX+numX+numU+NX*NU) );
609  }
610  else {
611  for( run6 = 0; run6 < NX+NU; run6++ ) {
612  loop2->addStatement( rk_hess_tmp2.getRow(run6) == rk_adj_diffs_tmp.getCols(NX+run6*(NX+NU),NX+(run6+1)*(NX+NU)) );
613  }
614  // compute the local derivatives in rk_diffsPrev2
615  loop2->addStatement( rk_diffsPrev2 == eyeM );
616  ExportForLoop diffLoop3( i, 0, NX );
617  diffLoop3.addStatement( tmp_index1 == (run*(NX+NXA)+i)*(NX+NU) );
618  ExportForLoop diffLoop4( j, 0, NX+NU );
619  diffLoop4.addStatement( tmp_index2 == tmp_index1+j );
620  for( run6 = 0; run6 < numStages; run6++ ) {
621  diffLoop4.addStatement( rk_diffsPrev2.getElement(i,j) += Ah.getElement(run5,run6)*rk_diffK.getElement( tmp_index2,run6 ) );
622  }
623  diffLoop3.addStatement( diffLoop4 );
624  loop2->addStatement( diffLoop3 );
625 
626  // update of rk_hess_tmp2 from the left and add it to rk_hess_tmp1
627  updateHessianTerm( loop2, i, j );
628  }
629  }
630 
631  if( (ExportSensitivityType)sensGen == FORWARD_OVER_BACKWARD ) {
632  for( run6 = 0; run6 < NX; run6++ ) { // NX_NX
633  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) );
634  }
635  for( run6 = 0; run6 < NX; run6++ ) { // NX_NU
636  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) );
637  loop2->addStatement( rk_hess_tmp2.getSubMatrix(NX,NX+NU,run6,run6+1) == rk_hess_tmp2.getSubMatrix(run6,run6+1,NX,NX+NU).getTranspose() );
638  }
639  for( run6 = 0; run6 < NU; run6++ ) { // NU_NU
640  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) );
641  }
642 
643  // compute the local result derivatives in rk_diffsPrev2
644  loop2->addStatement( rk_diffsPrev2 == eyeM );
645  ExportForLoop diffLoop5( i, 0, NX );
646  diffLoop5.addStatement( tmp_index1 == (run*(NX+NXA)+i)*(NX+NU) );
647  ExportForLoop diffLoop6( j, 0, NX+NU );
648  diffLoop6.addStatement( tmp_index2 == tmp_index1+j );
649  diffLoop6.addStatement( rk_diffsPrev2.getElement(i,j) += rk_diffK.getRow( tmp_index2 )*Bh );
650  diffLoop5.addStatement( diffLoop6 );
651  loop2->addStatement( diffLoop5 );
652  updateHessianTerm( loop2, i, j );
653 
654  // UPDATE HESSIAN RESULT
655  for( run6 = 0; run6 < NX; run6++ ) { // NX_NX
656  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) );
657  }
658  for( run6 = 0; run6 < NX; run6++ ) { // NX_NU
659  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) );
660  }
661  for( run6 = 0; run6 < NU; run6++ ) { // NU_NU
662  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) );
663  }
664  }
665 
666  loop2->addStatement( rk_ttt -= DMatrix(1.0/grid.getNumIntervals()) );
667  // end of the backward integrator loop.
668  if( !equidistantControlGrid() ) {
670  }
671  else {
672  integrate.addStatement( *loop2 );
673  }
674 
675 // integrate.addStatement( std::string( "if( " ) + determinant.getFullName() + " < 1e-12 ) {\n" );
676 // integrate.addStatement( error_code == 2 );
677 // integrate.addStatement( std::string( "} else if( " ) + determinant.getFullName() + " < 1e-6 ) {\n" );
678 // integrate.addStatement( error_code == 1 );
679 // integrate.addStatement( std::string( "} else {\n" ) );
681 // integrate.addStatement( std::string( "}\n" ) );
682 
683  code.addFunction( integrate );
684  code.addLinebreak( 2 );
685 
686  return SUCCESSFUL_RETURN;
687 }
688 
689 
691  ExportForLoop loop1( i, 0, NX );
692  ExportForLoop loop2( j, 0, NX+NU );
693  for( uint index = 0; index < NX; index++ ) {
695  }
696  loop1.addStatement( loop2 );
697  block->addStatement( loop1 );
698 
699  ExportForLoop loop3( i, 0, NU );
700  ExportForLoop loop4( j, 0, NX+NU );
701  loop4.addStatement( rk_hess_tmp1.getElement(NX+i,j) += rk_hess_tmp2.getElement(NX+i,j) );
702  for( uint index = 0; index < NX; index++ ) {
703  loop4.addStatement( rk_hess_tmp1.getElement(NX+i,j) += rk_diffsPrev2.getElement(index,NX+i)*rk_hess_tmp2.getElement(index,j) );
704  }
705  loop3.addStatement( loop4 );
706  block->addStatement( loop3 );
707 
708  return SUCCESSFUL_RETURN;
709 }
710 
711 
713 {
714  ExportForLoop loop0( stage,0,numStages );
715  ExportForLoop loop1( i, 0, NX1+NX2 );
716  loop1.addStatement( tmp_index == k_index*numStages + stage*(NX+NXA) );
717  loop1.addStatement( tmp_index2 == k_index+i );
718  loop1.addStatement( rk_xxx_traj.getCol( tmp_index+i ) == rk_eta.getCol( i ) );
719  for( uint j = 0; j < numStages; j++ ) {
720  loop1.addStatement( rk_xxx_traj.getCol( tmp_index+i ) += Ah.getElement(stage,j)*rk_kkk.getElement( tmp_index2,j ) );
721  }
722  loop0.addStatement( loop1 );
723 
724  ExportForLoop loop3( i, 0, NXA );
725  loop3.addStatement( tmp_index == k_index*numStages + stage*(NX+NXA)+NX );
726  loop3.addStatement( tmp_index2 == k_index+NX+i );
727  loop3.addStatement( rk_xxx_traj.getCol( tmp_index+i ) == rk_kkk.getElement( tmp_index2,stage ) );
728  loop0.addStatement( loop3 );
729  block->addStatement( loop0 );
730 
731  return SUCCESSFUL_RETURN;
732 }
733 
734 
736 {
737  if( NX2 > 0 ) {
738  ExportForLoop loop01( index1,NX1,NX1+NX2 );
739  ExportForLoop loop02( index2,0,NX1+NX2 );
740  loop02.addStatement( tmp_index == index2+index1*NX );
741  loop02.addStatement( rk_eta.getCol( tmp_index+2*NX+NXA ) == rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,index2,index2+1 ) );
742  loop01.addStatement( loop02 );
743 
744  if( NU > 0 ) {
745  ExportForLoop loop03( index2,0,NU );
746  loop03.addStatement( tmp_index == index2+index1*NU );
747  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 ) );
748  loop01.addStatement( loop03 );
749  }
750  block->addStatement( loop01 );
751  }
752  // ALGEBRAIC STATES
753  if( NXA > 0 ) {
754  ExportForLoop loop01( index1,NX,NX+NXA );
755  ExportForLoop loop02( index2,0,NX1+NX2 );
756  loop02.addStatement( tmp_index == index2+index1*NX );
757  loop02.addStatement( rk_eta.getCol( tmp_index+2*NX+NXA ) == rk_diffsNew2.getSubMatrix( index1-NX1-NX3,index1-NX1-NX3+1,index2,index2+1 ) );
758  loop01.addStatement( loop02 );
759 
760  if( NU > 0 ) {
761  ExportForLoop loop03( index2,0,NU );
762  loop03.addStatement( tmp_index == index2+index1*NU );
763  loop03.addStatement( rk_eta.getCol( tmp_index+(NX+NXA)*(1+NX)+NX ) == rk_diffsNew2.getSubMatrix( index1-NX1-NX3,index1-NX1-NX3+1,NX1+NX2+index2,NX1+NX2+index2+1 ) );
764  loop01.addStatement( loop03 );
765  }
766  block->addStatement( loop01 );
767  }
768 
769  return SUCCESSFUL_RETURN;
770 }
771 
772 
774  const ExportIndex& _index3, const ExportIndex& tmp_index )
775 {
776  uint index3; // index3 instead of _index3 to unroll loops
777  if( NX2 > 0 ) {
778  ExportForLoop loop01( index1,NX1,NX1+NX2 );
779  if( NX1 > 0 ) {
780  ExportForLoop loop02( index2,0,NX1 );
781  loop02.addStatement( tmp_index == index2+index1*NX );
782  loop02.addStatement( rk_eta.getCol( tmp_index+2*NX+NXA ) == rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,0,1 )*rk_diffsPrev1.getSubMatrix( 0,1,index2,index2+1 ) );
783  for( index3 = 1; index3 < NX1; index3++ ) {
784  loop02.addStatement( rk_eta.getCol( tmp_index+2*NX+NXA ) += rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,index3,index3+1 )*rk_diffsPrev1.getSubMatrix( index3,index3+1,index2,index2+1 ) );
785  }
786  for( index3 = 0; index3 < NX2; index3++ ) {
787  loop02.addStatement( rk_eta.getCol( tmp_index+2*NX+NXA ) += rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,NX1+index3,NX1+index3+1 )*rk_diffsPrev2.getSubMatrix( index3,index3+1,index2,index2+1 ) );
788  }
789  loop01.addStatement( loop02 );
790  }
791 
792  ExportForLoop loop05( index2,NX1,NX1+NX2 );
793  loop05.addStatement( tmp_index == index2+index1*NX );
794  loop05.addStatement( rk_eta.getCol( tmp_index+2*NX+NXA ) == rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,NX1,NX1+1 )*rk_diffsPrev2.getSubMatrix( 0,1,index2,index2+1 ) );
795  for( index3 = 1; index3 < NX2; index3++ ) {
796  loop05.addStatement( rk_eta.getCol( tmp_index+2*NX+NXA ) += rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,NX1+index3,NX1+index3+1 )*rk_diffsPrev2.getSubMatrix( index3,index3+1,index2,index2+1 ) );
797  }
798  loop01.addStatement( loop05 );
799 
800  if( NU > 0 ) {
801  ExportForLoop loop07( index2,0,NU );
802  loop07.addStatement( tmp_index == index2+index1*NU );
803  loop07.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 ) );
804  for( index3 = 0; index3 < NX1; index3++ ) {
805  loop07.addStatement( rk_eta.getCol( tmp_index+(NX+NXA)*(1+NX)+NX ) += rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,index3,index3+1 )*rk_diffsPrev1.getSubMatrix( index3,index3+1,NX1+index2,NX1+index2+1 ) );
806  }
807  for( index3 = 0; index3 < NX2; index3++ ) {
808  loop07.addStatement( rk_eta.getCol( tmp_index+(NX+NXA)*(1+NX)+NX ) += rk_diffsNew2.getSubMatrix( index1-NX1,index1-NX1+1,NX1+index3,NX1+index3+1 )*rk_diffsPrev2.getSubMatrix( index3,index3+1,NX1+NX2+index2,NX1+NX2+index2+1 ) );
809  }
810  loop01.addStatement( loop07 );
811  }
812  block->addStatement( loop01 );
813  }
814  // ALGEBRAIC STATES: NO PROPAGATION OF SENSITIVITIES NEEDED
815 
816  return SUCCESSFUL_RETURN;
817 }
818 
819 
820 returnValue SymmetricIRKExport::sensitivitiesImplicitSystem( ExportStatementBlock* block, const ExportIndex& index1, const ExportIndex& index2, const ExportIndex& index3, const ExportIndex& tmp_index1, const ExportIndex& tmp_index2, const ExportIndex& stepI, const ExportVariable& Ah, const ExportVariable& Bh, const ExportVariable& det, bool STATES, uint number )
821 {
822  if( NX2 > 0 ) {
823  DMatrix zeroM = zeros<double>( NX2+NXA,1 );
824  DMatrix tempCoefs( evaluateDerivedPolynomial( 0.0 ) );
825  uint i;
826 
827  ExportForLoop loop1( index2,0,numStages );
828  if( STATES && number == 1 ) {
829 // ExportForLoop loop2( index3,0,NX1 );
830 // loop2.addStatement( std::string(rk_rhsTemp.get( index3,0 )) + " = -(" + index3.getName() + " == " + index1.getName() + ");\n" );
831 // for( i = 0; i < numStages; i++ ) {
832 // loop2.addStatement( rk_rhsTemp.getRow( index3 ) -= rk_diffK.getElement( index3,i )*Ah.getElement(index2,i) );
833 // }
834 // loop1.addStatement( loop2 );
835  ExportForLoop loop3( index3,0,NX2+NXA );
836  loop3.addStatement( tmp_index1 == index2*(NX2+NXA)+index3 );
837  loop3.addStatement( rk_b.getRow( tmp_index1 ) == rk_diffsTemp2.getSubMatrix( index2,index2+1,index3*(NVARS2),index3*(NVARS2)+NX1 )*rk_rhsTemp.getRows(0,NX1) );
838 // if( NDX2 > 0 ) {
839 // loop3.addStatement( rk_b.getRow( tmp_index1 ) -= rk_diffsTemp2.getSubMatrix( index2,index2+1,index3*(NVARS2)+NVARS2-NX1-NX2,index3*(NVARS2)+NVARS2-NX2 )*rk_diffK.getSubMatrix( 0,NX1,index2,index2+1 ) );
840 // }
841  loop1.addStatement( loop3 );
842  }
843  else if( STATES && number == 2 ) {
844  for( i = 0; i < NX2+NXA; i++ ) {
845  loop1.addStatement( rk_b.getRow( index2*(NX2+NXA)+i ) == zeroM.getRow( 0 ) - rk_diffsTemp2.getElement( index2,index1+i*(NVARS2) ) );
846  }
847  }
848  else { // ~= STATES
849 // ExportForLoop loop2( index3,0,NX1 );
850 // loop2.addStatement( rk_rhsTemp.getRow( index3 ) == rk_diffK.getElement( index3,0 )*Ah.getElement(index2,0) );
851 // for( i = 1; i < numStages; i++ ) {
852 // loop2.addStatement( rk_rhsTemp.getRow( index3 ) += rk_diffK.getElement( index3,i )*Ah.getElement(index2,i) );
853 // }
854 // loop1.addStatement( loop2 );
855  ExportForLoop loop3( index3,0,NX2+NXA );
856  loop3.addStatement( tmp_index1 == index2*(NX2+NXA)+index3 );
857  loop3.addStatement( tmp_index2 == index1+index3*(NVARS2) );
858  loop3.addStatement( rk_b.getRow( tmp_index1 ) == zeroM.getRow( 0 ) - rk_diffsTemp2.getElement( index2,tmp_index2+NX1+NX2+NXA ) );
859  loop3.addStatement( rk_b.getRow( tmp_index1 ) -= rk_diffsTemp2.getSubMatrix( index2,index2+1,index3*(NVARS2),index3*(NVARS2)+NX1 )*rk_rhsTemp.getRows(0,NX1) );
860 // if( NDX2 > 0 ) {
861 // loop3.addStatement( rk_b.getRow( tmp_index1 ) -= rk_diffsTemp2.getSubMatrix( index2,index2+1,index3*(NVARS2)+NVARS2-NX1-NX2,index3*(NVARS2)+NVARS2-NX2 )*rk_diffK.getSubMatrix( 0,NX1,index2,index2+1 ) );
862 // }
863  loop1.addStatement( loop3 );
864  }
865  block->addStatement( loop1 );
866  if( STATES && (number == 1 || NX1 == 0) ) {
867  block->addStatement( std::string( "if( 0 == " ) + index1.getName() + " ) {\n" ); // factorization of the new matrix rk_A not yet calculated!
868  block->addStatement( det.getFullName() + " = " + ExportStatement::fcnPrefix + "_" + solver->getNameSolveFunction() + "( " + rk_A.getFullName() + ", " + rk_b.getFullName() + ", " + rk_auxSolver.getFullName() + " );\n" );
869  block->addStatement( std::string( "}\n else {\n" ) );
870  }
872  if( STATES && (number == 1 || NX1 == 0) ) block->addStatement( std::string( "}\n" ) );
873  // update rk_diffK with the new sensitivities:
874  ExportForLoop loop2( index2,0,numStages );
875  for( i = 0; i < NX; i++ ) {
876  if( STATES ) loop2.addStatement( tmp_index1 == (stepI*(NX+NXA)+i)*(NX+NU)+index1);
877  else loop2.addStatement( tmp_index1 == (stepI*(NX+NXA)+i)*(NX+NU)+NX+index1);
878  loop2.addStatement( rk_diffK.getElement(tmp_index1,index2) == rk_b.getRow(index2*NX2+i) );
879  }
880  for( i = 0; i < NXA; i++ ) {
881  if( STATES ) loop2.addStatement( tmp_index1 == (stepI*(NX+NXA)+NX+i)*(NX+NU)+index1);
882  else loop2.addStatement( tmp_index1 == (stepI*(NX+NXA)+NX+i)*(NX+NU)+NX+index1);
883  loop2.addStatement( rk_diffK.getElement(tmp_index1,index2) == rk_b.getRow(numStages*NX+index2*NXA+i) );
884  }
885  block->addStatement( loop2 );
886  // update rk_diffsNew with the new sensitivities:
887  ExportForLoop loop3( index2,0,NX2 );
888  if( STATES && number == 2 ) loop3.addStatement( std::string(rk_diffsNew2.get( index2,index1 )) + " = (" + index2.getName() + " == " + index1.getName() + "-" + toString(NX1) + ");\n" );
889 
890  if( STATES && number == 2 ) {
891  loop3.addStatement( tmp_index1 == (stepI*(NX+NXA)+index2)*(NX+NU));
892  loop3.addStatement( tmp_index2 == tmp_index1+index1);
893  loop3.addStatement( rk_diffsNew2.getElement( index2,index1 ) += rk_diffK.getRow( tmp_index2 )*Bh );
894  }
895  else if( STATES ) return ACADOERROR( RET_INVALID_OPTION );
896  else {
897  loop3.addStatement( tmp_index1 == (stepI*(NX+NXA)+index2)*(NX+NU));
898  loop3.addStatement( tmp_index2 == tmp_index1+NX+index1);
899  loop3.addStatement( rk_diffsNew2.getElement( index2,NX+index1 ) == rk_diffK.getRow( tmp_index2 )*Bh );
900  }
901 // if( STATES && number == 2 ) loop3.addStatement( rk_diffsNew2.getElement( index2,index1 ) += rk_diffK.getRow( NX1+index2 )*Bh );
902 // else if( STATES ) loop3.addStatement( rk_diffsNew2.getElement( index2,index1 ) == rk_diffK.getRow( NX1+index2 )*Bh );
903 // else loop3.addStatement( rk_diffsNew2.getElement( index2,index1+NX1+NX2 ) == rk_diffK.getRow( NX1+index2 )*Bh );
904 
905  block->addStatement( loop3 );
906  if( NXA > 0 ) {
907  if( !equidistantControlGrid() || grid.getNumIntervals() > 1 ) {
908  block->addStatement( std::string("if( run == 0 ) {\n") );
909  }
910  ExportForLoop loop4( index2,0,NXA );
911 
912  if( STATES ) {
913  loop4.addStatement( tmp_index1 == (stepI*(NX+NXA)+NX+index2)*(NX+NU));
914  loop4.addStatement( tmp_index2 == tmp_index1+index1);
915  loop4.addStatement( rk_diffsNew2.getElement( NX+index2,index1 ) == rk_diffK.getRow( tmp_index2 )*tempCoefs );
916  }
917  else {
918  loop4.addStatement( tmp_index1 == (stepI*(NX+NXA)+NX+index2)*(NX+NU));
919  loop4.addStatement( tmp_index2 == tmp_index1+NX+index1);
920  loop4.addStatement( rk_diffsNew2.getElement( NX+index2,NX+index1 ) == rk_diffK.getRow( tmp_index2 )*tempCoefs );
921  }
922 
923 // if( STATES ) loop4.addStatement( rk_diffsNew2.getElement( index2+NX2,index1 ) == rk_diffK.getRow( NX+index2 )*tempCoefs );
924 // else loop4.addStatement( rk_diffsNew2.getElement( index2+NX2,index1+NX1+NX2 ) == rk_diffK.getRow( NX+index2 )*tempCoefs );
925  block->addStatement( loop4 );
926  if( !equidistantControlGrid() || grid.getNumIntervals() > 1 ) {
927  block->addStatement( std::string("}\n") );
928  }
929  }
930  }
931 
932  return SUCCESSFUL_RETURN;
933 }
934 
935 
937 {
939  int sensGen;
940  get( DYNAMIC_SENSITIVITY,sensGen );
941 
942 // int gradientUp;
943 // get( LIFTED_GRADIENT_UPDATE, gradientUp );
944 // bool gradientUpdate = (bool) gradientUp;
945 
946  uint numX = NX*(NX+1)/2.0;
947  uint numU = NU*(NU+1)/2.0;
948  if( (ExportSensitivityType)sensGen == SYMMETRIC ) {
949  diffsDim = NX + NX*(NX+NU) + numX + NX*NU + numU;
950  }
951  else {
952  diffsDim = NX + NX*(NX+NU) + NX*(NX+NU)+NU*NU;
953  }
954 // if( gradientUpdate ) diffsDim += NX+NU;
955  inputDim = NX + diffsDim + NU + NOD;
956 
957  int useOMP;
958  get(CG_USE_OPENMP, useOMP);
959  ExportStruct structWspace;
960  structWspace = useOMP ? ACADO_LOCAL : ACADO_WORKSPACE;
961 
962  uint timeDep = 0;
963  if( timeDependant ) timeDep = 1;
964 
965  rk_eta = ExportVariable( "rk_eta", 1, inputDim, REAL );
966  rk_kkk = ExportVariable( "rk_Ktraj", grid.getNumIntervals()*(NX+NXA), numStages, REAL, structWspace );
967  rk_diffK = ExportVariable( "rk_diffKtraj", grid.getNumIntervals()*(NX+NXA)*(NX+NU), numStages, REAL, structWspace );
968 
969  rk_seed = ExportVariable( "rk_seed", 1, NX+NX*(NX+NU)+NX+NU+NOD+timeDep, REAL, structWspace );
970  rk_b_trans = ExportVariable( "rk_b_trans", 1, numStages*(NX+NXA), REAL, structWspace );
971 
972 // int liftMode;
973 // get( LIFTED_INTEGRATOR_MODE, liftMode );
974 
975  rk_seed = ExportVariable( "rk_seed", 1, NX+NX*(NX+NU)+NX+NU+NOD+timeDep, REAL, structWspace );
976  if( (ExportSensitivityType)sensGen == SYMMETRIC ) {
977  rk_adj_diffs_tmp = ExportVariable( "rk_adjoint", 1, NX + numX + NX*NU + numU, REAL, structWspace );
978  }
979  else {
980  rk_adj_diffs_tmp = ExportVariable( "rk_adjoint", 1, NX + (NX+NU)*(NX+NU), REAL, structWspace );
981  }
982 // if( gradientUpdate ) rk_seed = ExportVariable( "rk_seed", 1, NX+NX*(NX+NU)+2*NX+NU+NOD+timeDep, REAL, structWspace );
983 // rk_A_traj = ExportVariable( "rk_A_traj", grid.getNumIntervals()*numStages*(NX2+NXA), numStages*(NX2+NXA), REAL, structWspace );
984 // rk_aux_traj = ExportVariable( "rk_aux_traj", grid.getNumIntervals(), numStages*(NX2+NXA), INT, structWspace );
985 
986  rk_A_traj = ExportVariable( "rk_A_traj", grid.getNumIntervals()*numStages*(NX2+NXA), numStages*(NX2+NXA), REAL, structWspace );
987  rk_aux_traj = ExportVariable( "rk_aux_traj", grid.getNumIntervals(), numStages*(NX2+NXA), INT, structWspace );
988 
989  rk_xxx_traj = ExportVariable( "rk_stageV_traj", 1, grid.getNumIntervals()*numStages*(NX+NXA), REAL, structWspace );
990  rk_diffsPrev2 = ExportVariable( "rk_diffsPrev2", NX2, NX1+NX2+NU, REAL, structWspace );
991  rk_S_traj = ExportVariable( "rk_S_traj", grid.getNumIntervals()*NX, NX+NU, REAL, structWspace );
992 
993 // int linSolver;
994 // get( LINEAR_ALGEBRA_SOLVER, linSolver );
995 // if( (LinearAlgebraSolver) linSolver == SIMPLIFIED_IRK_NEWTON || (LinearAlgebraSolver) linSolver == SINGLE_IRK_NEWTON ) {
996 // rk_A = ExportVariable( "rk_J", NX2+NXA, NX2+NXA, REAL, structWspace );
997 // if(NDX2 > 0) rk_I = ExportVariable( "rk_I", NX2+NXA, NX2+NXA, REAL, structWspace );
998 // rk_A_traj = ExportVariable( "rk_J_traj", grid.getNumIntervals()*(NX2+NXA), NX2+NXA, REAL, structWspace );
999 // rk_aux_traj = ExportVariable( "rk_aux_traj", grid.getNumIntervals(), rk_auxSolver.getNumRows()*rk_auxSolver.getNumCols(), INT, structWspace );
1000 // rk_diffsTemp2 = ExportVariable( "rk_diffsTemp2", NX2+NXA, NVARS2, REAL, structWspace );
1001 // }
1002 // rk_adj_traj = ExportVariable( "rk_adj_traj", N*grid.getNumIntervals(), numStages*(NX+NXA), REAL, ACADO_VARIABLES );
1003 
1004  rk_hess_tmp1 = ExportVariable( "rk_hess1", NX+NU, NX+NU, REAL, structWspace );
1005  rk_hess_tmp2 = ExportVariable( "rk_hess2", NX+NU, NX+NU, REAL, structWspace );
1006 
1007  return SUCCESSFUL_RETURN;
1008 }
1009 
1010 
1011 
1012 // PROTECTED:
1013 
1014 
1016 
1017 // end of file.
ExportVariable rk_diffsPrev1
virtual returnValue setup()
virtual returnValue setup()
Expression symmetricDerivative(const Expression &arg1, const Expression &arg2, const Expression &forward_seed, const Expression &backward_seed, Expression *forward_result, Expression *backward_result)
ExportAcadoFunction adjoint_sweep
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()
virtual returnValue propagateImplicitSystem(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2, const ExportIndex &_index3, const ExportIndex &tmp_index)
returnValue initializeDDMatrix()
Definition: irk_export.cpp:864
ExportVariable getGlobalExportVariable() const
double getFirstTime() const
virtual returnValue updateImplicitSystem(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2, const ExportIndex &tmp_index)
Expression returnLowerTriangular(const Expression &expr)
ExportVariable getTranspose() const
GenericMatrix & appendCols(const GenericMatrix &_arg)
Definition: matrix.cpp:83
std::vector< Grid > outputGrids
ExportAcadoFunction diffs_rhs
int getNDX() const
Definition: function.cpp:217
ExportVariable rk_index
std::vector< ExportAcadoFunction > outputs
Allows to pass back messages to the calling function.
ExportVariable rk_kkk
Definition: rk_export.hpp:189
DifferentialState x
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
std::vector< ExportAcadoFunction > diffs_outputs
ExportVariable rk_diffsPrev2
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)
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)
Definition: irk_export.cpp:603
ImplicitIntegratorMode
ExportVariable getElement(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
ExportVariable rk_diffsTemp2
ForwardIRKExport & operator=(const ForwardIRKExport &arg)
#define CLOSE_NAMESPACE_ACADO
virtual returnValue sensitivitiesImplicitSystem(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2, const ExportIndex &index3, const ExportIndex &tmp_index1, const ExportIndex &tmp_index2, const ExportIndex &stepI, const ExportVariable &Ah, const ExportVariable &Bh, const ExportVariable &det, bool STATES, uint number)
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, 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.
ExportAcadoFunction rhs3
virtual returnValue copy(const ImplicitRungeKuttaExport &arg)
Base class for all variables within the symbolic expressions family.
Definition: expression.hpp:56
SymmetricIRKExport(UserInteraction *_userInteraction=0, const std::string &_commonHeaderName="")
virtual returnValue setDifferentialEquation(const Expression &rhs)
ExportVariable rk_eta
ExportAcadoFunction diffs_rhs3
ExportStruct
ExportVariable getAuxVariable() const
static std::string fcnPrefix
DVector evaluateDerivedPolynomial(double time)
ExportVariable getCols(const ExportIndex &idx1, const ExportIndex &idx2) const
Expression multipleForwardDerivative(const Expression &arg1, const Expression &arg2, const Expression &seed)
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
ExportVariable rk_auxSolver
Definition: irk_export.hpp:563
ExportVariable makeRowVector() const
const std::string getNameSolveReuseFunction()
ExportAcadoFunction diffs_sweep
const std::string get(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
ExportVariable reset_int
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
virtual returnValue getDataDeclarations(ExportStatementBlock &declarations, ExportStruct dataStruct=ACADO_ANY) const
virtual returnValue getCode(ExportStatementBlock &code)
Expression & appendRows(const Expression &arg)
Definition: expression.cpp:141
Encapsulates all user interaction for setting options, logging data and plotting results.
virtual uint getDim() const
returnValue addStatement(const ExportStatement &_statement)
int getNT() const
Definition: function.cpp:251
ExportFunction integrate
std::string getFullName() const
returnValue updateHessianTerm(ExportStatementBlock *block, const ExportIndex &index1, const ExportIndex &index2)
returnValue addLinebreak(uint num=1)
#define ASSERT(x)
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
const std::string getNameSolveFunction()
#define BEGIN_NAMESPACE_ACADO
ExportVariable error_code
ExportVariable rk_rhsTemp
Definition: irk_export.hpp:564
returnValue clearStaticCounters()
Definition: expression.hpp:398
Allows to export a tailored implicit Runge-Kutta integrator with symmetric second order sensitivity g...
Allows to export a tailored implicit Runge-Kutta integrator with forward sensitivity generation for f...
returnValue addFunction(const ExportFunction &_function)
virtual returnValue clear()
virtual returnValue getCode(ExportStatementBlock &code)=0
virtual returnValue getDataDeclarations(ExportStatementBlock &declarations, ExportStruct dataStruct=ACADO_ANY) const
Allows to export code for a block of statements.
Expression getRows(const uint &rowIdx1, const uint &rowIdx2) const
Definition: expression.cpp:548
SymmetricIRKExport & operator=(const SymmetricIRKExport &arg)
ExportVariable rk_adj_diffs_tmp
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)
GenericVector< T > getRow(unsigned _idx) const
Definition: matrix.hpp:197
ExportFunction & addIndex(const ExportIndex &_index)
#define ACADOERROR(retval)
virtual bool equidistantControlGrid() const
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)
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