returnValue DiscreteTimeExport::setup( ) { int sensGen; get( DYNAMIC_SENSITIVITY,sensGen ); if ( (ExportSensitivityType)sensGen != FORWARD ) ACADOERROR( RET_INVALID_OPTION ); int useOMP; get(CG_USE_OPENMP, useOMP); ExportStruct structWspace; structWspace = useOMP ? ACADO_LOCAL : ACADO_WORKSPACE; LOG( LVL_DEBUG ) << "Preparing to export DiscreteTimeExport... " << endl; ExportIndex run( "run" ); ExportIndex i( "i" ); ExportIndex j( "j" ); ExportIndex k( "k" ); ExportIndex tmp_index("tmp_index"); diffsDim = NX*(NX+NU); inputDim = NX*(NX+NU+1) + NU + NOD; // setup INTEGRATE function rk_index = ExportVariable( "rk_index", 1, 1, INT, ACADO_LOCAL, true ); rk_eta = ExportVariable( "rk_eta", 1, inputDim, REAL ); if( equidistantControlGrid() ) { integrate = ExportFunction( "integrate", rk_eta, reset_int ); } else { integrate = ExportFunction( "integrate", rk_eta, reset_int, rk_index ); } integrate.setReturnValue( error_code ); rk_eta.setDoc( "Working array to pass the input values and return the results." ); reset_int.setDoc( "The internal memory of the integrator can be reset." ); rk_index.setDoc( "Number of the shooting interval." ); error_code.setDoc( "Status code of the integrator." ); integrate.doc( "Performs the integration and sensitivity propagation for one shooting interval." ); integrate.addIndex( run ); integrate.addIndex( i ); integrate.addIndex( j ); integrate.addIndex( k ); integrate.addIndex( tmp_index ); rhs_in = ExportVariable( "x", inputDim-diffsDim, 1, REAL, ACADO_LOCAL ); rhs_out = ExportVariable( "f", NX, 1, REAL, ACADO_LOCAL ); fullRhs = ExportFunction( "full_rhs", rhs_in, rhs_out ); rhs_in.setDoc( "The state and parameter values." ); rhs_out.setDoc( "Right-hand side evaluation." ); fullRhs.doc( "Evaluates the right-hand side of the full model." ); rk_xxx = ExportVariable( "rk_xxx", 1, inputDim-diffsDim, REAL, structWspace ); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { rk_diffsPrev1 = ExportVariable( "rk_diffsPrev1", NX1, NX1+NU, REAL, structWspace ); rk_diffsPrev2 = ExportVariable( "rk_diffsPrev2", NX2, NX1+NX2+NU, REAL, structWspace ); rk_diffsPrev3 = ExportVariable( "rk_diffsPrev3", NX3, NX+NU, REAL, structWspace ); } rk_diffsNew1 = ExportVariable( "rk_diffsNew1", NX1, NX1+NU, REAL, structWspace ); rk_diffsNew2 = ExportVariable( "rk_diffsNew2", NX2, NX1+NX2+NU, REAL, structWspace ); rk_diffsNew3 = ExportVariable( "rk_diffsNew3", NX3, NX+NU, REAL, structWspace ); rk_diffsTemp3 = ExportVariable( "rk_diffsTemp3", NX3, NX1+NX2+NU, REAL, structWspace ); ExportVariable numInt( "numInts", 1, 1, INT ); if( !equidistantControlGrid() ) { ExportVariable numStepsV( "numSteps", numSteps, STATIC_CONST_INT ); integrate.addStatement( std::string( "int " ) + numInt.getName() + " = " + numStepsV.getName() + "[" + rk_index.getName() + "];\n" ); } integrate.addStatement( rk_xxx.getCols( NX,inputDim-diffsDim ) == rk_eta.getCols( NX+diffsDim,inputDim ) ); integrate.addLinebreak( ); // evaluate sensitivities linear input: if( NX1 > 0 ) { for( uint i1 = 0; i1 < NX1; i1++ ) { for( uint i2 = 0; i2 < NX1; i2++ ) { integrate.addStatement( rk_diffsNew1.getSubMatrix(i1,i1+1,i2,i2+1) == A11(i1,i2) ); } for( uint i2 = 0; i2 < NU; i2++ ) { integrate.addStatement( rk_diffsNew1.getSubMatrix(i1,i1+1,NX1+i2,NX1+i2+1) == B11(i1,i2) ); } } } // evaluate sensitivities linear output: if( NX1 > 0 ) { for( uint i1 = 0; i1 < NX3; i1++ ) { for( uint i2 = 0; i2 < NX3; i2++ ) { integrate.addStatement( rk_diffsNew3.getSubMatrix(i1,i1+1,NX-NX3+i2,NX-NX3+i2+1) == A33(i1,i2) ); } } } integrate.addLinebreak( ); // integrator loop: ExportForLoop tmpLoop( run, 0, grid.getNumIntervals() ); ExportStatementBlock *loop; if( equidistantControlGrid() ) { loop = &tmpLoop; } else { loop = &integrate; loop->addStatement( std::string("for(") + run.getName() + " = 0; " + run.getName() + " < " + numInt.getName() + "; " + run.getName() + "++ ) {\n" ); } loop->addStatement( rk_xxx.getCols( 0,NX ) == rk_eta.getCols( 0,NX ) ); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { // Set rk_diffsPrev: loop->addStatement( std::string("if( run > 0 ) {\n") ); if( NX1 > 0 ) { ExportForLoop loopTemp1( i,0,NX1 ); loopTemp1.addStatement( rk_diffsPrev1.getSubMatrix( i,i+1,0,NX1 ) == rk_eta.getCols( i*NX+NX+NXA,i*NX+NX+NXA+NX1 ) ); if( NU > 0 ) loopTemp1.addStatement( rk_diffsPrev1.getSubMatrix( i,i+1,NX1,NX1+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1),i*NU+(NX+NXA)*(NX+1)+NU ) ); loop->addStatement( loopTemp1 ); } if( NX2 > 0 ) { ExportForLoop loopTemp2( i,0,NX2 ); loopTemp2.addStatement( rk_diffsPrev2.getSubMatrix( i,i+1,0,NX1+NX2 ) == rk_eta.getCols( i*NX+NX+NXA+NX1*NX,i*NX+NX+NXA+NX1*NX+NX1+NX2 ) ); 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,i*NU+(NX+NXA)*(NX+1)+NX1*NU+NU ) ); loop->addStatement( loopTemp2 ); } if( NX3 > 0 ) { ExportForLoop loopTemp3( i,0,NX3 ); loopTemp3.addStatement( rk_diffsPrev3.getSubMatrix( i,i+1,0,NX ) == rk_eta.getCols( i*NX+NX+NXA+(NX1+NX2)*NX,i*NX+NX+NXA+(NX1+NX2)*NX+NX ) ); if( NU > 0 ) loopTemp3.addStatement( rk_diffsPrev3.getSubMatrix( i,i+1,NX,NX+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1)+(NX1+NX2)*NU,i*NU+(NX+NXA)*(NX+1)+(NX1+NX2)*NU+NU ) ); loop->addStatement( loopTemp3 ); } loop->addStatement( std::string("}\n") ); } // evaluate states: if( NX1 > 0 ) { loop->addFunctionCall( lin_input.getName(), rk_xxx, rk_eta.getAddress(0,0) ); } if( NX2 > 0 ) { loop->addFunctionCall( getNameRHS(), rk_xxx, rk_eta.getAddress(0,NX1) ); } if( NX3 > 0 ) { loop->addFunctionCall( getNameOutputRHS(), rk_xxx, rk_eta.getAddress(0,NX1+NX2) ); } // evaluate sensitivities if( NX2 > 0 ) { loop->addFunctionCall( getNameDiffsRHS(), rk_xxx, rk_diffsNew2.getAddress(0,0) ); } if( NX3 > 0 ) { loop->addFunctionCall( getNameOutputDiffs(), rk_xxx, rk_diffsTemp3.getAddress(0,0) ); ExportForLoop loop1( i,0,NX3 ); ExportForLoop loop2( j,0,NX1+NX2 ); loop2.addStatement( rk_diffsNew3.getSubMatrix(i,i+1,j,j+1) == rk_diffsTemp3.getSubMatrix(i,i+1,j,j+1) ); loop1.addStatement( loop2 ); loop2 = ExportForLoop( j,0,NU ); loop2.addStatement( rk_diffsNew3.getSubMatrix(i,i+1,NX+j,NX+j+1) == rk_diffsTemp3.getSubMatrix(i,i+1,NX1+NX2+j,NX1+NX2+j+1) ); loop1.addStatement( loop2 ); loop->addStatement( loop1 ); } // computation of the sensitivities using chain rule: if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { loop->addStatement( std::string( "if( run == 0 ) {\n" ) ); } // PART 1 updateInputSystem(loop, i, j, tmp_index); // PART 2 updateImplicitSystem(loop, i, j, tmp_index); // PART 3 updateOutputSystem(loop, i, j, tmp_index); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { loop->addStatement( std::string( "}\n" ) ); loop->addStatement( std::string( "else {\n" ) ); // PART 1 propagateInputSystem(loop, i, j, k, tmp_index); // PART 2 propagateImplicitSystem(loop, i, j, k, tmp_index); // PART 3 propagateOutputSystem(loop, i, j, k, tmp_index); loop->addStatement( std::string( "}\n" ) ); } // end of the integrator loop. if( !equidistantControlGrid() ) { loop->addStatement( "}\n" ); } else { integrate.addStatement( *loop ); } // PART 1 if( NX1 > 0 ) { DMatrix zeroR = zeros<double>(1, NX2+NX3); ExportForLoop loop1( i,0,NX1 ); loop1.addStatement( rk_eta.getCols( i*NX+NX+NXA+NX1,i*NX+NX+NXA+NX ) == zeroR ); integrate.addStatement( loop1 ); } // PART 2 DMatrix zeroR = zeros<double>(1, NX3); if( NX2 > 0 ) { ExportForLoop loop2( i,NX1,NX1+NX2 ); loop2.addStatement( rk_eta.getCols( i*NX+NX+NXA+NX1+NX2,i*NX+NX+NXA+NX ) == zeroR ); integrate.addStatement( loop2 ); } LOG( LVL_DEBUG ) << "done" << endl; return SUCCESSFUL_RETURN; }
returnValue DiscreteTimeExport::setup( ) { int useOMP; get(CG_USE_OPENMP, useOMP); ExportStruct structWspace; structWspace = useOMP ? ACADO_LOCAL : ACADO_WORKSPACE; // non equidistant integration grids not implemented for NARX integrators if( !equidistant ) return ACADOERROR( RET_INVALID_OPTION ); String fileName( "integrator.c" ); int printLevel; get( PRINTLEVEL,printLevel ); if ( (PrintLevel)printLevel >= HIGH ) acadoPrintf( "--> Preparing to export %s... ",fileName.getName() ); ExportIndex run( "run" ); ExportIndex i( "i" ); ExportIndex j( "j" ); ExportIndex k( "k" ); ExportIndex tmp_index("tmp_index"); uint diffsDim = NX*(NX+NU); uint inputDim = NX*(NX+NU+1) + NU + NP; // setup INTEGRATE function rk_index = ExportVariable( "rk_index", 1, 1, INT, ACADO_LOCAL, BT_TRUE ); rk_eta = ExportVariable( "rk_eta", 1, inputDim, REAL ); if( equidistantControlGrid() ) { integrate = ExportFunction( "integrate", rk_eta, reset_int ); } else { integrate = ExportFunction( "integrate", rk_eta, reset_int, rk_index ); } integrate.setReturnValue( error_code ); integrate.addIndex( run ); integrate.addIndex( i ); integrate.addIndex( j ); integrate.addIndex( k ); integrate.addIndex( tmp_index ); rhs_in = ExportVariable( "x", inputDim-diffsDim, 1, REAL, ACADO_LOCAL ); rhs_out = ExportVariable( "f", NX, 1, REAL, ACADO_LOCAL ); fullRhs = ExportFunction( "full_rhs", rhs_in, rhs_out ); rk_xxx = ExportVariable( "rk_xxx", 1, inputDim-diffsDim, REAL, structWspace ); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { rk_diffsPrev1 = ExportVariable( "rk_diffsPrev1", NX1, NX1+NU, REAL, structWspace ); rk_diffsPrev2 = ExportVariable( "rk_diffsPrev2", NX2, NX1+NX2+NU, REAL, structWspace ); } rk_diffsNew1 = ExportVariable( "rk_diffsNew1", NX1, NX1+NU, REAL, structWspace ); rk_diffsNew2 = ExportVariable( "rk_diffsNew2", NX2, NX1+NX2+NU, REAL, structWspace ); ExportVariable numInt( "numInts", 1, 1, INT ); if( !equidistantControlGrid() ) { ExportVariable numStepsV( "numSteps", numSteps, STATIC_CONST_INT ); integrate.addStatement( String( "int " ) << numInt.getName() << " = " << numStepsV.getName() << "[" << rk_index.getName() << "];\n" ); } integrate.addStatement( rk_xxx.getCols( NX,inputDim-diffsDim ) == rk_eta.getCols( NX+diffsDim,inputDim ) ); integrate.addLinebreak( ); // integrator loop: ExportForLoop tmpLoop( run, 0, grid.getNumIntervals() ); ExportStatementBlock *loop; if( equidistantControlGrid() ) { loop = &tmpLoop; } else { loop = &integrate; loop->addStatement( String("for(") << run.getName() << " = 0; " << run.getName() << " < " << numInt.getName() << "; " << run.getName() << "++ ) {\n" ); } loop->addStatement( rk_xxx.getCols( 0,NX ) == rk_eta.getCols( 0,NX ) ); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { // Set rk_diffsPrev: loop->addStatement( String("if( run > 0 ) {\n") ); if( NX1 > 0 ) { ExportForLoop loopTemp1( i,0,NX1 ); loopTemp1.addStatement( rk_diffsPrev1.getSubMatrix( i,i+1,0,NX1 ) == rk_eta.getCols( i*NX+NX+NXA,i*NX+NX+NXA+NX1 ) ); if( NU > 0 ) loopTemp1.addStatement( rk_diffsPrev1.getSubMatrix( i,i+1,NX1,NX1+NU ) == rk_eta.getCols( i*NU+(NX+NXA)*(NX+1),i*NU+(NX+NXA)*(NX+1)+NU ) ); loop->addStatement( loopTemp1 ); } if( NX2 > 0 ) { ExportForLoop loopTemp2( i,0,NX2 ); loopTemp2.addStatement( rk_diffsPrev2.getSubMatrix( i,i+1,0,NX1+NX2 ) == rk_eta.getCols( i*NX+NX+NXA+NX1*NX,i*NX+NX+NXA+NX1*NX+NX1+NX2 ) ); 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,i*NU+(NX+NXA)*(NX+1)+NX1*NU+NU ) ); loop->addStatement( loopTemp2 ); } loop->addStatement( String("}\n") ); } // evaluate states: if( NX1 > 0 ) { loop->addFunctionCall( lin_input.getName(), rk_xxx, rk_eta.getAddress(0,0) ); } if( NX2 > 0 ) { loop->addFunctionCall( getNameRHS(), rk_xxx, rk_eta.getAddress(0,NX1) ); } // evaluate sensitivities: if( NX1 > 0 ) { for( uint i1 = 0; i1 < NX1; i1++ ) { for( uint i2 = 0; i2 < NX1; i2++ ) { loop->addStatement( rk_diffsNew1.getSubMatrix(i1,i1+1,i2,i2+1) == A11(i1,i2) ); } for( uint i2 = 0; i2 < NU; i2++ ) { loop->addStatement( rk_diffsNew1.getSubMatrix(i1,i1+1,NX1+i2,NX1+i2+1) == B11(i1,i2) ); } } } if( NX2 > 0 ) { loop->addFunctionCall( getNameDiffsRHS(), rk_xxx, rk_diffsNew2.getAddress(0,0) ); } // computation of the sensitivities using chain rule: if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { loop->addStatement( String( "if( run == 0 ) {\n" ) ); } // PART 1 updateInputSystem(loop, i, j, tmp_index); // PART 2 updateImplicitSystem(loop, i, j, tmp_index); if( grid.getNumIntervals() > 1 || !equidistantControlGrid() ) { loop->addStatement( String( "}\n" ) ); loop->addStatement( String( "else {\n" ) ); // PART 1 propagateInputSystem(loop, i, j, k, tmp_index); // PART 2 propagateImplicitSystem(loop, i, j, k, tmp_index); loop->addStatement( String( "}\n" ) ); } // end of the integrator loop. if( !equidistantControlGrid() ) { loop->addStatement( "}\n" ); } else { integrate.addStatement( *loop ); } // PART 1 if( NX1 > 0 ) { Matrix zeroR = zeros(1, NX2); ExportForLoop loop1( i,0,NX1 ); loop1.addStatement( rk_eta.getCols( i*NX+NX+NXA+NX1,i*NX+NX+NXA+NX ) == zeroR ); integrate.addStatement( loop1 ); } if ( (PrintLevel)printLevel >= HIGH ) acadoPrintf( "done.\n" ); return SUCCESSFUL_RETURN; }