irk_4stage_simplified_newton_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 
35 
36 using namespace std;
37 
39 
40 //
41 // PUBLIC MEMBER FUNCTIONS:
42 //
43 
45  const std::string& _commonHeaderName
46  ) : ExportGaussElim( _userInteraction,_commonHeaderName )
47 {
48  stepsize = 0;
49  implicit = false;
50 }
51 
53 {}
54 
56  ExportStruct dataStruct
57  ) const
58 {
59  ExportGaussElim::getDataDeclarations( declarations, dataStruct );
60 
61  declarations.addDeclaration( rk_swap_complex,dataStruct ); // needed for the row swaps
62  if( REUSE ) {
63  declarations.addDeclaration( rk_bPerm_complex,dataStruct ); // reordered right-hand side
64  }
65  declarations.addDeclaration( A_mem_complex1,dataStruct );
66  declarations.addDeclaration( b_mem_complex1,dataStruct );
67 
68  declarations.addDeclaration( A_mem_complex2,dataStruct );
69  declarations.addDeclaration( b_mem_complex2,dataStruct );
70 
71  if( TRANSPOSE ) {
72  declarations.addDeclaration( b_mem_complex1_trans,dataStruct );
73  declarations.addDeclaration( b_mem_complex2_trans,dataStruct );
74  declarations.addDeclaration( rk_bPerm_complex_trans,dataStruct );
75  }
76 
77  return SUCCESSFUL_RETURN;
78 }
79 
80 
82  ) const
83 {
85 
86  declarations.addDeclaration( solve_complex );
87  if( REUSE ) {
88  declarations.addDeclaration( solveReuse_complex );
89  }
90 
91  declarations.addDeclaration( solve_full );
92  if( REUSE ) {
93  declarations.addDeclaration( solveReuse_full );
94  }
95 
96  return SUCCESSFUL_RETURN;
97 }
98 
99 
101  )
102 {
103  if( eig.isEmpty() || transf1.isEmpty() || transf2.isEmpty() || fabs(stepsize) <= ZERO_EPS ) return ACADOERROR(RET_INVALID_OPTION);
104 
105 // if( TRANSPOSE ) return ACADOERROR( RET_NOT_YET_IMPLEMENTED );
106 
108  code.addFunction( solve_complex );
109 
110  if( REUSE ) { // Also export the extra function which reuses the factorization of the matrix A
113 
114  if( TRANSPOSE ) {
117  }
118  }
119 
120  ExportVariable eig_var( 1.0/stepsize*eig );
121 
122  // SETUP solve_full
123  ExportVariable det_complex1( "det_complex1", 1, 1, REAL, ACADO_LOCAL, true );
124  ExportVariable det_complex2( "det_complex2", 1, 1, REAL, ACADO_LOCAL, true );
125  solve_full.addDeclaration( det_complex1 );
126  solve_full.addDeclaration( det_complex2 );
127  ExportIndex i( "i" );
128  solve_full.addIndex(i);
129 
130  // form the real and complex linear system matrices
132  if( implicit ) {
133  ExportForLoop loop1( i, 0, dim*dim );
134  loop1 << A_mem_complex1.getFullName() << "[i] += (" << eig_var.get(0,0) << "+" << eig_var.get(0,1) << "*I)*" << I_full.getFullName() << "[i];\n";
135  solve_full.addStatement( loop1 );
136  }
137  else {
138  ExportForLoop loop1( i, 0, dim );
139  loop1 << A_mem_complex1.getFullName() << "[i*" << toString(dim) << "+i] -= (" << eig_var.get(0,0) << "+" << eig_var.get(0,1) << "*I);\n";
140  solve_full.addStatement( loop1 );
141  }
142 
144  if( implicit ) {
145  ExportForLoop loop1( i, 0, dim*dim );
146  loop1 << A_mem_complex2.getFullName() << "[i] += (" << eig_var.get(1,0) << "+" << eig_var.get(1,1) << "*I)*" << I_full.getFullName() << "[i];\n";
147  solve_full.addStatement( loop1 );
148  }
149  else {
150  ExportForLoop loop1( i, 0, dim );
151  loop1 << A_mem_complex2.getFullName() << "[i*" << toString(dim) << "+i] -= (" << eig_var.get(1,0) << "+" << eig_var.get(1,1) << "*I);\n";
152  solve_full.addStatement( loop1 );
153  }
154 
155  // factorize the real and complex linear systems
158 
159  code.addFunction( solve_full );
160 
161  // SETUP solveReuse_full
162  if( REUSE ) {
164 
165  // transform the right-hand side
167 
168  // solveReuse the real and complex linear systems
171 
172  // transform back to the solution
174 
176 
177  if( TRANSPOSE ) {
178  uint NUM_RHS = nRightHandSides;
179  nRightHandSides = 1;
181 
182  // transform the right-hand side
184 
185  // solveReuse the real and complex linear systems
188 
189  // transform back to the solution
191 
193  nRightHandSides = NUM_RHS;
194  }
195  }
196 
197  return SUCCESSFUL_RETURN;
198 }
199 
200 
201 returnValue ExportIRK4StageSimplifiedNewton::transformRightHandSide( ExportStatementBlock& code, const ExportVariable& b_mem1, const ExportVariable& b_mem2, const ExportVariable& b_full_, const ExportVariable& transf_, const ExportIndex& index, const bool transpose )
202 {
203  uint i, j;
204 
205  ExportVariable transf1_var( transf_ );
206  ExportVariable stepSizeV( 1.0/stepsize );
207 
208  ExportForLoop loop1( index, 0, dim );
209  for( j = 0; j < nRightHandSides; j++ ) {
210  loop1.addStatement( b_mem1.getElement(index,j) == 0.0 );
211  for( i = 0; i < 4; i++ ) {
212  loop1.addStatement( b_mem1.getElement(index,j) += transf1_var.getElement(0,i)*b_full_.getElement(index+i*dim,j) );
213  }
214  stringstream ss1;
215  if( transpose ) ss1 << b_mem1.get(index,j) << " -= (";
216  else ss1 << b_mem1.get(index,j) << " += (";
217  for( i = 0; i < 4; i++ ) {
218  if( i > 0 ) ss1 << " + ";
219  ss1 << transf1_var.get(1,i) << "*" << b_full_.get(index+i*dim,j);
220  }
221  ss1 << ")*I;\n";
222  ss1 << b_mem1.get(index,j) << " *= " << stepSizeV.get(0,0) << ";\n";
223  loop1 << ss1.str();
224 
225 
226  loop1.addStatement( b_mem2.getElement(index,j) == 0.0 );
227  for( i = 0; i < 4; i++ ) {
228  loop1.addStatement( b_mem2.getElement(index,j) += transf1_var.getElement(2,i)*b_full_.getElement(index+i*dim,j) );
229  }
230  stringstream ss2;
231  if( transpose ) ss2 << b_mem2.get(index,j) << " -= (";
232  else ss2 << b_mem2.get(index,j) << " += (";
233  for( i = 0; i < 4; i++ ) {
234  if( i > 0 ) ss2 << " + ";
235  ss2 << transf1_var.get(3,i) << "*" << b_full_.get(index+i*dim,j);
236  }
237  ss2 << ")*I;\n";
238  ss2 << b_mem2.get(index,j) << " *= " << stepSizeV.get(0,0) << ";\n";
239  loop1 << ss2.str();
240  }
241  code.addStatement( loop1 );
242 
243  return SUCCESSFUL_RETURN;
244 }
245 
246 
247 returnValue ExportIRK4StageSimplifiedNewton::transformSolution( ExportStatementBlock& code, const ExportVariable& b_mem1, const ExportVariable& b_mem2, const ExportVariable& b_full_, const ExportVariable& transf_, const ExportIndex& index, const bool transpose )
248 {
249  uint j;
250  ExportVariable transf2_var( transf_ );
251 
252  ExportForLoop loop1( index, 0, dim );
253  for( j = 0; j < nRightHandSides; j++ ) {
254  stringstream ss;
255  ss << b_full_.get(index,j) << " = ";
256  if( transpose ) ss << transf2_var.get(0,0) << "*creal(" << b_mem1.get(index,j) << ") - ";
257  else ss << transf2_var.get(0,0) << "*creal(" << b_mem1.get(index,j) << ") + ";
258  ss << transf2_var.get(0,1) << "*cimag(" << b_mem1.get(index,j) << ") + ";
259  if( transpose ) ss << transf2_var.get(0,2) << "*creal(" << b_mem2.get(index,j) << ") - ";
260  else ss << transf2_var.get(0,2) << "*creal(" << b_mem2.get(index,j) << ") + ";
261  ss << transf2_var.get(0,3) << "*cimag(" << b_mem2.get(index,j) << ");\n";
262 
263  ss << b_full_.get(index+dim,j) << " = ";
264  if( transpose ) ss << transf2_var.get(1,0) << "*creal(" << b_mem1.get(index,j) << ") - ";
265  else ss << transf2_var.get(1,0) << "*creal(" << b_mem1.get(index,j) << ") + ";
266  ss << transf2_var.get(1,1) << "*cimag(" << b_mem1.get(index,j) << ") + ";
267  if( transpose ) ss << transf2_var.get(1,2) << "*creal(" << b_mem2.get(index,j) << ") - ";
268  else ss << transf2_var.get(1,2) << "*creal(" << b_mem2.get(index,j) << ") + ";
269  ss << transf2_var.get(1,3) << "*cimag(" << b_mem2.get(index,j) << ");\n";
270 
271  ss << b_full_.get(index+2*dim,j) << " = ";
272  if( transpose ) ss << transf2_var.get(2,0) << "*creal(" << b_mem1.get(index,j) << ") - ";
273  else ss << transf2_var.get(2,0) << "*creal(" << b_mem1.get(index,j) << ") + ";
274  ss << transf2_var.get(2,1) << "*cimag(" << b_mem1.get(index,j) << ") + ";
275  if( transpose ) ss << transf2_var.get(2,2) << "*creal(" << b_mem2.get(index,j) << ") - ";
276  else ss << transf2_var.get(2,2) << "*creal(" << b_mem2.get(index,j) << ") + ";
277  ss << transf2_var.get(2,3) << "*cimag(" << b_mem2.get(index,j) << ");\n";
278 
279  ss << b_full_.get(index+3*dim,j) << " = ";
280  if( transpose ) ss << transf2_var.get(3,0) << "*creal(" << b_mem1.get(index,j) << ") - ";
281  else ss << transf2_var.get(3,0) << "*creal(" << b_mem1.get(index,j) << ") + ";
282  ss << transf2_var.get(3,1) << "*cimag(" << b_mem1.get(index,j) << ") + ";
283  if( transpose ) ss << transf2_var.get(3,2) << "*creal(" << b_mem2.get(index,j) << ") - ";
284  else ss << transf2_var.get(3,2) << "*creal(" << b_mem2.get(index,j) << ") + ";
285  ss << transf2_var.get(3,3) << "*cimag(" << b_mem2.get(index,j) << ");\n";
286  loop1 << ss.str();
287  }
288  code.addStatement( loop1 );
289 
290  return SUCCESSFUL_RETURN;
291 }
292 
293 
295 
297  string << ", " << rk_swap_complex.getFullName();
298  if( REUSE ) {
299 // string << ", " << rk_perm.getFullName().getName();
300  string << ", " << rk_bPerm_complex.getFullName();
301  }
302 
303  return SUCCESSFUL_RETURN;
304 }
305 
306 
308 {
310 
311  if (nRightHandSides <= 0)
313 
314  int useOMP;
315  get(CG_USE_OPENMP, useOMP);
316  ExportStruct structWspace;
317  structWspace = useOMP ? ACADO_LOCAL : ACADO_WORKSPACE;
318 
319  determinant_complex = ExportVariable("det", 1, 1, COMPLEX, ACADO_LOCAL, true);
320  rk_swap_complex = ExportVariable( std::string( "rk_complex_" ) + identifier + "swap", 1, 1, COMPLEX, structWspace, true );
321  rk_bPerm_complex = ExportVariable( std::string( "rk_complex_" ) + identifier + "bPerm", dim, nRightHandSides, COMPLEX, structWspace );
322 
323  A_mem_complex1 = ExportVariable( std::string( "rk_complex1_" ) + identifier + "A", dim, dim, COMPLEX, structWspace );
324  b_mem_complex1 = ExportVariable( std::string( "rk_complex1_" ) + identifier + "b", dim, nRightHandSides, COMPLEX, structWspace );
325 
326  A_mem_complex2 = ExportVariable( std::string( "rk_complex2_" ) + identifier + "A", dim, dim, COMPLEX, structWspace );
327  b_mem_complex2 = ExportVariable( std::string( "rk_complex2_" ) + identifier + "b", dim, nRightHandSides, COMPLEX, structWspace );
328 
329  A_complex = ExportVariable( "A", dim, dim, COMPLEX );
331  rk_perm_complex = ExportVariable( "rk_perm", 1, dim, INT );
332 
335  solve_complex.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
336 
337  if( REUSE ) {
339  solveReuse_complex.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
340 
341  if( TRANSPOSE ) {
343  rk_bPerm_complex_trans = ExportVariable( std::string( "rk_complex_trans_" ) + identifier + "bPerm", dim, 1, COMPLEX, structWspace );
344 
345  b_mem_complex1_trans = ExportVariable( std::string( "rk_complex1_trans_" ) + identifier + "b", dim, 1, COMPLEX, structWspace );
346  b_mem_complex2_trans = ExportVariable( std::string( "rk_complex2_trans_" ) + identifier + "b", dim, 1, COMPLEX, structWspace );
347 
349  solveReuse_complexTranspose.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
350  }
351  }
352 
353  A_full = ExportVariable( "A", dim, dim, REAL );
354  I_full = ExportVariable( "A_I", dim, dim, REAL );
356  rk_perm_full = ExportVariable( "rk_perm", 2, dim, INT );
357 
358  if( implicit ) {
359  solve_full = ExportFunction( getNameSolveFunction(), A_full, I_full, rk_perm_full ); // Only perform the LU factorization!
360  }
361  else {
362  solve_full = ExportFunction( getNameSolveFunction(), A_full, rk_perm_full ); // Only perform the LU factorization!
363  }
365  solve_full.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
366  if( REUSE ) {
367  if( implicit ) {
370  }
371  else {
373  if( TRANSPOSE ) {
374  b_full_trans = ExportVariable( "b", 4*dim, 1, REAL );
376  }
377  }
378  solveReuse_full.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
379  }
380 
381  return SUCCESSFUL_RETURN;
382 }
383 
384 
386  eig = _eig;
387 
388  if( _eig.getNumRows() != 2 || _eig.getNumCols() != 2 ) return ACADOERROR( RET_INVALID_ARGUMENTS );
389  if( _eig.isZero() ) return ACADOERROR( RET_INVALID_ARGUMENTS );
390  // each row represents a complex conjugate pair of eigenvalues
391 
392  return SUCCESSFUL_RETURN;
393 }
394 
395 
396 returnValue ExportIRK4StageSimplifiedNewton::setTransformations( const DMatrix& _transf1, const DMatrix& _transf2, const DMatrix& _transf1_T, const DMatrix& _transf2_T ) {
397  transf1 = _transf1;
398  transf2 = _transf2;
399  transf1_T = _transf1_T;
400  transf2_T = _transf2_T;
401 
402  if( _transf1.getNumRows() != 4 || _transf1.getNumCols() != 4 ) return ACADOERROR( RET_INVALID_ARGUMENTS );
403  if( _transf2.getNumRows() != 4 || _transf2.getNumCols() != 4 ) return ACADOERROR( RET_INVALID_ARGUMENTS );
404  if( _transf1.isZero() || _transf2.isZero() ) return ACADOERROR( RET_INVALID_ARGUMENTS );
405 
406  return SUCCESSFUL_RETURN;
407 }
408 
409 
411  stepsize = _stepsize;
412 
413  return SUCCESSFUL_RETURN;
414 }
415 
416 
418 
419  return string( "solve_complex_" ) + identifier + "system";
420 }
421 
422 
424 
425  return string( "solve_complex_" ) + identifier + "system_reuse";
426 }
427 
428 
430 
431  return string( "solve_complex_trans_" ) + identifier + "system_reuse";
432 }
433 
435 
436  implicit = _implicit;
437 
438  return SUCCESSFUL_RETURN;
439 }
440 
441 //
442 // PROTECTED MEMBER FUNCTIONS:
443 //
444 
445 
446 
448 
449 // end of file.
bool isEmpty() const
Definition: matrix.hpp:193
const std::string getNameSolveTransposeReuseFunction()
virtual returnValue getCode(ExportStatementBlock &code)
returnValue setTransformations(const DMatrix &_transf1, const DMatrix &_transf2, const DMatrix &_transf1_T, const DMatrix &_transf2_T)
virtual returnValue setup()
Allows to pass back messages to the calling function.
BEGIN_NAMESPACE_ACADO typedef unsigned int uint
Definition: acado_types.hpp:42
virtual returnValue setupSolveReuseTranspose(ExportFunction &_solveReuse, ExportVariable &_bPerm)
Allows to export code of a for-loop.
string toString(T const &value)
virtual returnValue getDataDeclarations(ExportStatementBlock &declarations, ExportStruct dataStruct=ACADO_ANY) const
virtual returnValue setupSolveReuseComplete(ExportFunction &_solveReuse, ExportVariable &_bPerm)
ExportVariable getElement(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
#define CLOSE_NAMESPACE_ACADO
Defines a scalar-valued index variable to be used for exporting code.
virtual returnValue transformSolution(ExportStatementBlock &code, const ExportVariable &b_mem1, const ExportVariable &b_mem2, const ExportVariable &b_full_, const ExportVariable &transf_, const ExportIndex &index, const bool transpose)
returnValue setImplicit(BooleanType _implicit)
returnValue appendVariableNames(std::stringstream &string)
ExportStruct
Allows to export Gaussian elimination for solving linear systems of specific dimensions.
const std::string getNameSolveReuseFunction()
returnValue appendVariableNames(std::stringstream &string)
ExportIRK4StageSimplifiedNewton(UserInteraction *_userInteraction=0, const std::string &_commonHeaderName="")
const std::string get(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
Encapsulates all user interaction for setting options, logging data and plotting results.
Allows to export code of an arbitrary function.
returnValue addStatement(const ExportStatement &_statement)
virtual returnValue transformRightHandSide(ExportStatementBlock &code, const ExportVariable &b_mem1, const ExportVariable &b_mem2, const ExportVariable &b_full_, const ExportVariable &transf_, const ExportIndex &index, const bool transpose)
std::string getFullName() const
unsigned getNumRows() const
Definition: matrix.hpp:185
returnValue addLinebreak(uint num=1)
ExportFunction & setReturnValue(const ExportVariable &_functionReturnValue, bool _returnAsPointer=false)
virtual returnValue getDataDeclarations(ExportStatementBlock &declarations, ExportStruct dataStruct=ACADO_ANY) const
unsigned getNumCols() const
Definition: matrix.hpp:189
returnValue addDeclaration(const ExportVariable &_data, ExportStruct _dataStruct=ACADO_ANY)
const std::string getNameSolveFunction()
#define BEGIN_NAMESPACE_ACADO
returnValue addFunction(const ExportFunction &_function)
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
Allows to export code for a block of statements.
ExportArgument getAddress(const ExportIndex &_rowIdx, const ExportIndex &_colIdx=emptyConstExportIndex) const
const double ZERO_EPS
ExportFunction & addIndex(const ExportIndex &_index)
#define ACADOERROR(retval)
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
Defines a matrix-valued variable to be used for exporting code.
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 setupFactorization(ExportFunction &_solve, ExportVariable &_swap, ExportVariable &_determinant, const std::string &absF)


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