irk_3stage_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_real,dataStruct );
66  declarations.addDeclaration( A_mem_complex,dataStruct );
67  declarations.addDeclaration( b_mem_real,dataStruct );
68  declarations.addDeclaration( b_mem_complex,dataStruct );
69 
70  if( TRANSPOSE ) {
71  declarations.addDeclaration( b_mem_real_trans,dataStruct );
72  declarations.addDeclaration( b_mem_complex_trans,dataStruct );
73  declarations.addDeclaration( rk_bPerm_complex_trans,dataStruct );
74  }
75 
76  return SUCCESSFUL_RETURN;
77 }
78 
79 
81  ) const
82 {
84 
85  declarations.addDeclaration( solve_complex );
86  if( REUSE ) {
87  declarations.addDeclaration( solveReuse_complex );
88  }
89 
90  declarations.addDeclaration( solve_full );
91  if( REUSE ) {
92  declarations.addDeclaration( solveReuse_full );
93  }
94 
95  return SUCCESSFUL_RETURN;
96 }
97 
98 
100  )
101 {
102  if( eig.isEmpty() || transf1.isEmpty() || transf2.isEmpty() || fabs(stepsize) <= ZERO_EPS ) return ACADOERROR(RET_INVALID_OPTION);
103 
104 // if( TRANSPOSE ) return ACADOERROR( RET_NOT_YET_IMPLEMENTED );
105 
106  setupFactorization( solve, rk_swap, determinant, string("fabs") );
107  code.addFunction( solve );
108 
109  if( REUSE ) { // Also export the extra function which reuses the factorization of the matrix A
111  code.addFunction( solveReuse );
112 
113  if( TRANSPOSE ) {
116  }
117  }
118 
120  code.addFunction( solve_complex );
121 
122  if( REUSE ) { // Also export the extra function which reuses the factorization of the matrix A
125 
126  if( TRANSPOSE ) {
129  }
130  }
131 
132  ExportVariable eig_var( 1.0/stepsize*eig );
133 
134  // SETUP solve_full
135  ExportVariable det_complex( "det_complex", 1, 1, REAL, ACADO_LOCAL, true );
136  ExportVariable det_real( "det_real", 1, 1, REAL, ACADO_LOCAL, true );
137  solve_full.addDeclaration( det_complex );
138  solve_full.addDeclaration( det_real );
139  ExportIndex i( "i" );
140  solve_full.addIndex(i);
141 
142  // form the real and complex linear system matrices
144  if( implicit ) {
145  ExportForLoop loop1( i, 0, dim*dim );
146  loop1 << A_mem_complex.getFullName() << "[i] += (" << eig_var.get(0,0) << "+" << eig_var.get(0,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_complex.getFullName() << "[i*" << toString(dim) << "+i] -= (" << eig_var.get(0,0) << "+" << eig_var.get(0,1) << "*I);\n";
152  solve_full.addStatement( loop1 );
153  }
154 
156  if( implicit ) {
157  ExportForLoop loop2( i, 0, dim*dim );
158  loop2 << A_mem_real.getFullName() << "[i] += " << eig_var.get(1,0) << "*" << I_full.getFullName() << "[i];\n";
159  solve_full.addStatement( loop2 );
160  }
161  else {
162  ExportForLoop loop2( i, 0, dim );
163  loop2 << A_mem_real.getFullName() << "[i*" << toString(dim) << "+i] -= " << eig_var.get(1,0) << ";\n";
164  solve_full.addStatement( loop2 );
165  }
166 
167  // factorize the real and complex linear systems
170 
171  code.addFunction( solve_full );
172 
173  // SETUP solveReuse_full
174  if( REUSE ) {
176 
177  // transform the right-hand side
179 
180  // solveReuse the real and complex linear systems
183 
184  // transform back to the solution
186 
188 
189  if( TRANSPOSE ) {
190  uint NUM_RHS = nRightHandSides;
191  nRightHandSides = 1;
193 
194  // transform the right-hand side
196 
197  // solveReuse the real and complex linear systems
200 
201  // transform back to the solution
203 
205  nRightHandSides = NUM_RHS;
206  }
207  }
208 
209  return SUCCESSFUL_RETURN;
210 }
211 
212 
213 returnValue ExportIRK3StageSimplifiedNewton::transformRightHandSide( ExportStatementBlock& code, const ExportVariable& b_mem_complex_, const ExportVariable& b_mem_real_, const ExportVariable& b_full_, const ExportVariable& transf_, const ExportIndex& index, const bool transpose )
214 {
215  uint i, j;
216 
217  ExportVariable transf1_var( transf_ );
218  ExportVariable stepSizeV( 1.0/stepsize );
219 
220  ExportForLoop loop1( index, 0, dim );
221  for( j = 0; j < nRightHandSides; j++ ) {
222  loop1.addStatement( b_mem_complex_.getElement(index,j) == 0.0 );
223  for( i = 0; i < 3; i++ ) {
224  loop1.addStatement( b_mem_complex_.getElement(index,j) += transf1_var.getElement(0,i)*b_full_.getElement(index+i*dim,j) );
225  }
226  stringstream ss1;
227  if( transpose ) ss1 << b_mem_complex_.get(index,j) << " -= (";
228  else ss1 << b_mem_complex_.get(index,j) << " += (";
229  for( i = 0; i < 3; i++ ) {
230  if( i > 0 ) ss1 << " + ";
231  ss1 << transf1_var.get(1,i) << "*" << b_full_.get(index+i*dim,j);
232  }
233  ss1 << ")*I;\n";
234  ss1 << b_mem_complex_.get(index,j) << " *= " << stepSizeV.get(0,0) << ";\n";
235  loop1 << ss1.str();
236 
237  loop1.addStatement( b_mem_real_.getElement(index,j) == 0.0 );
238  for( i = 0; i < 3; i++ ) {
239  loop1.addStatement( b_mem_real_.getElement(index,j) += transf1_var.getElement(2,i)*b_full_.getElement(index+i*dim,j) );
240  }
241  stringstream ss2;
242  ss2 << b_mem_real_.get(index,j) << " *= " << stepSizeV.get(0,0) << ";\n";
243  loop1 << ss2.str();
244  }
245  code.addStatement( loop1 );
246 
247  return SUCCESSFUL_RETURN;
248 }
249 
250 
251 returnValue ExportIRK3StageSimplifiedNewton::transformSolution( ExportStatementBlock& code, const ExportVariable& b_mem_complex_, const ExportVariable& b_mem_real_, const ExportVariable& b_full_, const ExportVariable& transf_, const ExportIndex& index, const bool transpose )
252 {
253  uint j;
254  ExportVariable transf2_var( transf_ );
255 
256  ExportForLoop loop1( index, 0, dim );
257  for( j = 0; j < nRightHandSides; j++ ) {
258  stringstream ss;
259  ss << b_full_.get(index,j) << " = ";
260  if( transpose ) ss << transf2_var.get(0,0) << "*creal(" << b_mem_complex_.get(index,j) << ") - ";
261  else ss << transf2_var.get(0,0) << "*creal(" << b_mem_complex_.get(index,j) << ") + ";
262  ss << transf2_var.get(0,1) << "*cimag(" << b_mem_complex_.get(index,j) << ") + ";
263  ss << transf2_var.get(0,2) << "*" << b_mem_real_.get(index,j) << ";\n";
264 
265  ss << b_full_.get(index+dim,j) << " = ";
266  if( transpose ) ss << transf2_var.get(1,0) << "*creal(" << b_mem_complex_.get(index,j) << ") - ";
267  else ss << transf2_var.get(1,0) << "*creal(" << b_mem_complex_.get(index,j) << ") + ";
268  ss << transf2_var.get(1,1) << "*cimag(" << b_mem_complex_.get(index,j) << ") + ";
269  ss << transf2_var.get(1,2) << "*" << b_mem_real_.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_mem_complex_.get(index,j) << ") - ";
273  else ss << transf2_var.get(2,0) << "*creal(" << b_mem_complex_.get(index,j) << ") + ";
274  ss << transf2_var.get(2,1) << "*cimag(" << b_mem_complex_.get(index,j) << ") + ";
275  ss << transf2_var.get(2,2) << "*" << b_mem_real_.get(index,j) << ";\n";
276  loop1 << ss.str();
277  }
278  code.addStatement( loop1 );
279 
280  return SUCCESSFUL_RETURN;
281 }
282 
283 
285 
287  string << ", " << rk_swap_complex.getFullName();
288  if( REUSE ) {
289 // string << ", " << rk_perm.getFullName().getName();
290  string << ", " << rk_bPerm_complex.getFullName();
291  }
292 
293  return SUCCESSFUL_RETURN;
294 }
295 
296 
298 {
300 
301  if (nRightHandSides <= 0)
303 
304  int useOMP;
305  get(CG_USE_OPENMP, useOMP);
306  ExportStruct structWspace;
307  structWspace = useOMP ? ACADO_LOCAL : ACADO_WORKSPACE;
308 
309  determinant_complex = ExportVariable("det", 1, 1, COMPLEX, ACADO_LOCAL, true);
310  rk_swap_complex = ExportVariable( std::string( "rk_complex_" ) + identifier + "swap", 1, 1, COMPLEX, structWspace, true );
311  rk_bPerm_complex = ExportVariable( std::string( "rk_complex_" ) + identifier + "bPerm", dim, nRightHandSides, COMPLEX, structWspace );
312 
313  A_mem_real = ExportVariable( std::string( "rk_real_" ) + identifier + "A", dim, dim, REAL, structWspace );
314  A_mem_complex = ExportVariable( std::string( "rk_complex_" ) + identifier + "A", dim, dim, COMPLEX, structWspace );
315  b_mem_real = ExportVariable( std::string( "rk_real_" ) + identifier + "b", dim, nRightHandSides, REAL, structWspace );
316  b_mem_complex = ExportVariable( std::string( "rk_complex_" ) + identifier + "b", dim, nRightHandSides, COMPLEX, structWspace );
317 
318  A_complex = ExportVariable( "A", dim, dim, COMPLEX );
320  rk_perm_complex = ExportVariable( "rk_perm", 1, dim, INT );
321 
323  solve.setReturnValue( determinant, false );
324  solve.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
325 
328  solve_complex.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
329 
330  if( REUSE ) {
332  solveReuse.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
333 
335  solveReuse_complex.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
336 
337  if( TRANSPOSE ) {
339  rk_bPerm_complex_trans = ExportVariable( std::string( "rk_complex_trans_" ) + identifier + "bPerm", dim, 1, COMPLEX, structWspace );
340 
341  b_mem_real_trans = ExportVariable( std::string( "rk_real_trans_" ) + identifier + "b", dim, 1, REAL, structWspace );
342  b_mem_complex_trans = ExportVariable( std::string( "rk_complex_trans_" ) + identifier + "b", dim, 1, COMPLEX, structWspace );
344  solveReuseTranspose.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
345 
347  solveReuse_complexTranspose.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
348  }
349  }
350 
351  A_full = ExportVariable( "A", dim, dim, REAL );
352  I_full = ExportVariable( "A_I", dim, dim, REAL );
354  rk_perm_full = ExportVariable( "rk_perm", 2, dim, INT );
355 
356  if( implicit ) {
357  solve_full = ExportFunction( getNameSolveFunction(), A_full, I_full, rk_perm_full ); // Only perform the LU factorization!
358  }
359  else {
360  solve_full = ExportFunction( getNameSolveFunction(), A_full, rk_perm_full ); // Only perform the LU factorization!
361  }
363  solve_full.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
364  if( REUSE ) {
365  if( implicit ) {
368  }
369  else {
371  if( TRANSPOSE ) {
372  b_full_trans = ExportVariable( "b", 3*dim, 1, REAL );
374  }
375  }
376  solveReuse_full.addLinebreak( ); // FIX: TO MAKE SURE IT GETS EXPORTED
377  }
378 
379  return SUCCESSFUL_RETURN;
380 }
381 
382 
384  eig = _eig;
385 
386  if( _eig.getNumRows() != 2 || _eig.getNumCols() != 2 ) return ACADOERROR( RET_INVALID_ARGUMENTS );
387  if( _eig.isZero() ) return ACADOERROR( RET_INVALID_ARGUMENTS );
388  // first row represents the complex eigenvalue, second row represents the real eigenvalue
389  if( fabs(_eig(0,1)) <= ZERO_EPS || fabs(_eig(1,1)) > ZERO_EPS ) return ACADOERROR( RET_INVALID_OPTION );
390 
391  return SUCCESSFUL_RETURN;
392 }
393 
394 
395 returnValue ExportIRK3StageSimplifiedNewton::setTransformations( const DMatrix& _transf1, const DMatrix& _transf2, const DMatrix& _transf1_T, const DMatrix& _transf2_T ) {
396  transf1 = _transf1;
397  transf2 = _transf2;
398 
399  transf1_T = _transf1_T;
400  transf2_T = _transf2_T;
401 
402  if( _transf1.getNumRows() != 3 || _transf1.getNumCols() != 3 ) return ACADOERROR( RET_INVALID_ARGUMENTS );
403  if( _transf2.getNumRows() != 3 || _transf2.getNumCols() != 3 ) 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_real_" ) + identifier + "system";
420 }
421 
422 
424 
425  return string( "solve_real_" ) + identifier + "system_reuse";
426 }
427 
428 
430 
431  return string( "solve_real_trans_" ) + identifier + "system_reuse";
432 }
433 
434 
436 
437  return string( "solve_complex_" ) + identifier + "system";
438 }
439 
440 
442 
443  return string( "solve_complex_" ) + identifier + "system_reuse";
444 }
445 
446 
448 
449  return string( "solve_complex_trans_" ) + identifier + "system_reuse";
450 }
451 
453 
454  implicit = _implicit;
455 
456  return SUCCESSFUL_RETURN;
457 }
458 
459 //
460 // PROTECTED MEMBER FUNCTIONS:
461 //
462 
463 
464 
466 
467 // end of file.
returnValue setTransformations(const DMatrix &_transf1, const DMatrix &_transf2, const DMatrix &_transf1_T, const DMatrix &_transf2_T)
bool isEmpty() const
Definition: matrix.hpp:193
virtual returnValue getDataDeclarations(ExportStatementBlock &declarations, ExportStruct dataStruct=ACADO_ANY) const
const std::string getNameSolveTransposeReuseFunction()
returnValue setImplicit(BooleanType _implicit)
ExportFunction solveReuseTranspose
virtual returnValue transformRightHandSide(ExportStatementBlock &code, const ExportVariable &b_mem_complex_, const ExportVariable &b_mem_real_, const ExportVariable &b_full_, const ExportVariable &transf_, const ExportIndex &index, const bool transpose)
virtual returnValue setup()
Allows to pass back messages to the calling function.
returnValue appendVariableNames(std::stringstream &string)
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 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.
returnValue appendVariableNames(std::stringstream &string)
virtual returnValue getCode(ExportStatementBlock &code)
ExportStruct
Allows to export Gaussian elimination for solving linear systems of specific dimensions.
ExportIRK3StageSimplifiedNewton(UserInteraction *_userInteraction=0, const std::string &_commonHeaderName="")
const std::string getNameSolveReuseFunction()
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)
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)
virtual returnValue transformSolution(ExportStatementBlock &code, const ExportVariable &b_mem_complex_, const ExportVariable &b_mem_real_, const ExportVariable &b_full_, const ExportVariable &tranfs_, const ExportIndex &index, const bool transpose)
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
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)
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